Enhancer#create
在我们的测试类中,大家发现了,我们创建了一个Enhancer对象,并且设置了父类、回调函数等参数,最重要的入口函数是create方法。
/**
* 如果必须要创建一个新类,那么就用指定的回调对象创建一个新的对象实例
* 使用的父类的参数的构造方法来实例化父类的部分
*/
public Object create() {
//不作代理类限制
classOnly = false;
//没有构造参数类型
argumentTypes = null;
//执行创建
return createHelper();
}
Enhancer#createHelper
private Object createHelper() {
//校验callbackTypes、filter是否为空,以及为空时的处理
preValidate();
//通过EnhancerKey创建key
//终于知道为什么叫Enhancerkey并且变量名是KEY_FACTORY。
//原来EnhancerKey是专门用于生成代理类的缓存的key的类。
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;
//当前类是Enhancer 父类是AbstractClassGenerator
//调用父类即AbstractClassGenerator的创建代理类
Object result = super.create(key);
return result;
}
AbstractClassGenerator#create
和创建EnhancerKey的代理类一样,最后都调用了AbstractClassGenerator#create方法,不同的是AbstractClassGenerator#create方法的入参key的不同。
EnhancerKey是类的全限定名:net.sf.cglib.proxy.Enhancer$EnhancerKey
而Ehancer创建的代理类的key是由EnhancerKey的代理类创建的。
//通过EnhancerKey创建的key
protected Object create(Object key) {
try {
//获取到当前生成器的类加载器
ClassLoader loader = getClassLoader();
//CACHE= new WeakHashMap<ClassLoader, ClassLoaderData>();
//CACHE是当前类加载器对应的缓存可以理解为一级缓存
//缓存key为类加载器,缓存的value为ClassLoaderData
//ClassLoaderData可以理解为二级缓存
Map<ClassLoader, ClassLoaderData> cache = CACHE;
//先根据类加载器从一级缓存中获取对应的ClassLoaderData
ClassLoaderData data = cache.get(loader);
//如果缓存中的data为空
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
//经典的防止并发修改 二次判断 double check
if (data == null) {
//新建一个缓存Cache 并把原來的缓存加入新建的缓存中
Map<ClassLoader, ClassLoaderData> newCache
= new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
//新建一个当前加载器对应的ClassLoaderData 并加到缓存中
//ClassLoaderData#ClassLoaderData
data = new ClassLoaderData(loader);
//放入新缓存
newCache.put(loader, data);
//刷新全局缓存
CACHE = newCache;
}
}
}
// 使用创建的key
this.key = key;
//data:ClassLoaderData
//this:Enhancer
//getUseCache():可以通过Enhancer.setUseCache()设置
//data是AbstractClassGenerator$ClassLoaderData
//返回的是生成好的代理类的class信息
Object obj = data.get(this, getUseCache());
//如果为class则实例化class并返回 就是我们需要的代理类
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
//如果不是则说明是实体 则直接执行另一个方法返回实体
return nextInstance(obj);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
因为接下来的代码和创建EnhancerKey的代理类的代码都大同小异,所以直接跳过。
不同的地方在于EnhancerKey生成代理类的字节码用的是KeyFactory.Genrator#generateClass(ClassVisitor c)方法。
Enhancer生成代理类的字节码用的是Enhancer#generateClass(ClassVisitor c)方法。
调用generateClass(ClassVisitor c)方法是在DefaultGeneratorStrategy里,直接从这里看。
DefaultGeneratorStrategy#generate
public byte[] generate(ClassGenerator cg) throws Exception {
//创建一个写入器
DebuggingClassWriter cw = getClassVisitor();
//transform是模板方法
//子类可以通过transform方法加入自己的转换逻辑后
//再执行代理类生成器的generateClass方法
transform(cg).generateClass(cw);
//将cw写入的东西转换为byte数组返回
return transform(cw.toByteArray());
}
这里面主要是新建一个写入器,然后执行我们代理类生成器的generateClass方法将class信息写入这个ClassWriter 最后将里面的东西转换为byte数组返回,所以又回到了我们的代理类生成器的generateClass方法,这儿进入的是Enhancer的generateClass方法
Enhancer#generatorClass
public void generateClass(ClassVisitor v) throws Exception {
//需要代理的类或者接口 即 cglib代理.MyCalculator
Class sc = (superclass == null) ? Object.class : superclass;
//检查 final类无法被继承
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException
("Cannot subclass final class " + sc.getName());
//找到MyCalculator的所有的构造函数
List constructors = new ArrayList
(Arrays.asList(sc.getDeclaredConstructors()));
//去掉private之类的不能被继承的构造函数
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
//这儿顺序非常重要 上面是源码的注释 直接留着 相信大家都能看懂
//声明代理类方法集合
List actualMethods = new ArrayList();
//声明代理接口接口方法集合
List interfaceMethods = new ArrayList();
//声明所有必须为public的方法集合 这儿主要是代理类接口实现的接口的方法
final Set forcePublic = new HashSet();
//即通过传入的代理类 代理接口,遍历所有的方法并放入对应的集合
//主要 是获取代理类的所有方法 和 代理类所实现接口的所有方法 并过滤
//用字节码将 所有的方法写到代理类中
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
//对所有代理类方法修饰符做处理
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
public Object transform(Object value) {
Method method = (Method)value;
int modifiers = Constants.ACC_FINAL
| (method.getModifiers()
& ~Constants.ACC_ABSTRACT
& ~Constants.ACC_NATIVE
& ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
return ReflectUtils.getMethodInfo(method, modifiers);
}
});
//创建类写入器
ClassEmitter e = new ClassEmitter(v);
//1.开始创建类 并写入基本信息 如java版本,类修饰符 类名等
if (currentData == null) {
e.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
Type.getType(sc),
(useFactory ?
TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
TypeUtils.getTypes(interfaces)),
Constants.SOURCE_FILE);
} else {
e.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
null,
new Type[]{FACTORY},
Constants.SOURCE_FILE);
}
//
List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
//2. 声明一个private boolean 类型的属性:CGLIB$BOUND
e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
//3. 声明一个public static Object 类型的属性:CGLIB$FACTORY_DATA
e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
FACTORY_DATA_FIELD, OBJECT_TYPE, null);
// 这个默认为true
//如果为false则会声明一个private boolean 类型的属性:CGLIB$CONSTRUCTED
if (!interceptDuringConstruction) {
e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD,
Type.BOOLEAN_TYPE, null);
}
//4. 声明一个public static final 的ThreadLocal:CGLIB$THREAD_CALLBACKS
e.declare_field(Constants.PRIVATE_FINAL_STATIC,
THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
//5. 声明一个public static final 的CallBack类型的数组:CGLIB$STATIC_CALLBACKS
e.declare_field(Constants.PRIVATE_FINAL_STATIC,
STATIC_CALLBACKS_FIELD,CALLBACK_ARRAY, null);
//如果serialVersionUID不为null
//则设置一个public static final 的Long类型
//serialVersionUID
if (serialVersionUID != null) {
e.declare_field(Constants.PRIVATE_FINAL_STATIC,
Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
}
//遍历CallBackTypes 即我们构建Enhancer是setCallBack的所有类的类型
//本案例中是methodInterceptor 并且只传入了一个
for (int i = 0; i < callbackTypes.length; i++) {
//6.声明private修饰 我们自定义的CallBack类型的属性:
//CGLIB$CALLBACK_0 (从0开始编号,)
e.declare_field(Constants.ACC_PRIVATE,
getCallbackField(i), callbackTypes[i], null);
}
//7声明一个private static 的传入的Object类型的属性:CGLIB$CALLBACK_FILTER
e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC,
CALLBACK_FILTER_FIELD, OBJECT_TYPE, null);
//判断currentData
if (currentData == null) {
//8.如果为null则声明所有的代理类方法的变量
//以及其具体的重写实现方法,还有static初始化执行代码块
emitMethods(e, methods, actualMethods);
//9.声明构造函数
emitConstructors(e, constructorInfo);
} else {
//声明默认构造函数
emitDefaultConstructor(e);
}
//
emitSetThreadCallbacks(e);
emitSetStaticCallbacks(e);
emitBindCallbacks(e);
//如果currentData不为null
if (useFactory || currentData != null) {
//获取到所有CallBack索引数组
int[] keys = getCallbackKeys();
//10.声明三个newInstance方法
//只有一个callback参数
emitNewInstanceCallbacks(e);
//参数为callback数组
emitNewInstanceCallback(e);
//参数为callback数组 以及附带的一些参数
emitNewInstanceMultiarg(e, constructorInfo);
//11.声明getCallBack方法
emitGetCallback(e, keys);
//12.声明setCallBack方法
emitSetCallback(e, keys);
//12.声明setCallBacks方法
emitGetCallbacks(e);
//12.声明setCallBacks方法
emitSetCallbacks(e);
}
//类声明结束
e.end_class();
getMethods主要 是获取代理类的所有方法 和 代理类所实现接口的所有方法 用字节码将 所有的方法写到一个代理的类中,
private static void getMethods(Class superclass, Class[] interfaces, List methods, List interfaceMethods, Set forcePublic) {
//
ReflectUtils.addAllMethods(superclass, methods);
List target = (interfaceMethods != null) ? interfaceMethods : methods;
if (interfaces != null) {
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i] != Factory.class) {
ReflectUtils.addAllMethods(interfaces[i], target);
}
}
}
if (interfaceMethods != null) {
if (forcePublic != null) {
//这里会触发MethodWrapper类的加载,完成对MethodWrapper.MethodWrapperKey的代理
// MethodWrapper.MethodWrapperKey KEY_FACTORY =
// (MethodWrapper.MethodWrapperKey)KeyFactory.create(MethodWrapper.MethodWrapperKey.class);
//使用MethodWrapper对所有接口方法创建唯一标识
forcePublic.addAll(MethodWrapper.createSet(interfaceMethods));
}
methods.addAll(interfaceMethods);
}
// 过滤掉静态方法
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_STATIC));
// 过滤掉不可见的方法(包括两类:私有方法、默认修饰符且与目标类不在同一个包中的方法)
CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true));
// 过滤掉重复的方法(方法名、入参和返回类型都相同的方法)
CollectionUtils.filter(methods, new DuplicatesPredicate());
// 过滤掉final方法
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
}
public class MethodWrapper {
private static final MethodWrapper.MethodWrapperKey KEY_FACTORY = (MethodWrapper.MethodWrapperKey)KeyFactory.create(MethodWrapper.MethodWrapperKey.class);
private MethodWrapper() {
}
public static Object create(Method method) {
return KEY_FACTORY.newInstance(method.getName(), ReflectUtils.getNames(method.getParameterTypes()), method.getReturnType().getName());
}
public static Set createSet(Collection methods) {
Set set = new HashSet();
Iterator it = methods.iterator();
while(it.hasNext()) {
set.add(create((Method)it.next()));
}
return set;
}
public interface MethodWrapperKey {
Object newInstance(String var1, String[] var2, String var3);
}
}
MethodWrapper.MethodWrapperKey的作用是什么呢?
作用是输出方法的方法名、参数类型、返回值,用于比对方法和过滤方法。
for (Method method : Calculator.class.getMethods()) {
System.out.println(MethodWrapper.create(method));
}
输出:
add, {int, int}, int
wait,}, void
wait, {long, int}, void
wait, {long}, void
equals, {java.lang.Object}, boolean
toString,}, java.lang.String
hashCode,}, int
getClass,}, java.lang.Class
notify,}, void
notifyAll,}, void
可以看到这儿也是声明一个写入类 然后按照Ehancer的代理生成策略写入符合的class信息然后返回,最后依旧会执行toByteArray方法返回byte[]数组,这样则又回到了步骤中 根据类加载器 字节码数组来动态将代理类加载进内存中的方法了。最后我们回到根据class获取实例的代码即可返回被代理实例。 而我们执行方法时执行的是代理类中对应的方法,然后调用我们传入的callback执行 原理和jdk动态代理类似,至此 cglib动态代理源码分析到此结束。