参考文献:
http://www.jianshu.com/p/6f6bb2f0ece9
http://wiki.jikexueyuan.com/project/java-reflection/java-dynamic.html
动态代理的好处
动态代理中接口中的所有方法都能转移到handler的一个invoke方法中处理;静态代理中每个方法都要有一个对应的代理增强方法;静态代理中修改接口时,所有的代理类都要修改;而动态代理不用修改;JDK动态代理的原理
通过Proxy.newInstace()方法动态生成代理类,然后返回代理类的对象,并在代理对象中注入handler作为属性;代理类的对象调用方法时,都被转到handler的invoke()方法来执行;动态代理的底层实现
生成代理的过程 static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler) { //1. 根据类加载器和接口动态创建代理类 Class clazz = Proxy.getProxyClass(loader, interfaces); //2. 获得代理类的带参数的构造函数 Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class }); //3. 创建代理对象,并制定调用处理器实例为参数传入 Interface Proxy = (Interface)constructor.newInstance(new Object[] {handler}); } 生成的代理类,以及方法怎么转到handler上的 public final class $Proxy1 extends Proxy implements Subject{ private InvocationHandler h; private $Proxy1(){} //把handler注入到代理对象中 public $Proxy1(InvocationHandler h){ this.h = h; } //代理类实现的接口方法 public int request(int i){ //获取委托类的Method对象;然后调用handler的invoke()方法,并传入proxy,method对象和参数; Method method = Subject.class.getMethod("request", new Class[]{int.class}); return (Integer)h.invoke(this, method, new Object[]{new Integer(i)}); } } 自定义的Handler类,以及如何增强方法 public class MyInvocationHandler implements InvocationHandler{ // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在method执行前do something //根据args参数,执行method对应的方法 //在method执行后do something } } CGLIB动态代理 CGLIB通过修改字节码来实现代理;JDK动态代理在运行时通过反射和动态编译来生成类的字节码,然后加载到JVM中;spring中如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;spring中如果目标对象实现了接口,可以强制使用CGLIB实现AOP;spring中如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换;