1 前言
上节我们看了 EnhancerKey 是通过KeyFactory里的 Generator来创建代理对象,这节我们就来看下 Enhancer是如何创建代理对象的。
2 源码分析
上节我们看过了,AbstractClassGenerator 是模板模式的枢纽,创建代理对象子类复写 generateClass 和 firstInstance两个方法即可。那么我们就来看下 Enhancer 里的是如何实现的。
2.1 generateClass
public void generateClass(ClassVisitor v) throws Exception { // 就是我们的被代理类 Demo.class Class sc = (superclass == null) ? Object.class : superclass; // 看见没如果是final直接报错 if (TypeUtils.isFinal(sc.getModifiers())) throw new IllegalArgumentException("Cannot subclass final class " + sc); // 构造器并过滤 List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors())); filterConstructors(sc, constructors); // 收集方法 List actualMethods = new ArrayList(); List interfaceMethods = new ArrayList(); 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 对asm的classAdapter和MethodAdapter的实现,贯穿于cglib代码的处理 // 理解成就是描述类的 ClassEmitter e = new ClassEmitter(v); e.begin_class(Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), Type.getType(sc), (useFactory ? TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) : TypeUtils.getTypes(interfaces)), Constants.SOURCE_FILE); List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance()); // 声明属性 e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null); if (!interceptDuringConstruction) { e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null); } e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null); e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null); if (serialVersionUID != null) { e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID); } for (int i = 0; i < callbackTypes.length; i++) { e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null); } // 添加方法、构造器、等方法 emitMethods(e, methods, actualMethods); emitConstructors(e, constructorInfo); emitSetThreadCallbacks(e); emitSetStaticCallbacks(e); emitBindCallbacks(e); // 这个就是你的代理要不要继承 Factory 可以更改你的增强逻辑 if (useFactory) { int[] keys = getCallbackKeys(); emitNewInstanceCallbacks(e); emitNewInstanceCallback(e); emitNewInstanceMultiarg(e, constructorInfo); emitGetCallback(e, keys); emitSetCallback(e, keys); emitGetCallbacks(e); emitSetCallbacks(e); } e.end_class(); }
上边在构造类的属性呀,方法什么的,其中一点我简单说下,有个 useFactory 不知道你发现没,默认是开启的,也就是开启的情况下我们的代理类会实现 Factory接口,那么这个接口是干啥的呢,我们来看下:
主要分三类方法,一类是获取设置的回调,也就是我们的增强的代码类,一类是创建代理对象,一类就是设置增强代码类,也就是说可以更改我们代理类的增强逻辑,我们来试下:
2.2 firstInstance
这个方法 firstInstance ,我们的增强逻辑也是在这个方法里塞进去的,我们来看下具体过程:
protected Object firstInstance(Class type) throws Exception { if (classOnly) { return type; } else {
// 进入这个方法 return createUsingReflection(type); } }
private Object createUsingReflection(Class type) { /** * type 是什么也就是我们代理类的类信息 * 将我们的增强类设置进去 * 然后创建出来代理对象后 * 发现finally会清空掉类信息里的增强类 至于为什么 可能是保持类的干净?我猜的哈 有知道的可以告知下 */ setThreadCallbacks(type, callbacks); try{ // 创建代理对象 if (argumentTypes != null) { return ReflectUtils.newInstance(type, argumentTypes, arguments); } else { return ReflectUtils.newInstance(type); } }finally{ // clear thread callbacks to allow them to be gc'd 清空 setThreadCallbacks(type, null); } }
ReflectUtils.newInstance 就是获取构造方法创建对象,这里就不看了哈。
3 小结
好这节我们大概看了下 Enhancer 对象创建代理对象的过程,主要就是 generateClass 和 firstInstance两个方法,有理解不对的地方欢迎指正哈。
标签:Enhancer,ACC,代理,源码,new,null,type,Constants From: https://www.cnblogs.com/kukuxjx/p/17177172.html