cglib 代理的生成过程

工具类 KeyFactory

先从 KeyFactory 说起,创建 Enhancer 实例对象时,会执行如下的一段代码:

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) {
    // KeyFactory 中内部类
	Generator gen = new Generator();
	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);
	return gen.create();
}

KeyFactory$Generator 继承 AbstractClassGenerator。

public KeyFactory create() {
	setNamePrefix(keyInterface.getName());
	return (KeyFactory) super.create(keyInterface.getName());
}

 此时的 namePrefix 为 org.springframework.cglib.proxy.Enhancer$EnhancerKey,接着调用父类方法。

// AbstractClassGenerator
protected Object create(Object key) {  // 此时 key 为 org.springframework.cglib.proxy.Enhancer$EnhancerKey
	try {
		ClassLoader loader = getClassLoader();
		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) {
					Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
					data = new ClassLoaderData(loader);
					newCache.put(loader, data);
					CACHE = newCache;
				}
			}
		}
		this.key = key;
		// getUserCache() 默认 true
		// 获取新生成的 Class 对象
		Object obj = data.get(this, getUseCache());
		if (obj instanceof Class) {
			// 利用 Class,反射创建实例对象后返回
			return firstInstance((Class) obj);
		}
		return nextInstance(obj);
	}
	catch (RuntimeException | Error ex) {
		throw ex;
	}
	catch (Exception ex) {
		throw new CodeGenerationException(ex);
	}
}

可以看到,一个 ClassLoader,对应一个 ClassLoaderData,并且将传进来的参数 key 赋值给了 AbstractClassGenerator.key 属性。可以看看这个 ClassLoaderData 到底是什么。

// org.springframework.cglib.core.AbstractClassGenerator$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);
					// 包装为 WeakReference
					return gen.wrapCachedClass(klass);
				}
			};
	generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
}
	// 两个参数
	// keyMapper 生成缓存的 cacheKey
	// loader 
	public LoadingCache(Function<K, KK> keyMapper, Function<K, V> loader) {
        this.keyMapper = keyMapper;
        this.loader = loader;
        this.map = new ConcurrentHashMap();
    }
    private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
		public Object apply(AbstractClassGenerator gen) {
			return gen.key;
		}
	};

可以看到,生成的 Class 最后会缓存在 ClassLoaderData.generatedClasses 中的 map 中。再回到前面的 create 方法中,调用 data.get 方法。

// org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData
public Object get(AbstractClassGenerator gen, boolean useCache) {
	// useCache 默认 true
	if (!useCache) {
		return gen.generate(ClassLoaderData.this);
	}
	else { 
		// 将 gen 作为参数,此处 gen 为 KeyFactory$Generator
		Object cachedValue = generatedClasses.get(gen);
		// 拆装获取真实 Class 对象
		return gen.unwrapCachedValue(cachedValue);
	}
}

// LoadingCache
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);
}

利用 keyMapper 生成 cacheKey,根据 GET_KEY 可知,cacheKey 其实就是前面赋值给 AbstractClassGenerator 中的 key。接着从 map 中获取一次,不存在,调用 createEntry 进行创建。

