浅谈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动态代理
一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...
随机推荐
- Tomcat 配置Https
https://www.cnblogs.com/wanghaoyuhappy/p/5267702.html JDK1.8 keytool 生存证书 C:\keys\tomcat.keystore 1: ...
- APP-6-百度地图导航
1.代码部分 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <me ...
- JSP基本
JSPとは.HTMLファイルにJavaコードを埋め込んでおき.クライアントの要求に応じてコードを実行.処理結果のみをクライアントに送信する技術です. 1.JSPは実はサーブレットです.最初にリクエスト ...
- JS基础一-入门知识
一.什么是JavaScript JavaScript是一种基于对象和事件驱动并具有安全性能的解释性脚本语言.JavaScript不需要编译,直接嵌入在HTTP页面中,把静态页面转变成支持用户交互并响应 ...
- A New Year, A New Accent!
A New Year, A New Accent! Share Tweet Share Happy New Year! Does your list of resolutions include i ...
- Android高级控件(下)
Chronometer计时器 常用的方法 getBase() 基准时间 setFormat 设置显示格式 start() 开始计时 stop() 停止计时 setOnChronometerListen ...
- ArcGIS(ESRI)的发展历史和版本历史(简介)
作者:fenghuayoushi 来源:CSDN 原文:https://blog.csdn.net/fenghuayoushi/article/details/6677360 ESRI公司介绍 ...
- CSS强制换行和禁止换行代码
一.强制换行 1.word-break: break-all; 只对英文起作用,以字母作为换行依据. 2.word-wrap: break-word; 只对英文起作 ...
- 本地Navicat连不上Linux虚拟机MySQL数据库问题
LinuxAndMySQL 版权声明:本文为博主原创文章,未经博主允许不得转载. 在Linux登录到MySQL数据:mysql -uroot -p 输入密码 切换到mysql数据库 mysql> ...
- 函数putText()在图片上写文字
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace c ...