第十二讲-AOP之proxy增强-cglib
第十二讲-AOP之proxy增强-cglib
使用Cglib作为代理的例子
package com.cherry.a12;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyDemo {
static class Target{
public void foo(){
System.out.println("target foo...");
}
}
public static void main(String[] args) {
// 准备目标对象
Target target = new Target();
Target proxy = (Target)Enhancer.create(Target.class, new MethodInterceptor() {
@Override // 代理对象自己 代理类中执行的方法 方法执行时的参数 方法参数
public Object intercept(Object p, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
Object result = method.invoke(target, args);// 执行结果
System.out.println("after...");
return result;
}
});
proxy.foo();
}
}
运行结果如下:
before...
target foo...
after...
使用Cglib实现动态代理的特点:
- 代理类和目标类是子父的关系(代理类是子类,目标类是父类)
- 这也带来了一个问题,如果目标类使用了
final
关键字修饰,那么代理能成功吗?不行,例如将Target类改用final关键字修饰:
static final class Target{
public void foo(){
System.out.println("target foo...");
}
}
则会抛出异常:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot subclass final class com.cherry.a12.CglibProxyDemo$Target
- 当然,如果目标类的方法使用
final
关键字修饰,那么使用cglib还是实现功能增强吗,则是不能的:
static class Target{
public final void foo(){
System.out.println("target foo...");
}
}
target foo...
代理的本质就是对方法的重写,既然方法都不能被重写了,自然代理的增强功能也就失去了作用!
目前的Cglib使用的是反射机制来调用目标,但是Cglib还提供了MethodProxy
避免发射调用目标方法,如下面的示例(需要的是目标对象):
Target proxy = (Target)Enhancer.create(Target.class, new MethodInterceptor() {
@Override // 代理对象自己 代理类中执行的方法 方法执行时的参数 方法参数
public Object intercept(Object p, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
//Object result = method.invoke(target, args);// 执行结果
Object result = methodProxy.invoke(target, args); // 使用的不是反射!
System.out.println("after...");
return result;
}
});
运行如下:
before...
target foo...
after...
还有一种是调用invokeSuper()方法 --> 需要的是代理对象:
methodProxy.invokeSuper(p, args);
before...
target foo...
after...
分类:
Spring 高级49讲
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构