// LoadingCache
// key AbstractClassGenerator 此时为 KeyFactory$Generator
protected V createEntry(final K key, KK cacheKey, Object v) {
	boolean creator = false;
	FutureTask task;
	Object result;
	if (v != null) {
		task = (FutureTask)v;
	} else {
		// 封装 FutureTask
		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 的操作是一个异步操作。通过构造 LoadingCache 时传入的 loader 发起调用。

// AbstractClassGenerator
protected Class generate(ClassLoaderData data) {
	Class gen;
	Object save = CURRENT.get();
	// 此时 this 为 KeyFactory$Generator
	CURRENT.set(this);
	try {
		ClassLoader classLoader = data.getClassLoader();
		if (classLoader == null) {
			throw new IllegalStateException("ClassLoader is null while trying to define class " +
					getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
					"Please file an issue at cglib's issue tracker.");
		}
		synchronized (classLoader) {
			// 生成 className
			String name = generateClassName(data.getUniqueNamePredicate());
			data.reserveName(name);
			this.setClassName(name);
		}
		// false
		if (attemptLoad) {
			try {
				gen = classLoader.loadClass(getClassName());
				return gen;
			}
			catch (ClassNotFoundException e) {
				// ignore
			}
		}
		// 生成字节码数组
		byte[] b = strategy.generate(this);
		// 读取生成的 className
		String className = ClassNameReader.getClassName(new ClassReader(b));
		ProtectionDomain protectionDomain = getProtectionDomain();
		// 加载返回 class 对象
		synchronized (classLoader) { // just in case
			// SPRING PATCH BEGIN
			gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
			// SPRING PATCH END
		}
		return gen;
	}
	catch (RuntimeException | Error ex) {
		throw ex;
	}
	catch (Exception ex) {
		throw new CodeGenerationException(ex);
	}
	finally {
		// 设为初始值
		CURRENT.set(save); 
	}
}

由于 KeyFactory$Generator 并未设置 namingPolicy 和 strategy,一律采用 AbstractClassGenerator 默认策略。

// DefaultNamingPolicy
public String getClassName(String prefix, String source, Object key, Predicate names) {
	if (prefix == null) {
		prefix = "org.springframework.cglib.empty.Object";
	} else if (prefix.startsWith("java")) {
		prefix = "$" + prefix;
	}
	// 46 即字符 '.'
	String base = prefix + "$$" + source.substring(source.lastIndexOf(46) + 1) + this.getTag() + "$$" + Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
	// 执行后 base = org.springframework.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f
	String attempt = base;

	for(int var7 = 2; names.evaluate(attempt); attempt = base + "_" + var7++) {
	}

	return attempt;
}

// DefaultGeneratorStrategy
public byte[] generate(ClassGenerator cg) throws Exception {
	DebuggingClassWriter cw = this.getClassVisitor();
	this.transform(cg).generateClass(cw);
	return this.transform(cw.toByteArray());
}
public void generateClass(ClassVisitor v) {
	
	...
	ce.begin_class(Constants.V1_8,
			Constants.ACC_PUBLIC,
			getClassName(),
			KEY_FACTORY,
			new Type[]{Type.getType(keyInterface)},
			Constants.SOURCE_FILE);
	...
}

根据生成的 className,加载这个类,得到 Class 对象后返回。并且可以知道,生成的 class 父类为 org.springframework.cglib.core.KeyFactory,实现了接口 org.springframework.cglib.proxy.Enhancer$EnhancerKey。

得到 Class 对象后,调用 KeyFactory#firstInstance 反射创建一个实例对象,最后赋值给 KEY_FACTORY。这个对象有什么用呢?继续向下看。

Enhancer 创建代理类

public Class createClass() {
	classOnly = true;
	return (Class) createHelper();
}
// Enhancer
private Object createHelper() {
	preValidate();
	// 利用动态生成的 KEY_FACTORY,调用 newInstance 方法,生成 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);
	this.currentKey = key;
	Object result = super.create(key);
	return result;
}
public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f extends KeyFactory implements EnhancerKey {
    private final String FIELD_0;
    private final String[] FIELD_1;
    private final WeakCacheKey FIELD_2;
    private final Type[] FIELD_3;
    private final boolean FIELD_4;
    private final boolean FIELD_5;
    private final Long FIELD_6;

    public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f() {
    }

    public Object newInstance(String var1, String[] var2, WeakCacheKey var3, Type[] var4, boolean var5, boolean var6, Long var7) {
        return new Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f(var1, var2, var3, var4, var5, var6, var7);
    }

    public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f(String var1, String[] var2, WeakCacheKey var3, Type[] var4, boolean var5, boolean var6, Long var7) {
        this.FIELD_0 = var1;
        this.FIELD_1 = var2;
        this.FIELD_2 = var3;
        this.FIELD_3 = var4;
        this.FIELD_4 = var5;
        this.FIELD_5 = var6;
        this.FIELD_6 = var7;
    }
	.....
	// 省略重写的 equals、hashCode、toString 方法
}

 

newInstance 来自于接口 org.springframework.cglib.proxy.Enhancer$EnhancerKey,调用这个方法的目的就是为了传递参数,来生成一个复合键对象 key。这个 key 会传递给 AbstractClassGenerator 中的属性 key,最后会作为 ClassLoaderData 中属性 generatedClass 中缓存 map 的 key 值。

在 KEY_FACTORY 对应的 newClass 中,重写了 equals、hashCode、toString 方法,会利用 newInstance 方法传入的每一个参数,去实现这些方法。

为什么要动态生成这个工具类呢?

其实目的就是根据定义的接口方法,获取参数类型,动态生成一个持有这些参数字段的类,即使以后接口发生了变化,由于工具类是在运行时根据接口方法参数动态生成的,所以程序依然会正常运行。这种使用方式特别适用于复合键对象的生成。

下面来继续看目标对象代理类的生成。

调用到父类 AbstractClassGenerator#create 方法,为 key 赋值后,从 data 中获取,获取不到,调用 LoadingCache#createEntry 异步生成代理类。

// Enhancer
@Override
protected Class generate(ClassLoaderData data) {
	validate();
	if (superclass != null) {
		// namePrefix = com.icheetor.service.impl.UserServiceImpl
		setNamePrefix(superclass.getName());
	}
	else if (interfaces != null) {
		setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
	}
	// 还是通过父类方法实现
	return super.generate(data);
}

此处设置 namePrefix 分两种情况,存在父类,采用父类名;只存在接口,采用接口名,对应接口类型下的 cglib 代理。

接着调用 AbstractClassGenerator#generate 方法,此处没有采用默认的 namingPolicy 和 strategy,而是指定了,namingPolicy 为 SpringNamingPolicy,strategy 为 ClassLoaderAwareGeneratorStrategy。

// ClassLoaderAwareGeneratorStrategy
@Override
public byte[] generate(ClassGenerator cg) throws Exception {
	if (this.classLoader == null) {
		return super.generate(cg);
	}

	Thread currentThread = Thread.currentThread();
	ClassLoader threadContextClassLoader;
	try {
		// 线程上下文类加载器
		threadContextClassLoader = currentThread.getContextClassLoader();
	}
	catch (Throwable ex) {
		// Cannot access thread context ClassLoader - falling back...
		return super.generate(cg);
	}

	boolean overrideClassLoader = !this.classLoader.equals(threadContextClassLoader);
	if (overrideClassLoader) {
		currentThread.setContextClassLoader(this.classLoader);
	}
	try {
		return super.generate(cg);
	}
	finally {
		if (overrideClassLoader) {
			// Reset original thread context ClassLoader.
			currentThread.setContextClassLoader(threadContextClassLoader);
		}
	}
}

此类的目的,如果当前 classLoader 和 线程上下文类加载器不一致,设置线程上下文类加载器为 当前类加载器。

最后调入 Enhancer#generateClass 中,完成目标代理类的创建,我们称之为 proxyClass。此处有一点要注意,就是在 generateClass 方法中,又动态生成了一个工具类 MethodWrapper$MethodWrapperKey。

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);
    }
}

