java 动态代理模式(jdk和cglib)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java 动态代理模式(jdk和cglib),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5645字,纯文字阅读大概需要9分钟。
内容图文
![java 动态代理模式(jdk和cglib)](/upload/InfoBanner/zyjiaocheng/842/c7d0377100d04aa9b1f0e3eb93cb20fc.jpg)
1 package proxy.dynamicproxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 8 /** 9 * 需要实现InvocationHandler接口,内部维护一个实际类实例 10 * 11 */ 12 public class JdkProxyHandler implements InvocationHandler { 13 14 private Object realObject; 15 16 public Object proxy(Object realObject){ 17 this.realObject = realObject; 18 return Proxy.newProxyInstance(this.realObject.getClass().getClassLoader(), 19 this.realObject.getClass().getInterfaces(), this); 20 } 21 22 /** 23 * 24 * @param proxy 动态生成的代理类实例 25 * @param method 方法实例 26 * @param args 方法参数 27 * @return 28 * @throws Throwable 29 */ 30 @Override 31 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 32 System.out.println("我是代理人:大明星唱歌开始前,我先宣传一下:巴拉巴拉。。。"); 33 34 // 调用实际类的方法,并传入参数,内部是反射机制 35 Object ret = method.invoke(this.realObject, args); 36 37 System.out.println("我是代理人:大明星唱歌完毕了,我来总结一下:巴拉巴拉。。。"); 38 39 return ret; 40 } 41 }
1 package proxy.dynamicproxy; 2 3 import net.sf.cglib.proxy.Enhancer; 4 import net.sf.cglib.proxy.MethodInterceptor; 5 import net.sf.cglib.proxy.MethodProxy; 6 7 import java.lang.reflect.Method; 8 9 /** 10 * 需要实现MethodInterceptor接口 11 * cglib相关依赖: 12 * ant-1.6.2.jar 13 * asm-3.1.jar 14 * asm-util-3.1.jar 15 * cglib-2.2.2.jar 16 */ 17 public class CglibProxyHandler implements MethodInterceptor { 18 19 public Object proxy(Object realObject){ 20 21 // 使用字节码增强器 四个固定步骤: 22 // 1、new字节码增强器 23 // 2、设置当前类实例为回调 24 // 3、将实际类实例设置为父类 25 // 4、创建一个代理类 26 Enhancer enhancer = new Enhancer(); 27 enhancer.setCallback(this); 28 enhancer.setSuperclass(realObject.getClass()); 29 // 这里会生成代理类、代理类的FastClass辅助类、实际类的FastClass辅助类 30 // 辅助类为代理类和实际类的每个方法生成一个唯一的id 31 // 用于在调用intercept方法时,通过唯一id就可以调用对应的方法 32 // 不再走反射机制,提高性能 33 return enhancer.create(); 34 } 35 36 /** 37 * 38 * @param o 代理类的实例 39 * @param method 方法实例 40 * @param objects 方法参数 41 * @param methodProxy 方法代理 42 * @return 43 * @throws Throwable 44 */ 45 @Override 46 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 47 48 System.out.println("我是代理人:大明星唱歌开始前,我先宣传一下:巴拉巴拉。。。"); 49 50 // 这里如果使用 method.invoke方法,就等同于走了反射机制去调用方法,性能不高 51 // 而且还需要另外维护实际类实例 52 // Object ret = method.invoke(this.realObject, objects); 53 54 Object ret = methodProxy.invokeSuper(o, objects); 55 56 System.out.println("我是代理人:大明星唱歌完毕了,我来总结一下:巴拉巴拉。。。"); 57 58 return ret; 59 } 60 }
1 package proxy.dynamicproxy; 2 3 import net.sf.cglib.core.DebuggingClassWriter; 4 import proxy.staticproxy.IStar; 5 import proxy.staticproxy.RealStar; 6 7 public class Test { 8 public static void main(String[] args) { 9 10 /** 11 * 还是以“代理人”和“大明星”为例 12 * jdk动态代理:适用于大明星实现某接口的情况,且只能用于实现接口的情况 13 * 不能用于未实现任何接口的类,因为生成的动态代理类要继承自Proxy、同时实现大明星接口。 14 * cglib动态代理:适用于任何类。它是采用动态代理类直接继承大明星类的方式,将大明星当作父类 15 * 覆写大明星类的所有方法(除final修饰的方法,wait方法,notify方法) 16 * 17 * 优缺点: 18 * jdk方式,只能针对接口,底层直接写字节码的方式生成代理类,所以生成代理类速度快 19 * 但是代理类执行方法时,通过反射的方式去执行,速度不如cglib方式 20 * cglib方式,可以适用于任何类,底层使用ASM框架生成字节码,因为采用FastClass机制 21 * 在生成代理类的同时还要生成代理类和大明星类的对应FastClass类(辅助类) 22 * 这两个辅助类的作用是:对应FastClass辅助类会为代理类和大明星类的每一个方法 23 * (除final修饰的方法,wait方法,notify方法)生成唯一id,这样在后面的调用方法时 24 * 不再通过反射去执行逻辑,而是直接根据id找到对应的方法去执行,提高性能,但相对的,生成字节码速度较慢 25 */ 26 boolean isUseJdkProxy = false; 27 28 if (isUseJdkProxy) { 29 System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); 30 31 IStar star = (IStar) new JdkProxyHandler().proxy(new RealStar()); 32 star.sing(); 33 } 34 else { 35 36 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, 37 "C:\\Users\\Administrator\\IdeaProjects\\untitled\\cglibClass"); 38 39 IStar star = (IStar) new CglibProxyHandler().proxy(new RealStar()); 40 41 // 这一步里面的具体流程: 42 // 动态代理类的sing方法 --> CglibProxyHandler的intercept方法 43 // --> 实际类执行前的行为代理 --> MethodProxy.invokeSuper方法 44 // --> 根据唯一id在FastClass里找到对应的实际方法 45 // --> 代理类的FastClass内部:让代理类调用实际方法 46 // --> 代理类的实际方法内部一般就是直接调用父类(被代理类)的方法 47 // --> 返回父类方法的返回值 48 star.sing(); 49 50 } 51 } 52 }
内容总结
以上是互联网集市为您收集整理的java 动态代理模式(jdk和cglib)全部内容,希望文章能够帮你解决java 动态代理模式(jdk和cglib)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。