Spring源码(15) -- Aop动态代理之 Enhancer
Enhancer 用途
Enhancer (增强器) 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。
原始且最通用的回调类型是 MethodInterceptor(方法拦截器)。
通常,每个 Enhancer 都会使用一个 Callback 回调,但可以使用 callbackFilter 控制每个方法使用哪个回调。
此类最常见的用途体现在静态辅助方法中。
对于高级需求,例如自定义要使用的 ClassLoader,应该创建一个新的Enhancer实例。CGLIB中的其他类遵循类似的模式。
所有增强的对象都实现Factory接口,除非使用setUseFactory显式禁用此功能。
Factory接口提供了一个API来更改现有对象的回调,并提供了一种更快速、更简单的方法来创建相同类型的新实例。
几乎可以替代java.lang.reflect.Proxy 类。
源码
org.springframework.cglib.proxy.Enhancer
Callback[]
源码:org.springframework.cglib.proxy.Callback
Callback[] 是回调数组,是Enhancer的属性之一。
public interface Callback {
}
CallbackFilter
源码:org.springframework.cglib.proxy.CallbackFilter
CallbackFilter ,也是Enhancer的属性之一。
CallbackFilter 就是 CallBack 的过滤器,callbackFilter 可以控制每个方法使用哪个 Callback 回调。
可以重写 callbackFilter 接口,并实现 accept()方法。
public interface CallbackFilter {
int accept(Method var1);
boolean equals(Object var1);
}
Enhancer示例
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
public class EnhancerDemo {
public static class Target {
public void printHello() {
System.out.println("Hello World");
}
}
public static void main(String[] param) {
//Enhancer 是标准Jdk动态代理的替代品,用于生成动态子类以启用方法拦截,还允许代理扩展具体的基类。
Target proxy = (Target) Enhancer.create(Target.class, (MethodInterceptor) (p, method, args, methodProxy) -> {
System.out.println("before method.");
//以下 p的值是 com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731@27c60c
// methodProxy的 fastClassInfo 有 f1为 class com.example.demo.sourceCode.cglib.CglibDemo$Target,
// f2为class com.example.demo.sourceCode.cglib.CglibDemo$Target$$EnhancerByCGLIB$$87c3a731
Object result = methodProxy.invokeSuper(p, args);
System.out.println("after method.");
return result;
});
proxy.printHello();
}
}
Enhancer的 create()方法
create()方法,可以创建被拦截对象的辅助方法。
public static Object create(Class type, Callback callback) {
Enhancer e = new Enhancer();
//要扩展的类或要实现的接口
e.setSuperclass(type);
//设置回调数组
e.setCallback(callback);
return e.create();
}
/**
* 必要时生成一个新类,并使用指定的回调(如果有的话)创建一个新的对象实例。使用超类的无参数构造函数。
*/
public Object create() {
classOnly = false;
argumentTypes = null;
return createHelper();
}
private Object createHelper() {
preValidate();
Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID);
this.currentKey = key;
//重点看这里, 调用了父类的 create() 方法
Object result = super.create(key);
return result;
}
AbstractClassGenerator 的 create()
源码: org.springframework.cglib.core.AbstractClassGenerator#create
protected Object create(Object key) {
try {
//获取类加载器
ClassLoader loader = getClassLoader();
Map<ClassLoader, ClassLoaderData> cache = CACHE;
ClassLoaderData data = cache.get(loader);
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
if (data == null) {
//双重检查锁, 设置 ClassLoaderData。并设置缓存。
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
data = new ClassLoaderData(loader);
newCache.put(loader, data);
CACHE = newCache;
}
}
}
this.key = key;
// 生成对象
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
return nextInstance(obj);
}
catch (RuntimeException | Error ex) {
throw ex;
}
catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了