有没有似曾相识的感觉?一样的内部接口,利用 KeyFactory,传入接口 Class,生成 KEY_FACTORY,调用 newInstance,返回一个复合对象,此时 key 中字段为方法名、参数类型名称数组、返回值类型名称。

以此实现对接口方法的去重,最后将 set 集合返回。

在对所有方法进行去重的实现类 DuplicatesPredicate 中,还是采用了 MethodWrapper 中新生成的工具对象 KEY_FACTORY 来实现。

MethodProxy

完成 proxyClass 类的创建后,在 AbstractClassGenerate#generate 中,调用 ReflectUtils#defineClass 对 proxyClass 进行加载。

在新创建的代理类中,存在 static 静态代码块,当类加载时,调用 CGLIB$STATICHOOK1 钩子方法为 static 字段进行初始化赋值。

举个例子:

// var1  com.icheetor.service.impl.UserServiceImpl
// var0  com.icheetor.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$4a169aa
CGLIB$doSome$1$Proxy = MethodProxy.create(var1, var0, "()V", "doSome", "CGLIB$doSome$1");

参数 var1 表示被代理类 Class。

参数 var0 表示代理类 Class。

public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {

	MethodProxy proxy = new MethodProxy();
	proxy.sig1 = new Signature(name1, desc);
	proxy.sig2 = new Signature(name2, desc);
	proxy.createInfo = new CreateInfo(c1, c2);
	return proxy;
}
// org.springframework.cglib.proxy.MethodProxy$CreateInfo
public CreateInfo(Class c1, Class c2) {
	this.c1 = c1;
	this.c2 = c2;
	// 此时由于还处在目标类动态增强的过程中,直接获取到 Enhancer
	AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
	if (fromEnhancer != null) {
		// SpringNamingPolicy
		namingPolicy = fromEnhancer.getNamingPolicy();  
		// ClassLoaderAwareGeneratorStrategy
		strategy = fromEnhancer.getStrategy();
		// false
		attemptLoad = fromEnhancer.getAttemptLoad();
	}
}

至此完成了类的加载,在方法返回的过程中,在 AbstractClassGenerator$ClassLoaderData 构造方法定义的 load 中,调用 wrapCachedClass,Enhancer 对这个方法完成了重写。

