Java动态代理实现方法小结
本文实例讲述了Java动态代理实现方法。分享给大家供大家参考,具体如下:
静态代理了解的差不多了,但是对于动态代理理解的还不是很通透,这里先把一些常用的动态代理实现方法记录下来,日后时常看看争取早日融会贯通。
1、JDK实现动态代理
主要使用了Proxy.newProxyInstance()方法,该方法的官方解释为:返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目标类:代理类要增强的类 public class SomeServiceImpl implements ISomeService { @Override public String doFirst() { return "AAAbbb" ; } @Override public void doSecond() { System.out.println( "SomeServiceImpl:执行doSecond()" ); } @Override public String doThird() { return "aaa" ; } } public class Mytest { public static void main(String[] args) { ISomeService target = new SomeServiceImpl(); ISomeService someService = (ISomeService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { // proxy:代理对象 // method:目标方法 // args:目标方法的参数列表 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); if (result!= null ) { result=((String)result).toUpperCase(); } return result; } }); System.out.println(someService.doFirst()); someService.doSecond(); System.out.println(someService.doThird()); } } |
2、CGLIB实现动态代理(没接口)
使用JDK的Proxy实现动态代理,要求目标类与代理类实现相同的接口,若目标类不存在接口,则无法使用该方式实现。
对于没有接口的类,要为其创建动态代理,就要使用CGLIB来实现。CGLIB动态代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。使用CGLIB生成代理类,要求目标类必须能被继承,因此不能是final类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //目标类:代理类要增强的类 public class SomeService { public String doFirst() { System.out.println( "SomeServiceImpl:执行doFirst()" ); return "AAAbbb" ; } public void doSecond() { System.out.println( "SomeServiceImpl:执行doSecond()" ); } } //注意:使用Cglib动态代理,要求目标类不能是final的 //Cglib动态代理的增强原理是:子类增强父类,所以目标类必须能被继承 public class CglibFactory implements MethodInterceptor { private SomeService target; public CglibFactory() { } public CglibFactory(SomeService target) { this .target = target; } public SomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父类,即目标类。因为Cglib动态代理增强的原理是:子类增强父类 enhancer.setSuperclass(SomeService. class ); //设置回调接口对象 enhancer.setCallback( this ); //create()方法用于创建Cglib动态代理对象 return (SomeService)enhancer.create(); } //回调函数的执行条件:代理对象执行目标方法时会触发该方法 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object invoke = method.invoke(target, args); if (invoke!= null ) { invoke=((String)invoke).toUpperCase(); } return invoke; } } public class Mytest { public static void main(String[] args) { SomeService target = new SomeService(); SomeService proxy = new CglibFactory(target).myCglibCreator(); proxy.doFirst(); } } |
3、CGLIB实现动态代理(有接口)
在有接口的情况下利用CGLIB实现动态代理跟没有接口的情况下利用CGLIB实现动态代理,其实差不多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目标类:代理类要增强的类 public class SomeService implements ISomeService { public String doFirst() { return "AAAbbb" ; } public void doSecond() { System.out.println( "SomeServiceImpl:执行doSecond()" ); } @Override public String doThird() { return "third" ; } } //注意:使用Cglib动态代理,要求目标类不能是final的 //Cglib动态代理的增强原理是:子类增强父类,所以目标类必须能被继承 public class CglibFactory implements MethodInterceptor { private ISomeService target; public CglibFactory() { } public CglibFactory(ISomeService target) { this .target = target; } public ISomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父类,即目标类。因为Cglib动态代理增强的原理是:子类增强父类 enhancer.setSuperclass(ISomeService. class ); //设置回调接口对象 enhancer.setCallback( this ); //create()方法用于创建Cglib动态代理对象 return (ISomeService)enhancer.create(); } //回调函数的执行条件:代理对象执行目标方法时会触发该方法 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object invoke = method.invoke(target, args); if (invoke!= null ) { invoke=((String)invoke).toUpperCase(); } return invoke; } } public class Mytest { public static void main(String[] args) { ISomeService target = new SomeService(); ISomeService proxy = new CglibFactory(target).myCglibCreator(); System.out.println(proxy.doFirst()); proxy.doSecond(); System.out.println(proxy.doThird()); } } |
更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
springboot+RabbitMQ+InfluxDB+Grafara监控实践
这篇文章主要介绍了springboot+RabbitMQ+InfluxDB+Grafara监控实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-07-07Java实现读取项目中文件(.json或.properties)的方法详解
这篇文章主要为大家详细介绍了Java实现读取项目中文件的方法,例如.json或.properties,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下2023-04-04Nacos1.4.0 Windows10单机模式启动和集群启动过程解析
这篇文章主要介绍了Nacos1.4.0 Windows10单机模式启动和集群启动,第一次使用nacos,废话不多说,记录下自己启动Nacos遇到的坑,感兴趣的朋友跟随小编一起看看吧2023-10-10
最新评论