public class MyTest {
public static void main(String[] args) {
//动态代理创建的class文件存储到本地
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"d:\\code");
//通过cglib动态代理获取代理对象的过程,创建调用的对象,在后续创建过程中EnhanceKey的对象,所以在进行enhancer对象创建的时候需要把EnhancerKey(newInstance)对象准备好,恰好这个对象也需要动态代理来生成
Enhancer enhancer = new Enhancer();
//设置enhancer对象的父类
enhancer.setSuperclass(MyCalculator.class);
//设置enhancer的回调对象
enhancer.setCallback(new MyCglib());
//创建代理对象
MyCalculator myCalculator = (MyCalculator) enhancer.create();
//通过代理对象调用目标方法
myCalculator.add(1,1);
System.out.println(myCalculator.getClass());
}
}
一 创建EnHancer对象
创建EnHacner对象时,发现EnHancer有父类对象AbstractClassGenerator,优先完成父类对象的加载
二 加载AbstractClassGenerator对象
在AbstractClassGenerator类中有一个内部类ClassLoaderData,里面有两个重要的回调函数GET_KEY 和load,一个用来把当前创建的代理对象名称存储为全局变量,一个用来生成代理对象的Class类
protected static class ClassLoaderData {
private final Set<String> reservedClassNames = new HashSet<String>();
/**
* {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer}
* configuration), and the value is the generated class plus some additional values
* (see {@link #unwrapCachedValue(Object)}.
* <p>The generated classes can be reused as long as their classloader is reachable.</p>
* <p>Note: the only way to access a class is to find it through generatedClasses cache, thus
* the key should not expire as long as the class itself is alive (its classloader is alive).</p>
*/
private final LoadingCache<AbstractClassGenerator, Object, Object> generatedClasses;
/**
* Note: ClassLoaderData object is stored as a value of {@code WeakHashMap<ClassLoader, ...>} thus
* this classLoader reference should be weak otherwise it would make classLoader strongly reachable
* and alive forever.
* Reference queue is not required since the cleanup is handled by {@link WeakHashMap}.
*/
private final WeakReference<ClassLoader> classLoader;
private final Predicate uniqueNamePredicate = new Predicate() {
public boolean evaluate(Object name) {
return reservedClassNames.contains(name);
}
};
private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
return gen.key;
}
};
public ClassLoaderData(ClassLoader classLoader) {
// 判断类加载器不能为空
if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported");
}
// 设置类加载器,弱引用 即在下次垃圾回收时就会进行回收
this.classLoader = new WeakReference<ClassLoader>(classLoader);
// 新建一个回调函数,这个回调函数的作用在于缓存中没获取到值时,调用传入的生成的生成代理类并返回
Function<AbstractClassGenerator, Object> load =
new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
Class klass = gen.generate(ClassLoaderData.this);
return gen.wrapCachedClass(klass);
}
};
// 为这个ClassLoadData新建一个缓存类
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
}
public ClassLoader getClassLoader() {
return classLoader.get();
}
public void reserveName(String name) {
reservedClassNames.add(name);
}
public Predicate getUniqueNamePredicate() {
return uniqueNamePredicate;
}
public Object get(AbstractClassGenerator gen, boolean useCache) {
// 如果不用缓存(默认使用)
if (!useCache) {
// 则直接调用生成器的命令
return gen.generate(ClassLoaderData.this);
}
else {
// 传入代理类生成器 并根据代理类生成器获取值返回
Object cachedValue = generatedClasses.get(gen);
// 解包装并返回
return gen.unwrapCachedValue(cachedValue);
}
}
}
三、EnhancerKey对象的创建
Cglib动态代理需要一个Enhancer增强器,在new Enhancer对象时会创建EnhancerKey对象,EnhancerKey是一个内部接口,里面的newInstance方法在创建我们的代理对象时会用到,所以需要优先创建一个EnhancerKey代理对象
public interface EnhancerKey {
public Object newInstance(String type,
String[] interfaces,
WeakCacheKey<CallbackFilter> filter,
Type[] callbackTypes,
boolean useFactory,
boolean interceptDuringConstruction,
Long serialVersionUID);
}
private static final EnhancerKey KEY_FACTORY =
(EnhancerKey) KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);
public static KeyFactory create(ClassLoader loader, Class keyInterface, KeyFactoryCustomizer customizer,
List<KeyFactoryCustomizer> next) {
// 创建一个最简易的代理类生成器 即只会生成HashCode equals toString newInstance方法
Generator gen = new Generator();
// 设置接口为enhancerKey类型
gen.setInterface(keyInterface);
// SPRING PATCH BEGIN
gen.setContextClass(keyInterface);
// SPRING PATCH END
if (customizer != null) {
// 添加定制器
gen.addCustomizer(customizer);
}
if (next != null && !next.isEmpty()) {
for (KeyFactoryCustomizer keyFactoryCustomizer : next) {
// 添加定制器
gen.addCustomizer(keyFactoryCustomizer);
}
}
// 设置生成器的类加载器
gen.setClassLoader(loader);
// 生成enhancerKey的代理类
return gen.create();
}
调用AbstractClassGenerator的create方法,Enhancer继承了AbstractClassGenerator,在创建Enhancer时优先设置了GET_KEY变量,这个函数接口会在后期调用,给全局变量设置下当前生成代理类的全路径名称
private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
return gen.key;
}
};
protected Object create(Object key) {
try {
// 获取到当前生成器的类加载器
ClassLoader loader = getClassLoader();
// 当前类加载器对应的缓存 缓存key为类加载器,缓存的value为ClassLoaderData,可以理解为一个缓存对象,只不过此缓存对象中包含的是具体的业务逻辑处理过程,有两个function的函数式接口,一个是返回gen.key,对应的名称叫GET_KEY,还有一个是为了创建具体的class,名字叫做load
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) {
// 新建一个缓存Cache,并将之前的缓存Cache的数据添加进来,并将已经被gc回收的数据给清除掉
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
// 新建一个当前加载器对应的ClassLoaderData并加到缓存中,但ClassLoaderData中此时还没有数据
data = new ClassLoaderData(loader);
newCache.put(loader, data);
// 刷新全局缓存
CACHE = newCache;
}
}
}
// 设置一个全局key
this.key = key;
// 在刚创建的data(ClassLoaderData)中调用get方法 并将当前生成器,
// 以及是否使用缓存的标识穿进去 系统参数 System.getProperty("cglib.useCache", "true")
// 返回的是生成好的代理类的class信息
Object obj = data.get(this, getUseCache());
// 如果为class则实例化class并返回我们需要的代理类
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
// 如果不是则说明是实体,则直接执行另一个方法返回实体
return nextInstance(obj);
}
catch (RuntimeException | Error ex) {
throw ex;
}
catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}
在create方法里面调用内部类ClassLoaderData的构造方法
public ClassLoaderData(ClassLoader classLoader) {
// 判断类加载器不能为空
if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported");
}
// 设置类加载器,弱引用 即在下次垃圾回收时就会进行回收
this.classLoader = new WeakReference<ClassLoader>(classLoader);
// 新建一个回调函数,这个回调函数的作用在于缓存中没获取到值时,调用传入的生成的生成代理类并返回
Function<AbstractClassGenerator, Object> load =
new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
Class klass = gen.generate(ClassLoaderData.this);
return gen.wrapCachedClass(klass);
}
};
// 为这个ClassLoadData新建一个缓存类
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
}
在generatedClasses里存入两个函数式接口,GET_KEY是返回当前生成代理类的全路径名称,load是生成代理class类
Object obj = data.get(this, getUseCache());
在之前只是存入了两个函数式接口,并没有进行调用,在data.get方法里完成具体的调用,load回调函数里通过Class klass = gen.generate(ClassLoaderData.this)完成EnHancerKey的Class对象的创建
public Object get(AbstractClassGenerator gen, boolean useCache) {
// 如果不用缓存(默认使用)
if (!useCache) {
// 则直接调用生成器的命令
return gen.generate(ClassLoaderData.this);
}
else {
// 传入代理类生成器 并根据代理类生成器获取值返回
Object cachedValue = generatedClasses.get(gen);
// 解包装并返回
return gen.unwrapCachedValue(cachedValue);
}
}
public V get(K key) {
KK cacheKey = this.keyMapper.apply(key);
Object v = this.map.get(cacheKey);
return v != null && !(v instanceof FutureTask) ? v : this.createEntry(key, cacheKey, v);
}
protected V createEntry(final K key, KK cacheKey, Object v) {
boolean creator = false;
FutureTask task;
Object result;
if (v != null) {
task = (FutureTask)v;
} else {
task = new FutureTask(new Callable<V>() {
public V call() throws Exception {
return LoadingCache.this.loader.apply(key);
}
});
result = this.map.putIfAbsent(cacheKey, task);
if (result == null) {
creator = true;
task.run();
} else {
if (!(result instanceof FutureTask)) {
return result;
}
task = (FutureTask)result;
}
}
try {
result = task.get();
} catch (InterruptedException var9) {
throw new IllegalStateException("Interrupted while loading cache item", var9);
} catch (ExecutionException var10) {
Throwable cause = var10.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException)cause;
}
throw new IllegalStateException("Unable to load cache item", cause);
}
if (creator) {
this.map.put(cacheKey, result);
}
return result;
}
调用两个回调方法,完成全局变量的赋值以及Class对象的创建,然后返回到firstInstance方法调用ReflectUtils.newInstance转为object对象,当完成了Enhancerkey对象的创建后才可以创建我们自己的代理对象
四、创建代理对象
//创建代理对象 MyCalculator myCalculator = (MyCalculator) enhancer.create();
public Object create() {
this.classOnly = false;
this.argumentTypes = null;
return this.createHelper();
}
private Object createHelper() {
// 校验callbackTypes、filter是否为空,以及为空时的处理
preValidate();
// 通过newInstance方法来创建EnhancerKey对象,正常情况下,只需要new一个对象就可以调用方法了,但是Key_Factory是一个EnhancerKey类型,是一个内部接口,需要动态代理来实现,最终是为了调用newInstance方法
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);
// 设置当前enhancer的代理类的key标识
this.currentKey = key;
// 调用父类即AbstractClassGenerator的创建代理类
Object result = super.create(key);
return result;
}
调用super.create时又回到之前创建代理对象EnhancerKey的create方法,此时CACHE缓存对象已经在创建EnhancerKey代理对象时完成了赋值,所以直接调用data.get完成我们本身的代理对象创建,到这一步和之前创建EnhancerKey代理对象的逻辑一样
protected Object create(Object key) {
try {
// 获取到当前生成器的类加载器
ClassLoader loader = getClassLoader();
// 当前类加载器对应的缓存 缓存key为类加载器,缓存的value为ClassLoaderData,可以理解为一个缓存对象,只不过此缓存对象中包含的是具体的业务逻辑处理过程,有两个function的函数式接口,一个是返回gen.key,对应的名称叫GET_KEY,还有一个是为了创建具体的class,名字叫做load
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) {
// 新建一个缓存Cache,并将之前的缓存Cache的数据添加进来,并将已经被gc回收的数据给清除掉
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
// 新建一个当前加载器对应的ClassLoaderData并加到缓存中,但ClassLoaderData中此时还没有数据
data = new ClassLoaderData(loader);
newCache.put(loader, data);
// 刷新全局缓存
CACHE = newCache;
}
}
}
// 设置一个全局key
this.key = key;
// 在刚创建的data(ClassLoaderData)中调用get方法 并将当前生成器,
// 以及是否使用缓存的标识穿进去 系统参数 System.getProperty("cglib.useCache", "true")
// 返回的是生成好的代理类的class信息
Object obj = data.get(this, getUseCache());
// 如果为class则实例化class并返回我们需要的代理类
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
// 如果不是则说明是实体,则直接执行另一个方法返回实体
return nextInstance(obj);
}
catch (RuntimeException | Error ex) {
throw ex;
}
catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}