// Enhancer 重写了 AbstractClassGenerator#wrapCachedClass 方法
@Override
protected Object wrapCachedClass(Class klass) {
	Class[] argumentTypes = this.argumentTypes;
	if (argumentTypes == null) {
		argumentTypes = Constants.EMPTY_CLASS_ARRAY;
	}
	EnhancerFactoryData factoryData = new EnhancerFactoryData(klass, argumentTypes, classOnly);
	Field factoryDataField = null;
	try {
		// The subsequent dance is performed just once for each class,
		// so it does not matter much how fast it goes
		factoryDataField = klass.getField(FACTORY_DATA_FIELD);  // CGLIB$FACTORY_DATA
		factoryDataField.set(null, factoryData);
		Field callbackFilterField = klass.getDeclaredField(CALLBACK_FILTER_FIELD);  // CGLIB$CALLBACK_FILTER
		callbackFilterField.setAccessible(true);
		callbackFilterField.set(null, this.filter);
	}
	catch (NoSuchFieldException e) {
		throw new CodeGenerationException(e);
	}
	catch (IllegalAccessException e) {
		throw new CodeGenerationException(e);
	}
	return new WeakReference<EnhancerFactoryData>(factoryData);
}

最后在 Enhancer#nextInstance 方法中返回这个 Class 对象,赋值给 proxyClass。

方法调用时的代理创建

我们先来看看在创建的 proxyClass 中,方法被代理后具体是什么样?

final void CGLIB$doSome$1() {
	super.doSome();
}

public final void doSome() {
	MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
	if (var10000 == null) {
		CGLIB$BIND_CALLBACKS(this);
		var10000 = this.CGLIB$CALLBACK_0;
	}

	if (var10000 != null) {
		var10000.intercept(this, CGLIB$doSome$1$Method, CGLIB$emptyArgs, CGLIB$doSome$1$Proxy);
	} else {
		super.doSome();
	}
}
public interface MethodInterceptor extends Callback {
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
                               MethodProxy proxy) throws Throwable;
}

这不是 Aop 中定义的 org.aopalliance.intercept.MethodInterceptor,而是 cglib 中定义的 net.sf.cglib.proxy.MethodInterceptor,spring 引入 cglib 后,将包名替换了,最后变成了org.springframework.cglib.proxy.MethodInterceptor。

当我们设置 Callback 时,其实就是在设置 org.springframework.cglib.proxy.MethodInterceptor。在实现 cglib 代理时,spring 对 org.springframework.cglib.proxy.MethodInterceptor 的实现类为 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor,所以最后的 intercept 方法调用会进入 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor 中去执行。

当执行完最后一个拦截器调用时,会执行连接点方法,即被代理方法的调用,org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation 重写了 invokeJoinPoint 方法。

// org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation
@Override
protected Object invokeJoinpoint() throws Throwable {
	if (this.methodProxy != null) {
		try {
			return this.methodProxy.invoke(this.target, this.arguments);
		}
		catch (CodeGenerationException ex) {
			logFastClassGenerationFailure(this.method);
		}
	}
	return super.invokeJoinpoint();
}

methodProxy 在 proxyClass 加载的时候,已经完成了实例化。下面我们来看看这个调用会发生什么。

FastClass

public Object invoke(Object obj, Object[] args) throws Throwable {
	try {
		init();
		FastClassInfo fci = fastClassInfo;
		// 发起调用
		return fci.f1.invoke(fci.i1, obj, args);
	}
	catch (InvocationTargetException ex) {
		throw ex.getTargetException();
	}
	catch (IllegalArgumentException ex) {
		if (fastClassInfo.i1 < 0)
			throw new IllegalArgumentException("Protected method: " + sig1);
		throw ex;
	}
}
private void init() {
	/*
	 * Using a volatile invariant allows us to initialize the FastClass and
	 * method index pairs atomically.
	 *
	 * Double-checked locking is safe with volatile in Java 5.  Before 1.5 this
	 * code could allow fastClassInfo to be instantiated more than once, which
	 * appears to be benign.
	 */
	if (fastClassInfo == null) {
		synchronized (initLock) {
			if (fastClassInfo == null) {
				// 拿到创建 MethodProxy 时的 createInfo
				CreateInfo ci = createInfo;

				FastClassInfo fci = new FastClassInfo();
				// 动态生成 f1
				fci.f1 = helper(ci, ci.c1);
				// 动态生成 f2
				fci.f2 = helper(ci, ci.c2);
				// sig1 执行 toString 后得到字符串求 hashCode,根据 hashCode 和方法签名,返回 index
				fci.i1 = fci.f1.getIndex(sig1);  // 1
				fci.i2 = fci.f2.getIndex(sig2);  // 17
				fastClassInfo = fci;
				// init 方法只执行一次
				createInfo = null;
			}
		}
	}
}

