浅谈Java代理二:Cglib动态代理-MethodInterceptor

CGLib动态代理特点

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

示例业务逻辑:

1-有一个明星叫胡歌(class HuGe)

3-找明星做事情需要经过助理(ProxyFactory )

4-如果要找胡歌唱歌、演戏,需要先找助理,然后助理去找胡歌唱歌、演戏(class testProcyFactory)

1-被代理类(没有实现任何接口)

  1. package com.huishe.testOfSpring.methodinterceptor;
  2.  
  3. public class HuGe {
  4.  
  5. public void sing(String song) {
  6. System.out.println("胡歌演唱: " + song);
  7. }
  8.  
  9. public String act(String teleplay) {
  10. System.out.println("胡歌决定出演电视剧: " + teleplay);
  11. return "胡歌答应出演电视剧: " + teleplay;
  12. }
  13. }

2-代理工厂(即创建代理的通用写法)

  1. package com.huishe.testOfSpring.methodinterceptor;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import net.sf.cglib.proxy.Enhancer;
  6. import net.sf.cglib.proxy.MethodInterceptor;
  7. import net.sf.cglib.proxy.MethodProxy;
  8.  
  9. public class ProxyFactory implements MethodInterceptor{
  10. //要代理的原始对象
  11. private Object object;
  12.  
  13. //1-创建代理对象
  14. public Object createProcy(Object target){
  15. this.object = target;
  16. //1-Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展
  17. Enhancer enhancer=new Enhancer();
  18. //2-将被代理类HuGe设置成父类
  19. enhancer.setSuperclass(this.object.getClass());
  20. //3-设置拦截器
  21. enhancer.setCallback(this);
  22. //4-动态生成一个代理类
  23. Object objProxy = enhancer.create();
  24.  
  25. return objProxy;
  26.  
  27. }
  28.  
  29. //2-实现MethodInterceptor的intercept方法
  30. public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
  31. System.out.println("before: " + method);
  32. //调用proxy.invoke()方法,会报java.lang.StackOverflowError错误,原因是invoke()内部会一直被反复调用
  33. //Object object = proxy.invoke(obj, args);
  34. Object object = proxy.invokeSuper(obj, args);
  35. System.out.println("after: " + method);
  36. return object;
  37. }
  38. }

3-进行测试

  1. package com.huishe.testOfSpring.methodinterceptor;
  2.  
  3. import org.junit.Test;
  4.  
  5. import net.sf.cglib.proxy.Enhancer;
  6.  
  7. public class cglibMethodInterceptorTest {
  8.  
  9. @Test
  10. public void testProcyFactory(){
  11. //1-实例化需要被代理的类
  12. HuGe huGe = new HuGe();
  13. //2-实例化代理工厂
  14. ProxyFactory cglibProxy = new ProxyFactory();
  15. //3-动态生成一个代理类,并从Object强制转型成父类型HuGe
  16. HuGe hg =(HuGe)cglibProxy.createProcy(huGe);
  17.  
  18. //4-执行动态代理类的方法
  19. hg.sing("逍遥叹");
  20. hg.act("琅琊榜");
  21.  
  22. }
  23.  
  24. }

4-测试结果

  1. 日志输出:
  2.  
  3. before: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
  4. 胡歌演唱: 逍遥叹
  5. after: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
  6. before: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
  7. 胡歌决定出演电视剧: 琅琊榜
  8. after: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)

参考资料

1-https://blog.csdn.net/jiaotuwoaini/article/details/51675684
2-https://www.cnblogs.com/writeLessDoMore/p/6973853.html

浅谈Java代理二:Cglib动态代理-MethodInterceptor的更多相关文章

  1. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  2. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

  3. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  4. JDK动态代理、CGLIB动态代理详解

    Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...

  5. jdk动态代理与cglib动态代理例子

    1.JAVA的动态代理特征:特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象 ...

  6. 代理模式详解:静态代理+JDK/CGLIB 动态代理实战

    1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...

  7. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  8. JDK 动态代理与 CGLIB 动态代理,它俩真的不一样

    摘要:一文带你搞懂JDK 动态代理与 CGLIB 动态代理 本文分享自华为云社区<一文带你搞懂JDK 动态代理与 CGLIB 动态代理>,作者: Code皮皮虾 . 两者有何区别 1.Jd ...

  9. 代理模式 & Java原生动态代理技术 & CGLib动态代理技术

    第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...

  10. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

随机推荐

  1. https 学习总结

    最近看了点https 做下总结  面的博客如果没有错误的话,理解起来绝对是醍醐灌顶!让人信服,如果我的理解有问题,请及时指正! 参考博客:    http://www.ruanyifeng.com/b ...

  2. Grafana+Zabbix使用配置

    官方提供的网友分享的图形面板,可以自行选择使用下载---  https://grafana.com/dashboards   Grafana 是 Graphite 和 InfluxDB 仪表盘和图形编 ...

  3. DNS协议工作过程;DNS的安全隐患

    DNS协议工作过程   下面以域名为m.xyz.com的主机欲通过另一个主机的域名y.abc.com的IP地址为例,简述DNS协议过程. 主机m.xyz.com先向其本地服务器dns.xyz.com进 ...

  4. Arcgis map export or print Error: Cannot map metafile into memory. Not enough memory

      Arcgis map export or print Error: Cannot map metafile into memory. Not enough memory Link: https:/ ...

  5. unity 三种注入示例

    /* * 演示Unity 注入 * */ using Microsoft.Practices.Unity; using System; namespace Unity.Property.Inject ...

  6. 用Lucene4.5对中文文本建立索引

    这里需要完成一个能对txt文本建立索引,并能完成检索查询.完成这个功能,使用的是Lucene4.5,同时使用其自带的中文分析器. 准备工作是在一个文件夹里面建一些txt文件,这是我的文件结构: 首先要 ...

  7. 嵌入式 Web Server 温度检测系统

    1. Web Server 服务器后台表单处理程序:使用 CGI 程序接口编写后台程序的 Web 服务器. 2. Boa 服务器

  8. CentOS7 安装 GitLab

    虽然GitHub已经很好了,但是我们必须联上公网才可以使用并且如果不付费的话,你的代码在网上就是公开的!但是在企业环境中,我们公司的代码不希望被公开并且也不想付费给GitHub,这时怎么办呢?我们可以 ...

  9. HttpClient之EntityUtils对象

    最近在学习安卓并用thinkphp做后台,为了抵抗自己的烂记性,就在这里记录一下当我从tp后台获取到json串传到安卓客户端所用到的一个方法函数. EntityUtils对象是org.apache.h ...

  10. 使用Js控制ReactRouter路由

    [使用Js控制ReactRouter路由] 首先引入PropTypes: const PropTypes = require('prop-types'); 然后定义context的router属性: ...