工具类 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 文件,打开相应开关即可。