6.CGLIB动态代理源码之Enhancer#create

267 阅读6分钟

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动态代理源码分析到此结束。

Enhancer#create步骤

1.生成指定类的Class对象字节数组

2.将Class对象字节数组转换为Class对象

3.通过 Class.forName 方法将Class对象装载到JVM