private static FastClass helper(CreateInfo ci, Class type) {
	FastClass.Generator g = new FastClass.Generator();
	g.setType(type);
	// SPRING PATCH BEGIN
	g.setContextClass(type);
	// SPRING PATCH END
	// 使用 c2 的 ClassLoader
	g.setClassLoader(ci.c2.getClassLoader());
	// SpringNamingPolicy
	g.setNamingPolicy(ci.namingPolicy);
	// ClassLoaderAwareGeneratorStrategy
	g.setStrategy(ci.strategy);
	// false
	g.setAttemptLoad(ci.attemptLoad);
	return g.create();
}

在创建 MethodProxy 对象时,已经为 createInfo 赋值,仍采用 Enhancer 中配置的 namingPolicy 和 strategy。 

// org.springframework.cglib.reflect.FastClass$Generator
public FastClass create() {
	// com.icheetor.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$4a169aa
	this.setNamePrefix(this.type.getName());
	return (FastClass)super.create(this.type.getName());
}
// FastClass
public void generateClass(ClassVisitor v) throws Exception {
	new FastClassEmitter(v, this.getClassName(), this.type);
}

 最后创建出一个父类为 org.springframework.cglib.reflect.FastClass 的工具类。

创建完工具类后,调用 FastClass$Generator#firstInstance 完成实例对象的创建。

protected Object firstInstance(Class type) {
	return ReflectUtils.newInstance(type, new Class[]{Class.class}, new Object[]{this.type});
}

在 init 方法中可以看到,生成了两个动态类,一个对应的 type 为 c1,即被代理类;一个对应的 type 为 c2,即目标代理类。

举个例子:

c1:com.icheetor.service.impl.UserServiceImpl

动态类:com.icheetor.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$208db98d


c2:com.icheetor.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$4a169aa

动态类:com.icheetor.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$4a169aa$$FastClassBySpringCGLIB$$190c557b

最后为 fci 中的 f1 和 f2 赋值,接着调用 getIndex 为 i1 和 i2 赋值。

下面来看下 FastClass 中 抽象方法 getIndex 在动态类中的具体实现:

public int getIndex(Signature var1) {
	String var10000 = var1.toString();
	switch(var10000.hashCode()) {
	case -1166389848:
		if (var10000.equals("print()V")) {
			return 5;
		}
		break;
	case -543458570:
		if (var10000.equals("doSome()V")) {
			return 0;
		}
		break;
	case 1826985398:
		if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
			return 2;
		}
		break;
	case 1913648695:
		if (var10000.equals("toString()Ljava/lang/String;")) {
			return 3;
		}
		break;
	case 1952954384:
		if (var10000.equals("doOther()V")) {
			return 1;
		}
		break;
	case 1984935277:
		if (var10000.equals("hashCode()I")) {
			return 4;
		}
	}

	return -1;
}

根据传入的签名 var1 计算 hashCode,根据 hashCode 得到索引。

// fci.f1
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
	UserServiceImpl var10000 = (UserServiceImpl)var2;
	int var10001 = var1;

	try {
		switch(var10001) {
		case 0:
			var10000.doSome();
			return null;
		case 1:
			var10000.doOther();
			return null;
		case 2:
			return new Boolean(var10000.equals(var3[0]));
		case 3:
			return var10000.toString();
		case 4:
			return new Integer(var10000.hashCode());
		case 5:
			var10000.print();
			return null;
		}
	} catch (Throwable var4) {
		throw new InvocationTargetException(var4);
	}

	throw new IllegalArgumentException("Cannot find matching method/constructor");
}

有一点需要注意,getIndex 返回的索引值并不是固定的,只是和 invoke 方法中根据索引调用的方法匹配即可。

实现了在相同类型的不同对象上调用原始方法。

为什么要生成 FastClass 代理类

现在来想想为什么要生成这个父类为 FastClass 的代理类?

先来看看,如果不重写 invokeJoinpoint 方法下的情况:

// ReflectiveMethodInvocation
@Nullable
protected Object invokeJoinpoint() throws Throwable {
	return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

利用反射调用方法,而反射本身是有性能开销的。

重写后,方法的调用,在前面生成的 invoke 方法中可以看到,就是用 原始对象 UserServiceImpl来发起调用的,这样就避免了反射开销。

顺便说下,在 Dubbo 框架中,也借鉴了这种思想,在 service 端提供服务时,利用 Javassist 动态生成一个 Wrapper,调用时 wrapper.invokeMethod 最终转化成通过 原始对象 去调用待调用的方法,减少了反射开销。

如果想查看生成的代理类中的全部代码,参考 Cglib 查看生成的 class 文件,打开相应开关即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潭影空人心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值