java动态代理和CGLIB
参考:https://www.jianshu.com/p/cbd4c1ad8a75
上一篇我们利用jdk的动态代理实现了一个简单的注解处理器,可以自动给一个button添加指定的监听器.
但是jdk的动态代理有一个不足之处,就是他代理的类必须实现了一个接口,如果我们要代理的类就是一个类,没有实现接口,
那么jdk的动态代理就无能无力了,这个时候我们需要用到一个更为强大的工具cglib,他可以动态给要代理的类生成一个子类
由子类代替父类完成工作,并作一定的功能增强.
下面我们举一个简单的例子,我又一个类,他只负责打招呼
public class Hello { public void sayHello(){ System.out.println("hello,world"); } }
现在我在不改变这个类的基础上,想对他进行功能增强,应该怎么办?
肯定是使用代理啊,那Hello是个类,没有实现接口,我们只能用cglib,cglib是一个第三方的库,我们要先引进来
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
接下来我们要定义一个方法过滤器,对sayHello进行增强,其中
methodProxy.invokeSuper(obj, args);就是调用原来hello里的sayHello
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class HelloMethodInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("log before method"); Object result = methodProxy.invokeSuper(obj, args); System.out.println("log after method"); return result; } }
然后我们写一个例子,测试下效果
import net.sf.cglib.proxy.Enhancer; public class HelloProxy { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Hello.class); enhancer.setCallback(new HelloMethodInterceptor()); Hello proxy =(Hello) enhancer.create(); proxy.sayHello(); } }
输出
log before method
hello,world
log after method
事实证明,cglib已经完美实现了我们想要的功能.
对比jdk的动态代理可以发现:
cglib的MethodInterceptor就相当于jdk动态代理中的InvocationHandler
cglib中的Enhancer就相当jdk动态代理中的Proxy
用法基本相同,只不过jdk动态代理基于接口实现,cglib是基于子类继承父类.
//代理的静态实现,更像Proxy.newInstance Hello proxy2 =(Hello) Enhancer.create(Hello.class, new HelloMethodInterceptor()); proxy2.sayHello();
当然我们可以对上面的类进行改造,把方法过滤器和代理类的实现放在一个类中
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class HelloMethodInterceptor implements MethodInterceptor { private Object obj; public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("log before method"); Object result = methodProxy.invokeSuper(obj, args); System.out.println("log after method"); return result; } public Object createProxy(Object obj){ this.obj=obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.obj.getClass()); enhancer.setCallback(this); return enhancer.create(); } }
测试一下效果
public class HelloProxy { public static void main(String[] args) { HelloMethodInterceptor interceptor = new HelloMethodInterceptor(); Hello proxy = (Hello) interceptor.createProxy(new Hello()); proxy.sayHello(); } }
代码更加简洁,功能还是一样
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2021-03-12 计算机系统、文化、概论、导论类经典PDF电子书合集
2021-03-12 大数据hadoop,spark,flink等经典电子书PDF下载