浅谈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.*Error错误,原因是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动态代理
一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...
随机推荐
-
js控制文本框只能输入中文、英文、数字与指定特殊符号.
先在'' 里输入 onkeyup="value=value.replace(/[^\X]/g,'')" 然后在(/[\X]/g,'')里的 X换成你想输入的代码就可以了, 中文u4 ...
-
分布式的Id生成器
项目中需要一个分布式的Id生成器,twitter的Snowflake中这个既简单又高效,网上找的Java版本 package com.cqfc.id; import org.slf4j.Logger; ...
-
java1.8的默认方法的坑
默认方法: 接口的方法一直都是抽象方法,自从1.8出来了之后,新增了一个默认方法.可以在接口中实现方法 1.默认方法需要用default修饰 2.默认方法不能是静态的 3.子接口继承了2个相同签名的默 ...
-
Linux环境安装Jenkins
安装环境: CenOS 6.4 JDK_1.6.0_23 一.安装前检查环境 检查是否安装JDK: java --version 二.安装Jenkins 1. 添加Jenkins的源(reposito ...
-
MySQL show slave status命令参数
? Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLIST用于从属I/O线程.如果线程正在试图连接到主服务器,正在等待来自主服务器的 ...
-
Java线程调度—休眠
线程休眠的方法是Thread.sleep(long millis) 和Thread.sleep(long millis, int nanos) ,均为静态方法,那调用sleep休眠的哪个线程呢?简单说 ...
-
HDU1024 DP的优化 最大M子段和问题
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
-
Python中matplotlib模块解析
用Matplotlib绘制二维图像的最简单方法是: 1. 导入模块 导入matplotlib的子模块 import matplotlib.pyplot as plt import numpy as ...
-
《Linux内核设计与实现》读书笔记 18
第十八章调试 18.1 准备开始 一个bug:大部分bug通常都不是行为可靠而且定义明确的 一个藏匿bug的内核版本:找出bug首先出现的版本 相关内核代码的知识和运气 18.2内核中的bug 可以有 ...
-
jQuery插件初级练习2
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...