浅谈Java代理二:Cglib动态代理-MethodInterceptor
浅谈Java代理二:Cglib动态代理-MethodInterceptor
CGLib动态代理特点:
使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
示例业务逻辑:
1-有一个明星叫胡歌(class HuGe)
3-找明星做事情需要经过助理(ProxyFactory )
4-如果要找胡歌唱歌、演戏,需要先找助理,然后助理去找胡歌唱歌、演戏(class testProcyFactory)
1-被代理类(没有实现任何接口)
package com.huishe.testOfSpring.methodinterceptor; public class HuGe { public void sing(String song) {
System.out.println("胡歌演唱: " + song);
} public String act(String teleplay) {
System.out.println("胡歌决定出演电视剧: " + teleplay);
return "胡歌答应出演电视剧: " + teleplay;
}
}
2-代理工厂(即创建代理的通用写法)
package com.huishe.testOfSpring.methodinterceptor; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class ProxyFactory implements MethodInterceptor{
//要代理的原始对象
private Object object; //1-创建代理对象
public Object createProcy(Object target){
this.object = target;
//1-Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展
Enhancer enhancer=new Enhancer();
//2-将被代理类HuGe设置成父类
enhancer.setSuperclass(this.object.getClass());
//3-设置拦截器
enhancer.setCallback(this);
//4-动态生成一个代理类
Object objProxy = enhancer.create(); return objProxy; } //2-实现MethodInterceptor的intercept方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before: " + method);
//调用proxy.invoke()方法,会报java.lang.StackOverflowError错误,原因是invoke()内部会一直被反复调用
//Object object = proxy.invoke(obj, args);
Object object = proxy.invokeSuper(obj, args);
System.out.println("after: " + method);
return object;
}
}
3-进行测试
package com.huishe.testOfSpring.methodinterceptor; import org.junit.Test; import net.sf.cglib.proxy.Enhancer; public class cglibMethodInterceptorTest { @Test
public void testProcyFactory(){
//1-实例化需要被代理的类
HuGe huGe = new HuGe();
//2-实例化代理工厂
ProxyFactory cglibProxy = new ProxyFactory();
//3-动态生成一个代理类,并从Object强制转型成父类型HuGe
HuGe hg =(HuGe)cglibProxy.createProcy(huGe); //4-执行动态代理类的方法
hg.sing("逍遥叹");
hg.act("琅琊榜"); } }
4-测试结果
日志输出: before: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
胡歌演唱: 逍遥叹
after: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
before: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
胡歌决定出演电视剧: 琅琊榜
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的更多相关文章
- 浅谈Spring中JDK动态代理与CGLIB动态代理
前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...
- Java代理(静态代理、JDK动态代理、CGLIB动态代理)
Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- JDK动态代理、CGLIB动态代理详解
Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...
- jdk动态代理与cglib动态代理例子
1.JAVA的动态代理特征:特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象 ...
- 代理模式详解:静态代理+JDK/CGLIB 动态代理实战
1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...
- 代理模式详解:静态代理、JDK动态代理与Cglib动态代理
代理模式简介分类 概念 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...
- JDK 动态代理与 CGLIB 动态代理,它俩真的不一样
摘要:一文带你搞懂JDK 动态代理与 CGLIB 动态代理 本文分享自华为云社区<一文带你搞懂JDK 动态代理与 CGLIB 动态代理>,作者: Code皮皮虾 . 两者有何区别 1.Jd ...
- 代理模式 & Java原生动态代理技术 & CGLib动态代理技术
第一部分.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...
- 017 Java中的静态代理、JDK动态代理、cglib动态代理
一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...
随机推荐
- vector 内存释放相关
在使用vector 存储char 类型时 new的数据 在vecto 执行rerase的时候或者 单项执行clear 内存是不能被释放的. 比如有下面的一个测试: class SnapshotInfo ...
- 页面ajax自带的访问后台时,正在加载中
ajax自带访问后台时,提示正在加载中,加载完成后自动消除遮罩层,代码如下: var mask=mui.createMask();//遮罩层 //传统ajax的post请求方式 mui.ajax('h ...
- javascript_ajax 地址三级联动
1.三级地址联动思路如下: 2.建立数据库.这里直接使用网上的地址数库,最后一个字段无用,先不去管它 3.建立一个server.php 文件 <?php // 数据库连接 mysql_conne ...
- THE BOX MODEL
Review In this lesson, we covered the four properties of the box model: height and width, padding, b ...
- 设计模式入门——Head First
设计模式是被前人发现.经过总结形成了一套某一类问题的一般性解决方案.使用模式最好的方式是:把模式装进脑子,然后在设计和已有的应用中,寻找何处可以使用它们.以往是代码复用,现在是经验复用. 从模拟鸭子游 ...
- 在CentOS7中利用yum命令安装mysql
在CentOS7中利用yum命令安装mysql 原创 2016年08月31日 10:42:33 标签: mysql / centos 4832 一.说明 我们是在VMware虚拟机上安装的mysql, ...
- 【转】JS windows.open()详解
window.open(url, name, features, replace) Arguments - 参数 url 可选字符串参数,指向要在新窗口中显示的文档的URL.如果省略该参数,或者参 ...
- 关于T-SQL中exists或者not exists子查询的“伪优化”的做法
问题起源 在使用t-sql中的exists(或者not exists)子查询的时候,不知道什么时候开始,发现一小部分人存在一种“伪优化”的一些做法,并且向不明真相的群众传递这一种写法“优越性”,实在看 ...
- C++ 关于滚动条的滚动问题
SCROLLINFO scrollinfo; GetScrollInfo(SB_HORZ, &scrollinfo, SIF_ALL); switch (nSBCode) { case SB_ ...
- 学JS的心路历程-正规表达式Regular Expression
今天我们来看正规表达式,在谈到为什么需要多学这个之前,先来看个示例. 假设需要判断输入字串是否含有“apple”: var text=“A apple a day keeps the doctor a ...