动态代理
这里再简单总结一下
什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象。
静态代理是在程序发布之前,我们就必须写好代理类的
动态代理在程序发布之前,并没有写好代理类,而是发布之后,动态创建代理对象的
这篇文章主要介绍两种动态代理,jdk代理和cglib代理
jdk代理
实现
通过实现 InvocationHandler 接口创建自己的调用处理器
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类
通过反射机制获得动态代理类的构造函数
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入
代码
Sale saleProxy=(Sale)Proxy.newProxyInstance( jiajun.getClass().getClassLoader(), jiajun.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("===before==="); Object obj = method.invoke(jiajun, args); System.out.println("===after==="); return obj; } }); saleProxy.sale(); saleProxy.rent();
原理
生成一个代理类,这个代理类继承Proxy类并且实现了我们定义的接口,代理对象调用方法的时候,调用这个代理对象的一个成员InvocationHandler(上面我们传入了一个InvocationHandler实现对象)的方法,也就是我们添加了before和after后的方法。
cglib代理
实现
实现CGLib包提供的MethodInterceptor接口,实现intercept方法,用CGLib中的Enhancer的creat方法创建代理对象
代码
class CGLibProxy implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("Before:" + method); Object object = proxy.invokeSuper(obj, arg); System.out.println("After:" + method); return object; } }public class Test2 { public static void main(String[] args) { CGLibProxy cgLibProxy=new CGLibProxy(); Jiajun jiajunProxy=(Jiajun)Enhancer.create(Jiajun.class,cgLibProxy); jiajunProxy.buy(); jiajunProxy.sale(); } }
原理
通过asm字节码生成框架生成代理类Class的二进制字节码
通过Class.forName加载二进制字节码,生成Class对象
通过反射机制获取实例构造,并初始化代理类对象
jdk代理 vs cglib代理
jdk代理只能代理接口,不能代理没有接口的类。
cglib代理可以代理没有接口的类
总结
动态代理相对于静态代理更加灵活,减少了代码量也提高了可维护性。
动态代理有两种,一种是jdk代理,通过创建一个继承Proxy类并实现接口的代理对象。一种是cglib代理,通过asm生成代理类class的字节码,再生成Class对象,最后通过反射创建代理对象。
jdk代理只适合基于接口的代理,cglib可以代理没有实现接口的目标对象。
我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)
http://www.cnblogs.com/-new/p/7151136.html