1、基于JDK的动态代理
整个代理最核心的方法就是Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, handler)。使用JDK动态代理的时候,必须要有InvocationHandler这个对象。
2、基于CGLib的动态代理
使用CGLib动态代理的时候,不需要指定接口
准备好自定义的测试类之后,开始Debug运行代码
进入Enhancer类中
// 使用key工厂创建出对应class的代理类,后面的keyFactory.
// HASH_ASM_TYPE即代理类中创建HashCode方法的策略
private static final EnhancerKey KEY_FACTORY =(EnhancerKey) KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);
这个KeyFactory就是为了拼接或生成某些Map或Set中的key值,只是这些key值比较特殊,里面包含n多个键而已。比如1、2、3是一个组合,2、3也是一个组合,都可以作为key
进入create方法中
// 创建约一个最简单的代理类生成器
Generator gen = new Generator();
// 设置接口为enhancerKey类型
gen.setInterface(keyInterface);
// 为了整合Spring而做准备
gen.setContextClass(keyInterface);
// 添加定制器,为了扩展做准备
gen.addCustomizer(customizer);
// 设置生成器的类加载器
gen.setClassLoader(loader);
// 生成enhancerKey的代理类
// 不是具体的MyCalculator类的代理类
gen.create();
继续进入到create方法中
// 设置了该生成器生成代理类的名字前缀
// 既接口名:Enhancer.enhancerKey
setNamePrefix(keyInterface.getName());
代码继续进入到create方法中
// 获取当前生成器的类加载器
ClassLoader loader = getClassLoader();
// 当前类加载器对应的缓存,缓存key为类加载器
// 缓存的value为ClassLoaderData
// ClassLoaderData中放了2个函数式接口(Function),后续会进行调用
Map<ClassLoader, ClassLoaderData> cache = CACHE;
// 从缓存中获取当前类加载器加载过的类
ClassLoaderData data = cache.get(loader);
…..
// 新建一个缓存Cache,将之前的缓存Cache的数据
// 添加进来,并将已经被GC回收的数据清除掉
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
// 新建一个当前加载器对应的ClassLoaderData,并加入到缓存中
// 但ClassLOaderData中此时还没有数据
data = new ClassLoaderData(loader);
// 刷新全局缓存
CACHE = newCache;
…..
// 设置全局key
this.key = key;
// 在刚刚创建的ClassLoaderData中调用get方法
Object obj = data.get(this, getUseCache());
代码继续进入到get方法中
// 如果不使用缓存(默认使用)
if (!useCache) {
// 直接调用生成器的命令
return gen.generate(ClassLoaderData.this);
} else {
// 传入代理类生成器,并根据代理类生成器获取值返回
Object cachedValue = generatedClasses.get(gen);
// 解包装
return gen.unwrapCachedValue(cachedValue);
}
代码继续进入到createEntry方法中
代码继续进入到generate方法中
// 当前的代理类生成器放入ThreadLocal中
CURRENT.set(this);
// 获取类加载器
ClassLoader classLoader = data.getClassLoader();
…..
synchronized (classLoader) {
// 生成代理类名字
String name = generateClassName(data.getUniqueNamePredicate());
// 将这个名字放入缓存中
data.reserveName(name);
// 当前代理类生成器设置类名
this.setClassName(name);
}
…..
// 生成字节码
byte[] b = strategy.generate(this);
代码继续进入到generateClass方法中
// 创建类写入聚合对象
ClassEmitter ce = new ClassEmitter(v);
// 找到被代理类的newInstance方法,如果没有则会报异常
// 也就是说如果想用Generator代理类生成器,必须要有newInstance方法
Method newInstance = ReflectUtils.findNewInstance(keyInterface);
// 如果被代理类的newInstance不为Object也会报异常
// 此处代理的Enhancer.EnhancerKey newInstance方法返回值为Object
if (!newInstance.getReturnType().equals(Object.class)) {
throw new IllegalArgumentException(“newInstance method must return Object”);
}
// 找到newInstance方法的所有参数类型,并当做成员变量
Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
// 创建类开始写入类头、版本号、访问权限、类名等
ce.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
KEY_FACTORY,
new Type[]{Type.getType(keyInterface)},
Constants.SOURCE_FILE);
// 写入无参构造方法
EmitUtils.null_constructor(ce);
// 写入newInstance方法
EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));
// 写入有参构造方法
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
TypeUtils.parseConstructor(parameterTypes),
null);
// 有参构造方法中调用父类构造方法,super.xxx
e.super_invoke_constructor();
// 找到传入的方法定制器,比如:hashCode方法定制器等
List<FieldTypeCustomizer> fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class);
// 遍历成员变量,也就是newInstance方法的所有参数
for (int i = 0; i < parameterTypes.length; i++) {
…..
// 将这些参数全部声明到写入类中
ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
getFieldName(i),
fieldType,
null);
…..
// 设置每个成员变量的值
e.putfield(getFieldName(i));
}
// 设置返回值
e.return_value();
// 有参构造和成员变量写入完成
e.end_method();
// 写入hashCode方法
e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
…..
// 写入equals方法
e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
…..
// 写入toString方法
e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
…..
// 类信息已经全部写入ClassVisitor中
ce.end_class();
代码继续往下走回到generate方法中
// 获取到字节码代表的class名字
String className = ClassNameReader.getClassName(new ClassReader(b));
…..
// 往内存中加载
gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
代码继续往下走回到create方法中
// 返回生成好的代理类class信息
Object obj = data.get(this, getUseCache());
// 如果是class,则实例化class,并返回我们需要的代理类
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
// 如果不是则说明是实体,就直接执行另一个方法返回实体
return nextInstance(obj);
代码继续往下走回到main方法中,此时已经将enhancer对象创建完成。在后续创建过程中需要一个EnhancerKey的对象,所以在进行enhancer对象创建的时候需要先把EnhancerKey(newInstance)对象准备好,而这个对象也需要动态代理来创建。
代码继续往下走,进入create方法中的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);
代码继续往下走,进入super.create方法中,和刚刚创建enhancer代理一样的方法,而此时缓存中的值就不是空了
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/111913.html