技术开发 频道

Spring 框架的设计理念与设计模式分析

  Spring 中 AOP 特性详解

  动态代理的实现原理

  要了解 Spring 的 AOP 就必须先了解的动态代理的原理,因为 AOP 就是基于动态代理实现的。动态代理还要从 JDK 本身说起。

  在 Jdk 的 java.lang.reflect 包下有个 Proxy 类,它正是构造代理类的入口。这个类的结构入下:

  图 16. Proxy 类结构

 动态代理的实现原理

  从上图发现最后面四个是公有方法。而最后一个方法 newProxyInstance 就是创建代理对象的方法。这个方法的源码如下:

  清单 6. Proxy. newProxyInstance

public static Object newProxyInstance(ClassLoader loader,
    Class
<?>[] interfaces,
    InvocationHandler h)
    
throws IllegalArgumentException {
    
    
if (h == null) {
        
throw new NullPointerException();
    }
    Class cl
= getProxyClass(loader, interfaces);
    
try {
        Constructor cons
= cl.getConstructor(constructorParams);
        
return (Object) cons.newInstance(new Object[] { h });
    }
catch (NoSuchMethodException e) {
        
throw new InternalError(e.toString());
    }
catch (IllegalAccessException e) {
        
throw new InternalError(e.toString());
    }
catch (InstantiationException e) {
        
throw new InternalError(e.toString());
    }
catch (InvocationTargetException e) {
        
throw new InternalError(e.toString());
    }
}

  这个方法需要三个参数:ClassLoader,用于加载代理类的 Loader 类,通常这个 Loader 和被代理的类是同一个 Loader 类。Interfaces,是要被代理的那些那些接口。InvocationHandler,就是用于执行除了被代理接口中方法之外的用户自定义的操作,他也是用户需要代理的最终目的。用户调用目标方法都被代理到 InvocationHandler 类中定义的唯一方法 invoke 中。这在后面再详解。

  下面还是看看 Proxy 如何产生代理类的过程,他构造出来的代理类到底是什么样子?下面揭晓啦。

  图 17. 创建代理对象时序图

 动态代理的实现原理

  其实从上图中可以发现正在构造代理类的是在 ProxyGenerator 的 generateProxyClass 的方法中。ProxyGenerator 类在 sun.misc 包下,感兴趣的话可以看看他的源码。

  假如有这样一个接口,如下:

  清单 7. SimpleProxy 类

public interface SimpleProxy {
    
public void simpleMethod1();    
    
public void simpleMethod2();
}

  代理来生成的类结构如下:

  清单 8. $Proxy2 类

public class $Proxy2 extends java.lang.reflect.Proxy implements SimpleProxy{
    java.lang.reflect.Method m0;
    java.lang.reflect.Method m1;
    java.lang.reflect.Method m2;
    java.lang.reflect.Method m3;
    java.lang.reflect.Method m4;

    
int hashCode();
    
boolean equals(java.lang.Object);
    java.lang.String toString();
    
void simpleMethod1();
    
void simpleMethod2();
}

  这个类中的方法里面将会是调用 InvocationHandler 的 invoke 方法,而每个方法也将对应一个属性变量,这个属性变量 m 也将传给 invoke 方法中的 Method 参数。整个代理就是这样实现的。

0
相关文章