Cglib 动态代理原理:动态生成继承自目标类的代理类,通过 MethodProxy 生成继承自 FastClass 的 目标类 和 代理类 分别基于 FastClass 的代理类 拦截并调用父类相应的方法。因此 目标类不能被 final 修饰,否则报错。
- Cglib 基于 asm 库直接操作字节码,直接操作底层JVM的汇编指令,要求使用者要对 class 组织结构和 JVM 汇编指令有一定的了解
- Cglib 动态代理通过继承目标类实现
- Cglib 动态代理通过对象直接调用,不涉及反射调用(也可以反射),性能较 JDK动态代理 和 Javassist 动态代理更优
public class ProxyTarget {
public void doSomething() {
System.out.println("do something");
}
}
Cglib动态代理拦截器实现,实现 net.sf.cglib.proxy.MethodInterceptor
接口,其中:
/**
* obj: 继承自目标类动态生成的代理类对象
* method: 目标类方法
* args: 目标类实际调用参数
* proxy: 动态生成代理类对应目标方法生成的代理方法
**/
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy)
实现中可以使用:
- method.invoke --使用反射,实际上并未使用到 Cglib MethodProxy 和 FastClass
method.invoke(target, args);
proxy.invoke 和 proxy.invokeSuper 都会使用到 Cglib MethodProxy 生成 FastClass,为方法签名,并为签名建立索引,使目标对象通过 switch case 根据索引直接调用目标方法。
- proxy.invoke --通过调用目标类生成的 FastClass 实现类
- proxy.invokeSuper --通过调用代理类生成的 FastClass 实现类
proxy.invoke(target, args); //通过目标类生成的 FastClass 调用目标类实例的目标方法 proxy.invoke(obj, args); //循环调用导致:StackOverflowError proxy.invokeSuper(target, args); //目标类向动态代理类强转导致:ClassCastException proxy.invokeSuper(obj, args); //通过由代理类生成的 FastClass 调用代理类实例的目标方法
import net.sf.cglib.proxy.*;
import java.lang.reflect.Method;
public final class CglibProxyFactory<T> {
private T target;
private Enhancer enhancer;
public CglibProxyFactory(T target) {
this.enhancer = new Enhancer();
this.enhancer.setCallback(getDefaultCallback());
this.enhancer.setCallbackFilter(getDefaultCallbackFilter());
this.target = target;
}
public T getProxy() {
enhancer.setSuperclass(target.getClass());
//enhancer.setInterfaces(target.getClass().getInterfaces());
return (T) enhancer.create();
//return (T) Enhancer.create(target.getClass(), this);
}
public void setCallback(Callback callbak) {
this.enhancer.setCallback(callbak);
}
public void setCallbacks(Callback[] callbaks) {
this.enhancer.setCallbacks(callbaks);
}
public void setCallbackFilter(CallbackFilter filter) {
this.enhancer.setCallbackFilter(filter);
}
private Callback getDefaultCallback() {
return (MethodInterceptor) (Object obj, Method method, Object[] args, MethodProxy proxy) -> {
System.out.println("before " + method.getName() + " execution...");
//Object result = method.invoke(target, args);
//Object result = proxy.invoke(target, args);
//Object result = proxy.invoke(obj, args);//StackOverflowError
//Object result = proxy.invokeSuper(target, args);//ClassCastException
Object result = proxy.invokeSuper(obj, args);
System.out.println("after " + method.getName() + " execution...");
return result;
};
}
private CallbackFilter getDefaultCallbackFilter() {
return (Method method) -> {
//返回Callback数组对应的索引,执行相应的过滤操作
if (method.getName().equals("doSomething")) {
return 0;
}
return 0;
};
}
}
Cglib动态代理通过 Enhancer::create 去创建代理对象,需要设置superclass、interfaces(可选)、callback等参数。create 最终调用 createHelper 方法:
private Object createHelper() {
validate();
if (superclass != null) {
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter,
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID));
}
这里分为两步:
-
KEY_FACTORY是在Enhancer被加载时初始化的 static final 对象:
private static final EnhancerKey KEY_FACTORY = (EnhancerKey)KeyFactory.create(EnhancerKey.class);
-
通过 KEY_FACTORY.newInstance 动态生成一个继承自KeyFactory并实现Enhancer.EnhancerKey接口的类(仅包含一个newInstance接口方法),并创建该类的实例
-
通过上一步的实例,创建目标类的代理类,创建过程中还会创建一个继承自KeyFactory并实现MethodWrapper.MethodWrapperKey接口的类(仅包含一个newInstance接口方法)。
KeyFactory::create
Generator是AbstractClassGenerator一个实现类,用于动态生成Class文件
public static KeyFactory create(ClassLoader loader, Class keyInterface, Customizer customizer) {
Generator gen = new Generator();
gen.setInterface(keyInterface);
gen.setCustomizer(customizer);
gen.setClassLoader(loader);
return gen.create();
}
AbstractClassGenerator::create
通过调用 strategy.generate(this) 将定义的类信息转换成 byte[]
private GeneratorStrategy strategy = DefaultGeneratorStrategy.INSTANCE;
protected Object create(Object key) {
try {
Class gen = null;
synchronized (source) {
ClassLoader loader = getClassLoader();
Map cache2 = null;
cache2 = (Map)source.cache.get(loader);
if (cache2 == null) {
cache2 = new HashMap();
cache2.put(NAME_KEY, new HashSet());
source.cache.put(loader, cache2);
} else if (useCache) {
Reference ref = (Reference)cache2.get(key);
gen = (Class) (( ref == null ) ? null : ref.get());
}
if (gen == null) {
Object save = CURRENT.get();
CURRENT.set(this);
try {
this.key = key;
if (attemptLoad) {
try {
gen = loader.loadClass(getClassName());
} catch (ClassNotFoundException e) {
// ignore
}
}
if (gen == null) {
byte[] b = strategy.generate(this);
String className = ClassNameReader.getClassName(new ClassReader(b));
getClassNameCache(loader).add(className);
gen = ReflectUtils.defineClass(className, b, loader);
}
if (useCache) {
cache2.put(key, new WeakReference(gen));
}
return firstInstance(gen);
} finally {
CURRENT.set(save);
}
}
}
return firstInstance(gen);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
DefaultGeneratorStrategy::generate
将 ClassWriter 转换为 byte[] 数组,ClassWriter 默认为 DebuggingClassWriter
public byte[] generate(ClassGenerator cg) throws Exception {
ClassWriter cw = getClassWriter();
transform(cg).generateClass(cw);
return transform(cw.toByteArray());
}
protected ClassWriter getClassWriter() throws Exception {
return new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
}
DebuggingClassWriter::static
- 系统属性:DEBUG_LOCATION_PROPERTY = “cglib.debugLocation” 的有无决定是否生成class文件
- org.objectweb.asm.util.TraceClassVisitor 类文件是否存在决定在生成 class 时生成 .asm 后缀的跟踪文件
static {
debugLocation = System.getProperty(DEBUG_LOCATION_PROPERTY);
if (debugLocation != null) {
System.err.println("CGLIB debugging enabled, writing to '" + debugLocation + "'");
try {
Class.forName("org.objectweb.asm.util.TraceClassVisitor");
traceEnabled = true;
} catch (Throwable ignore) {
}
}
}
...
public byte[] toByteArray() {
return (byte[]) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
byte[] b = DebuggingClassWriter.super.toByteArray();
if (debugLocation != null) {
String dirs = className.replace('.', File.separatorChar);
try {
new File(debugLocation + File.separatorChar + dirs).getParentFile().mkdirs();
File file = new File(new File(debugLocation), dirs + ".class");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
out.write(b);
} finally {
out.close();
}
if (traceEnabled) {
file = new File(new File(debugLocation), dirs + ".asm");
out = new BufferedOutputStream(new FileOutputStream(file));
try {
ClassReader cr = new ClassReader(b);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
TraceClassVisitor tcv = new TraceClassVisitor(null, pw);
cr.accept(tcv, 0);
pw.flush();
} finally {
out.close();
}
}
} catch (IOException e) {
throw new CodeGenerationException(e);
}
}
return b;
}
});
}
}
Generator::generateClass
组装Class文件
public void generateClass(ClassVisitor v) {
ClassEmitter ce = new ClassEmitter(v);
Method newInstance = ReflectUtils.findNewInstance(keyInterface);
if (!newInstance.getReturnType().equals(Object.class)) {
throw new IllegalArgumentException("newInstance method must return Object");
}
Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
KEY_FACTORY,
new Type[]{ Type.getType(keyInterface) },
Constants.SOURCE_FILE);
EmitUtils.null_constructor(ce);
EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));
int seed = 0;
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
TypeUtils.parseConstructor(parameterTypes),
null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
for (int i = 0; i < parameterTypes.length; i++) {
seed += parameterTypes[i].hashCode();
ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
getFieldName(i),
parameterTypes[i],
null);
e.dup();
e.load_arg(i);
e.putfield(getFieldName(i));
}
e.return_value();
e.end_method();
// hash code
e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
int hc = (constant != 0) ? constant : PRIMES[(int)(Math.abs(seed) % PRIMES.length)];
int hm = (multiplier != 0) ? multiplier : PRIMES[(int)(Math.abs(seed * 13) % PRIMES.length)];
e.push(hc);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.hash_code(e, parameterTypes[i], hm, customizer);
}
e.return_value();
e.end_method();
// equals
e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
Label fail = e.make_label();
e.load_arg(0);
e.instance_of_this();
e.if_jump(e.EQ, fail);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
e.load_arg(0);
e.checkcast_this();
e.getfield(getFieldName(i));
EmitUtils.not_equals(e, parameterTypes[i], fail, customizer);
}
e.push(1);
e.return_value();
e.mark(fail);
e.push(0);
e.return_value();
e.end_method();
// toString
e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
e.new_instance(Constants.TYPE_STRING_BUFFER);
e.dup();
e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
e.push(", ");
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizer);
}
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
e.return_value();
e.end_method();
ce.end_class();
}
Enhancer::generateClass
Enhancer 继承 AbstractClassGenerator ,用于组装目标代理类。其中,MethodWrapper.create(method) 将会触发生成另外一个实现 MethodWrapper.MethodWrapperKey 接口的代理类。
public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null) ? Object.class : superclass;
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc);
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
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();
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);
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);
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();
}
MethodWrapper::create
和创建 Enhancer.EnhancerKey 接口代理类原理一样,都是通过 KeyFactory 去创建。
private static final MethodWrapperKey KEY_FACTORY =
(MethodWrapperKey)KeyFactory.create(MethodWrapperKey.class);
public static Object create(Method method) {
return KEY_FACTORY.newInstance(method.getName(),
ReflectUtils.getNames(method.getParameterTypes()),
method.getReturnType().getName());
}
Enhancer::firstInstance
Enhancer::create 中调用 strategy::generate
生成 byte[] 后会调用 firstInstance 方法,这个抽象方法由 AbstractClassGenerator 的各个子类实现(Enhancer 和 KeyFactory$Generator),在 Enhancer 中,根据 classOnly 这个参数决定是生成实例还是直接返回 Class 对象,只有在调用 Enhancer::createClass
时才直接返回 Class 对象,其他都是是返回实例。
protected Object firstInstance(Class type) throws Exception {
if (classOnly) {
return type;
} else {
return createUsingReflection(type);
}
}
KeyFactory$Generator::firstInstance
在 KeyFactory$Generator 中 firstInstance 直接创建并返回实例对象:
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type);
}
测试类
通过设置系统变量 DebuggingClassWriter.DEBUG_LOCATION_PROPERTY 将动态代理类生成从 System.out 重定向到 D:/cglib-dynamic-proxy 目录:
import net.sf.cglib.core.DebuggingClassWriter;
public class CglibDynamicProxyTester {
public static void main(String args[]) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/cglib-dynamic-proxy");
ProxyTarget target = new ProxyTarget();
CglibDynamicProxyMethodInterceptor interceptor = new CglibDynamicProxyMethodInterceptor(target);
ProxyTarget proxy = (ProxyTarget) interceptor.getProxy();
proxy.doSomething();
}
}
目录结构:
D:\cglib-dynamic-proxy>
D:.
| asm-3.3.1.jar
| cfr-0.140.jar
| cglib-2.2.2.jar
| CglibDynamicProxyTester.java
| CglibProxyFactory.java
| ProxyTarget$$EnhancerByCGLIB$$d1fa18f0$$FastClassByCGLIB$$25a353a0.class
| ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.class
| ProxyTarget$$FastClassByCGLIB$$e11ac57f.class
| ProxyTarget.java
|
\---net
\---sf
\---cglib
+---core
| MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7.class
|
\---proxy
Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72.class
反编译动态代理生成的class文件:
//设置环境变量:CLASSPATH 链接 cglib 和 asm 的 jar 包
D:\cglib-dynamic-proxy>SET CLASSPATH=%CLASSPATH%;./cglib-2.2.2.jar;./asm-3.3.1.jar;
//编译 java 文件
D:\cglib-dynamic-proxy>javac -d ./ ./*.java
//执行测试方法
D:\cglib-dynamic-proxy>java CglibDynamicProxyTester
//cfr 反编译 cglib 生成的动态代理对象
D:\cglib-dynamic-proxy>java -jar cfr-0.140.jar net/sf/cglib/proxy/Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72.class --outputdir .
D:\cglib-dynamic-proxy>java -jar cfr-0.140.jar net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7.class --outputdir .
D:\cglib-dynamic-proxy>java -jar cfr-0.140.jar ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.class --outputdir .
D:\cglib-dynamic-proxy>java -jar cfr-0.140.jar ProxyTarget$$FastClassByCGLIB$$e11ac57f.class --outputdir .
D:\cglib-dynamic-proxy>java -jar cfr-0.140.jar ProxyTarget$$EnhancerByCGLIB$$d1fa18f0$$FastClassByCGLIB$$25a353a0.class --outputdir .
代理类:ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.java
,继承自目标类:ProxyTarget
- 通过 MethodProxy 用代理类对象的 doSomthing 方法代理目标类 doSomthing 方法
- 在动态生成代理类对象的 doSomthing 方法中调用自定义拦截器的 intercept 方法。
/*
* Decompiled with CFR 0.140.
*
* Could not load the following classes:
* net.sf.cglib.core.ReflectUtils
* net.sf.cglib.core.Signature
* net.sf.cglib.proxy.Callback
* net.sf.cglib.proxy.Factory
* net.sf.cglib.proxy.MethodInterceptor
* net.sf.cglib.proxy.MethodProxy
*/
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyTarget$$EnhancerByCGLIB$$d1fa18f0
extends ProxyTarget
implements Factory {
private boolean CGLIB$BOUND;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static final Method CGLIB$doSomething$0$Method;
private static final MethodProxy CGLIB$doSomething$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$finalize$1$Method;
private static final MethodProxy CGLIB$finalize$1$Proxy;
private static final Method CGLIB$equals$2$Method;
private static final MethodProxy CGLIB$equals$2$Proxy;
private static final Method CGLIB$toString$3$Method;
private static final MethodProxy CGLIB$toString$3$Proxy;
private static final Method CGLIB$hashCode$4$Method;
private static final MethodProxy CGLIB$hashCode$4$Proxy;
private static final Method CGLIB$clone$5$Method;
private static final MethodProxy CGLIB$clone$5$Proxy;
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class<?> class_ = Class.forName("ProxyTarget$$EnhancerByCGLIB$$d1fa18f0");
Class<?> class_2 = Class.forName("java.lang.Object");
Method[] arrmethod = ReflectUtils.findMethods((String[])new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (Method[])class_2.getDeclaredMethods());
CGLIB$finalize$1$Method = arrmethod[0];
CGLIB$finalize$1$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"finalize", (String)"CGLIB$finalize$1");
CGLIB$equals$2$Method = arrmethod[1];
CGLIB$equals$2$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/Object;)Z", (String)"equals", (String)"CGLIB$equals$2");
CGLIB$toString$3$Method = arrmethod[2];
CGLIB$toString$3$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/String;", (String)"toString", (String)"CGLIB$toString$3");
CGLIB$hashCode$4$Method = arrmethod[3];
CGLIB$hashCode$4$Proxy = MethodProxy.create(class_2, class_, (String)"()I", (String)"hashCode", (String)"CGLIB$hashCode$4");
CGLIB$clone$5$Method = arrmethod[4];
CGLIB$clone$5$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/Object;", (String)"clone", (String)"CGLIB$clone$5");
class_2 = Class.forName("ProxyTarget");
CGLIB$doSomething$0$Method = ReflectUtils.findMethods((String[])new String[]{"doSomething", "()V"}, (Method[])class_2.getDeclaredMethods())[0];
CGLIB$doSomething$0$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"doSomething", (String)"CGLIB$doSomething$0");
}
final void CGLIB$doSomething$0() {
super.doSomething();
}
public final void doSomething() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$doSomething$0$Method, CGLIB$emptyArgs, CGLIB$doSomething$0$Proxy);
return;
}
super.doSomething();
}
final void CGLIB$finalize$1() throws Throwable {
super.finalize();
}
protected final void finalize() throws Throwable {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$finalize$1$Method, CGLIB$emptyArgs, CGLIB$finalize$1$Proxy);
return;
}
super.finalize();
}
final boolean CGLIB$equals$2(Object object) {
return super.equals(object);
}
public final boolean equals(Object object) {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$2$Method, new Object[]{object}, CGLIB$equals$2$Proxy);
return object2 == null ? false : (Boolean)object2;
}
return super.equals(object);
}
final String CGLIB$toString$3() {
return super.toString();
}
public final String toString() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
return (String)methodInterceptor.intercept((Object)this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy);
}
return super.toString();
}
final int CGLIB$hashCode$4() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
return object == null ? 0 : ((Number)object).intValue();
}
return super.hashCode();
}
final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
return methodInterceptor.intercept((Object)this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy);
}
return super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature signature) {
String string = signature.toString();
switch (string.hashCode()) {
case -1574182249: {
if (!string.equals("finalize()V")) break;
return CGLIB$finalize$1$Proxy;
}
case -508378822: {
if (!string.equals("clone()Ljava/lang/Object;")) break;
return CGLIB$clone$5$Proxy;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) break;
return CGLIB$equals$2$Proxy;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) break;
return CGLIB$toString$3$Proxy;
}
case 1984935277: {
if (!string.equals("hashCode()I")) break;
return CGLIB$hashCode$4$Proxy;
}
case 2121560294: {
if (!string.equals("doSomething()V")) break;
return CGLIB$doSomething$0$Proxy;
}
}
return null;
}
public ProxyTarget$$EnhancerByCGLIB$$d1fa18f0() {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0 proxyTarget$$EnhancerByCGLIB$$d1fa18f0 = this;
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(proxyTarget$$EnhancerByCGLIB$$d1fa18f0);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] arrcallback) {
CGLIB$THREAD_CALLBACKS.set(arrcallback);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] arrcallback) {
CGLIB$STATIC_CALLBACKS = arrcallback;
}
private static final void CGLIB$BIND_CALLBACKS(Object object) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0 proxyTarget$$EnhancerByCGLIB$$d1fa18f0 = (ProxyTarget$$EnhancerByCGLIB$$d1fa18f0)object;
if (!proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BOUND) {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BOUND = true;
Object object2 = CGLIB$THREAD_CALLBACKS.get();
if (object2 != null || (object2 = CGLIB$STATIC_CALLBACKS) != null) {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])object2)[0];
}
}
}
public Object newInstance(Callback[] arrcallback) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(arrcallback);
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(null);
return new ProxyTarget$$EnhancerByCGLIB$$d1fa18f0();
}
public Object newInstance(Callback callback) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(new Callback[]{callback});
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(null);
return new ProxyTarget$$EnhancerByCGLIB$$d1fa18f0();
}
/*
* Unable to fully structure code
* Enabled aggressive block sorting
* Lifted jumps to return sites
*/
public Object newInstance(Class[] var1_1, Object[] var2_2, Callback[] var3_3) {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(var3_3);
switch (var1_1.length) {
case 0: {
** break;
}
}
throw new IllegalArgumentException("Constructor not found");
lbl6: // 1 sources:
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS(null);
return new ProxyTarget$$EnhancerByCGLIB$$d1fa18f0();
}
public Callback getCallback(int n) {
MethodInterceptor methodInterceptor;
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
switch (n) {
case 0: {
methodInterceptor = this.CGLIB$CALLBACK_0;
break;
}
default: {
methodInterceptor = null;
}
}
return methodInterceptor;
}
public void setCallback(int n, Callback callback) {
switch (n) {
case 0: {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
break;
}
}
}
public Callback[] getCallbacks() {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$BIND_CALLBACKS(this);
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0 proxyTarget$$EnhancerByCGLIB$$d1fa18f0 = this;
return new Callback[]{this.CGLIB$CALLBACK_0};
}
public void setCallbacks(Callback[] arrcallback) {
Callback[] arrcallback2 = arrcallback;
Callback[] arrcallback3 = arrcallback2;
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0 proxyTarget$$EnhancerByCGLIB$$d1fa18f0 = this;
this.CGLIB$CALLBACK_0 = (MethodInterceptor)arrcallback2[0];
}
static {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$STATICHOOK1();
}
}
Enhancer.EnhancerKey 接口代理类:Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72.java
/*
* Decompiled with CFR 0.140.
*
* Could not load the following classes:
* net.sf.cglib.core.KeyFactory
* net.sf.cglib.proxy.CallbackFilter
* net.sf.cglib.proxy.Enhancer
* net.sf.cglib.proxy.Enhancer$EnhancerKey
* org.objectweb.asm.Type
*/
package net.sf.cglib.proxy;
import net.sf.cglib.core.KeyFactory;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import org.objectweb.asm.Type;
public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72
extends KeyFactory
implements Enhancer.EnhancerKey {
private final String FIELD_0;
private final String[] FIELD_1;
private final CallbackFilter 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$$7fb24d72() {
}
public Object newInstance(String string, String[] arrstring, CallbackFilter callbackFilter, Type[] arrtype, boolean bl, boolean bl2, Long l) {
return new Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(string, arrstring, callbackFilter, arrtype, bl, bl2, l);
}
public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(String string, String[] arrstring, CallbackFilter callbackFilter, Type[] arrtype, boolean bl, boolean bl2, Long l) {
this.FIELD_0 = string;
this.FIELD_1 = arrstring;
this.FIELD_2 = callbackFilter;
this.FIELD_3 = arrtype;
this.FIELD_4 = bl;
this.FIELD_5 = bl2;
Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 = this;
this.FIELD_6 = l;
}
public int hashCode() {
String string = this.FIELD_0;
int n = 8095873 * 69403 + (string != null ? string.hashCode() : 0);
String[] arrstring = this.FIELD_1;
if (arrstring != null) {
String[] arrstring2 = arrstring;
for (int i = 0; i < arrstring2.length; ++i) {
String string2 = arrstring2[i];
n = n * 69403 + (string2 != null ? string2.hashCode() : 0);
}
}
CallbackFilter callbackFilter = this.FIELD_2;
int n2 = n * 69403 + (callbackFilter != null ? callbackFilter.hashCode() : 0);
Type[] arrtype = this.FIELD_3;
if (arrtype != null) {
Type[] arrtype2 = arrtype;
for (int i = 0; i < arrtype2.length; ++i) {
Type type = arrtype2[i];
n2 = n2 * 69403 + (type != null ? type.hashCode() : 0);
}
}
Long l = this.FIELD_6;
return ((n2 * 69403 + (this.FIELD_4 ^ true)) * 69403 + (this.FIELD_5 ^ true)) * 69403 + (l != null ? ((Object)l).hashCode() : 0);
}
/*
* Enabled force condition propagation
* Lifted jumps to return sites
*/
public boolean equals(Object object) {
if (!(object instanceof Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)) return false;
String string = this.FIELD_0;
String string2 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_0;
if (string2 == null) {
if (string != null) return false;
} else {
if (string == null) {
return false;
}
if (!string.equals(string2)) return false;
}
String[] arrstring = this.FIELD_1;
String[] arrstring2 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_1;
if (arrstring2 == null) {
if (arrstring != null) return false;
} else {
if (arrstring == null) {
return false;
}
if (arrstring2.length != arrstring.length) return false;
String[] arrstring3 = arrstring2;
String[] arrstring4 = arrstring;
for (int i = 0; i < arrstring3.length; ++i) {
String string3 = arrstring3[i];
String string4 = arrstring4[i];
if (string4 == null) {
if (string3 != null) return false;
continue;
}
if (string3 == null) {
return false;
}
if (!string3.equals(string4)) return false;
}
}
CallbackFilter callbackFilter = this.FIELD_2;
CallbackFilter callbackFilter2 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_2;
if (callbackFilter2 == null) {
if (callbackFilter != null) return false;
} else {
if (callbackFilter == null) {
return false;
}
if (!callbackFilter.equals((Object)callbackFilter2)) return false;
}
Type[] arrtype = this.FIELD_3;
Type[] arrtype2 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_3;
if (arrtype2 == null) {
if (arrtype != null) return false;
} else {
if (arrtype == null) {
return false;
}
if (arrtype2.length != arrtype.length) return false;
Type[] arrtype3 = arrtype2;
Type[] arrtype4 = arrtype;
for (int i = 0; i < arrtype3.length; ++i) {
Type type = arrtype3[i];
Type type2 = arrtype4[i];
if (type2 == null) {
if (type != null) return false;
continue;
}
if (type == null) {
return false;
}
if (!type.equals((Object)type2)) return false;
}
}
if (this.FIELD_4 != ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_4 || this.FIELD_5 != ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_5) return false;
Long l = this.FIELD_6;
Long l2 = ((Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72)object).FIELD_6;
if (l2 == null) {
if (l != null) return false;
return true;
}
if (l == null) {
return false;
} else {
if (!((Object)l).equals(l2)) return false;
return true;
}
}
public String toString() {
StringBuffer stringBuffer;
StringBuffer stringBuffer2;
StringBuffer stringBuffer3 = new StringBuffer();
String string = this.FIELD_0;
StringBuffer stringBuffer4 = (string != null ? stringBuffer3.append(string.toString()) : stringBuffer3.append("null")).append(", ");
String[] arrstring = this.FIELD_1;
if (arrstring != null) {
StringBuffer stringBuffer5 = stringBuffer4.append("{");
String[] arrstring2 = arrstring;
for (int i = 0; i < arrstring2.length; ++i) {
String string2 = arrstring2[i];
stringBuffer5 = (string2 != null ? stringBuffer5.append(string2.toString()) : stringBuffer5.append("null")).append(", ");
}
stringBuffer5.setLength(stringBuffer5.length() - 2);
stringBuffer2 = stringBuffer5.append("}");
} else {
stringBuffer2 = stringBuffer4.append("null");
}
StringBuffer stringBuffer6 = stringBuffer2.append(", ");
CallbackFilter callbackFilter = this.FIELD_2;
StringBuffer stringBuffer7 = (callbackFilter != null ? stringBuffer6.append(callbackFilter.toString()) : stringBuffer6.append("null")).append(", ");
Type[] arrtype = this.FIELD_3;
if (arrtype != null) {
StringBuffer stringBuffer8 = stringBuffer7.append("{");
Type[] arrtype2 = arrtype;
for (int i = 0; i < arrtype2.length; ++i) {
Type type = arrtype2[i];
stringBuffer8 = (type != null ? stringBuffer8.append(type.toString()) : stringBuffer8.append("null")).append(", ");
}
stringBuffer8.setLength(stringBuffer8.length() - 2);
stringBuffer = stringBuffer8.append("}");
} else {
stringBuffer = stringBuffer7.append("null");
}
StringBuffer stringBuffer9 = stringBuffer.append(", ").append(this.FIELD_4).append(", ").append(this.FIELD_5).append(", ");
Long l = this.FIELD_6;
return (l != null ? stringBuffer9.append(((Object)l).toString()) : stringBuffer9.append("null")).toString();
}
}
MethodWrapper.MethodWrapperKey 接口代理类:MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7.java
/*
* Decompiled with CFR 0.140.
*
* Could not load the following classes:
* net.sf.cglib.core.KeyFactory
* net.sf.cglib.core.MethodWrapper
* net.sf.cglib.core.MethodWrapper$MethodWrapperKey
*/
package net.sf.cglib.core;
import net.sf.cglib.core.KeyFactory;
import net.sf.cglib.core.MethodWrapper;
public class MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
extends KeyFactory
implements MethodWrapper.MethodWrapperKey {
private final String FIELD_0;
private final String[] FIELD_1;
private final String FIELD_2;
public MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7() {
}
public Object newInstance(String string, String[] arrstring, String string2) {
return new MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7(string, arrstring, string2);
}
public MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7(String string, String[] arrstring, String string2) {
this.FIELD_0 = string;
this.FIELD_1 = arrstring;
MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 methodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 = this;
this.FIELD_2 = string2;
}
public int hashCode() {
String string = this.FIELD_0;
int n = 938313161 * 362693231 + (string != null ? string.hashCode() : 0);
String[] arrstring = this.FIELD_1;
if (arrstring != null) {
String[] arrstring2 = arrstring;
for (int i = 0; i < arrstring2.length; ++i) {
String string2 = arrstring2[i];
n = n * 362693231 + (string2 != null ? string2.hashCode() : 0);
}
}
String string3 = this.FIELD_2;
return n * 362693231 + (string3 != null ? string3.hashCode() : 0);
}
/*
* Enabled force condition propagation
* Lifted jumps to return sites
*/
public boolean equals(Object object) {
if (!(object instanceof MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7)) return false;
String string = this.FIELD_0;
String string2 = ((MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7)object).FIELD_0;
if (string2 == null) {
if (string != null) return false;
} else {
if (string == null) {
return false;
}
if (!string.equals(string2)) return false;
}
String[] arrstring = this.FIELD_1;
String[] arrstring2 = ((MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7)object).FIELD_1;
if (arrstring2 == null) {
if (arrstring != null) return false;
} else {
if (arrstring == null) {
return false;
}
if (arrstring2.length != arrstring.length) return false;
String[] arrstring3 = arrstring2;
String[] arrstring4 = arrstring;
for (int i = 0; i < arrstring3.length; ++i) {
String string3 = arrstring3[i];
String string4 = arrstring4[i];
if (string4 == null) {
if (string3 != null) return false;
continue;
}
if (string3 == null) {
return false;
}
if (!string3.equals(string4)) return false;
}
}
String string5 = this.FIELD_2;
String string6 = ((MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7)object).FIELD_2;
if (string6 == null) {
if (string5 != null) return false;
return true;
}
if (string5 == null) {
return false;
} else {
if (!string5.equals(string6)) return false;
return true;
}
}
public String toString() {
StringBuffer stringBuffer;
StringBuffer stringBuffer2 = new StringBuffer();
String string = this.FIELD_0;
StringBuffer stringBuffer3 = (string != null ? stringBuffer2.append(string.toString()) : stringBuffer2.append("null")).append(", ");
String[] arrstring = this.FIELD_1;
if (arrstring != null) {
StringBuffer stringBuffer4 = stringBuffer3.append("{");
String[] arrstring2 = arrstring;
for (int i = 0; i < arrstring2.length; ++i) {
String string2 = arrstring2[i];
stringBuffer4 = (string2 != null ? stringBuffer4.append(string2.toString()) : stringBuffer4.append("null")).append(", ");
}
stringBuffer4.setLength(stringBuffer4.length() - 2);
stringBuffer = stringBuffer4.append("}");
} else {
stringBuffer = stringBuffer3.append("null");
}
StringBuffer stringBuffer5 = stringBuffer.append(", ");
String string3 = this.FIELD_2;
return (string3 != null ? stringBuffer5.append(string3.toString()) : stringBuffer5.append("null")).toString();
}
}
MethodProxy::create
通过Class对象、Class动态代理对象、方法名、动态代理方法名 创建方法代理,根据方法名对方法签名,创建 MethodProxy 对象:
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;
}
MethodProxy::invoke 和 invokeSuper 的区别:
- invoke 调用 fci.f1.invoke 也就是通过目标类 c1 生成的 FastClass 动态代理类
- invokeSuper 调用 fci.f2.invoke 也就是通过目标类 c2 生成的 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 e) {
throw e.getTargetException();
} catch (IllegalArgumentException e) {
if (fastClassInfo.i1 < 0)
throw new IllegalArgumentException("Protected method: " + sig1);
throw e;
}
}
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
MethodProxy::init
初始化 FastClassInfo:
- 通过 switch case 判断方法签名 signature.toString().hashCode() 值创建 FastClass 动态代理类(查看
ProxyTarget$$FastClassByCGLIB$$e11ac57f .java
和ProxyTarget$$EnhancerByCGLIB$$353bee02$$FastClassByCGLIB$$c041df7a.java
),提供接口:- public int getIndex(Signature sig) --根据方法签名获取索引(signature.toString().hashCode()的值)
- public int getIndex(String name, Class[] parameterTypes) --根据方法名和参数类型获取索引
- public int getIndex(Class[] parameterTypes) --根据参数类型
- public Object invoke(int index, Object obj, Object[] args) throws InvocationTargetException --根据索引和实例对象、参数调用方法
- public int getMaxIndex() --获取最大索引
- 为 FastClassInfo 设置索引
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)
{
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
private static class FastClassInfo
{
FastClass f1;
FastClass f2;
int i1;
int i2;
}
private static class CreateInfo
{
Class c1;
Class c2;
NamingPolicy namingPolicy;
GeneratorStrategy strategy;
boolean attemptLoad;
public CreateInfo(Class c1, Class c2)
{
this.c1 = c1;
this.c2 = c2;
//获取绑定到当前线程的Enhancer
AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
if (fromEnhancer != null) {
//设置命名规则
namingPolicy = fromEnhancer.getNamingPolicy();
//设置创建策略,默认为 DefaultGeneratorStrategy.INSTANCE
strategy = fromEnhancer.getStrategy();
//设置是否尝试从getDefaultClassLoader指定的ClassLoader中获取Class信息
attemptLoad = fromEnhancer.getAttemptLoad();
}
}
}
private static FastClass helper(CreateInfo ci, Class type) {
//FastClass.Generator 是 AbstractClassGenerator 的子类
FastClass.Generator g = new FastClass.Generator();
g.setType(type);
g.setClassLoader(ci.c2.getClassLoader());
g.setNamingPolicy(ci.namingPolicy);
g.setStrategy(ci.strategy);
g.setAttemptLoad(ci.attemptLoad);
return g.create();
}
由 MethodProxy$FastClass
生成继承自 FastClass 的 ProxyTarget
代理类:ProxyTarget$$FastClassByCGLIB$$e11ac57f.java
/*
* Decompiled with CFR 0.140.
*
* Could not load the following classes:
* net.sf.cglib.core.Signature
* net.sf.cglib.reflect.FastClass
*/
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.reflect.FastClass;
public class ProxyTarget$$FastClassByCGLIB$$e11ac57f
extends FastClass {
public ProxyTarget$$FastClassByCGLIB$$e11ac57f(Class class_) {
super(class_);
}
public int getIndex(Signature signature) {
String string = signature.toString();
switch (string.hashCode()) {
case -1725733088: {
if (!string.equals("getClass()Ljava/lang/Class;")) break;
return 7;
}
case -1026001249: {
if (!string.equals("wait(JI)V")) break;
return 2;
}
case 243996900: {
if (!string.equals("wait(J)V")) break;
return 3;
}
case 946854621: {
if (!string.equals("notifyAll()V")) break;
return 9;
}
case 1116248544: {
if (!string.equals("wait()V")) break;
return 1;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) break;
return 4;
}
case 1902039948: {
if (!string.equals("notify()V")) break;
return 8;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) break;
return 5;
}
case 1984935277: {
if (!string.equals("hashCode()I")) break;
return 6;
}
case 2121560294: {
if (!string.equals("doSomething()V")) break;
return 0;
}
}
return -1;
}
public int getIndex(String string, Class[] arrclass) {
String string2 = string;
Class[] arrclass2 = arrclass;
block0 : switch (string2.hashCode()) {
case -1776922004: {
if (!string2.equals("toString")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 5;
}
}
break;
}
case -1295482945: {
if (!string2.equals("equals")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("java.lang.Object")) break block0;
return 4;
}
default: {
break;
}
}
break;
}
case -1039689911: {
if (!string2.equals("notify")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 8;
}
}
break;
}
case 3641717: {
if (!string2.equals("wait")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 1;
}
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("long")) break block0;
return 3;
}
case 2: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("long")) break block0;
arrclass2 = arrclass2;
if (!arrclass2[1].getName().equals("int")) break block0;
return 2;
}
default: {
break;
}
}
break;
}
case 147696667: {
if (!string2.equals("hashCode")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 6;
}
}
break;
}
case 1794410543: {
if (!string2.equals("doSomething")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 0;
}
}
break;
}
case 1902066072: {
if (!string2.equals("notifyAll")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 9;
}
}
break;
}
case 1950568386: {
if (!string2.equals("getClass")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 7;
}
}
break;
}
default: {
break;
}
}
return -1;
}
public int getIndex(Class[] arrclass) {
switch (arrclass.length) {
case 0: {
return 0;
}
}
return -1;
}
public Object invoke(int n, Object object, Object[] arrobject) throws InvocationTargetException {
ProxyTarget proxyTarget = (ProxyTarget)object;
try {
switch (n) {
case 0: {
proxyTarget.doSomething();
return null;
}
case 1: {
proxyTarget.wait();
return null;
}
case 2: {
proxyTarget.wait(((Number)arrobject[0]).longValue(), ((Number)arrobject[1]).intValue());
return null;
}
case 3: {
proxyTarget.wait(((Number)arrobject[0]).longValue());
return null;
}
case 4: {
return new Boolean(proxyTarget.equals(arrobject[0]));
}
case 5: {
return proxyTarget.toString();
}
case 6: {
return new Integer(proxyTarget.hashCode());
}
case 7: {
return proxyTarget.getClass();
}
case 8: {
proxyTarget.notify();
return null;
}
case 9: {
proxyTarget.notifyAll();
return null;
}
}
}
catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int n, Object[] arrobject) throws InvocationTargetException {
try {
switch (n) {
case 0: {
return new ProxyTarget();
}
}
}
catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 9;
}
}
由 MethodProxy$FastClass.java
生成继承自 FastClass 的 ProxyTarget$$EnhancerByCGLIB$$d1fa18f0
代理类:ProxyTarget$$EnhancerByCGLIB$$d1fa18f0$$FastClassByCGLIB$$25a353a0.java
/*
* Decompiled with CFR 0.140.
*
* Could not load the following classes:
* net.sf.cglib.core.Signature
* net.sf.cglib.proxy.Callback
* net.sf.cglib.reflect.FastClass
*/
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.reflect.FastClass;
public class ProxyTarget$$EnhancerByCGLIB$$d1fa18f0$$FastClassByCGLIB$$25a353a0
extends FastClass {
public ProxyTarget$$EnhancerByCGLIB$$d1fa18f0$$FastClassByCGLIB$$25a353a0(Class class_) {
super(class_);
}
public int getIndex(Signature signature) {
String string = signature.toString();
switch (string.hashCode()) {
case -2055565910: {
if (!string.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) break;
return 9;
}
case -1725733088: {
if (!string.equals("getClass()Ljava/lang/Class;")) break;
return 24;
}
case -1457535688: {
if (!string.equals("CGLIB$STATICHOOK1()V")) break;
return 20;
}
case -1411812934: {
if (!string.equals("CGLIB$hashCode$4()I")) break;
return 16;
}
case -1026001249: {
if (!string.equals("wait(JI)V")) break;
return 22;
}
case -894172689: {
if (!string.equals("newInstance(Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) break;
return 3;
}
case -713887907: {
if (!string.equals("CGLIB$doSomething$0()V")) break;
return 19;
}
case -623122092: {
if (!string.equals("CGLIB$findMethodProxy(Lnet/sf/cglib/core/Signature;)Lnet/sf/cglib/proxy/MethodProxy;")) break;
return 18;
}
case -419626537: {
if (!string.equals("setCallbacks([Lnet/sf/cglib/proxy/Callback;)V")) break;
return 8;
}
case 243996900: {
if (!string.equals("wait(J)V")) break;
return 23;
}
case 374345669: {
if (!string.equals("CGLIB$equals$2(Ljava/lang/Object;)Z")) break;
return 15;
}
case 560567118: {
if (!string.equals("setCallback(ILnet/sf/cglib/proxy/Callback;)V")) break;
return 7;
}
case 811063227: {
if (!string.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) break;
return 4;
}
case 946854621: {
if (!string.equals("notifyAll()V")) break;
return 26;
}
case 973717575: {
if (!string.equals("getCallbacks()[Lnet/sf/cglib/proxy/Callback;")) break;
return 11;
}
case 1116248544: {
if (!string.equals("wait()V")) break;
return 21;
}
case 1221173700: {
if (!string.equals("newInstance([Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) break;
return 5;
}
case 1230699260: {
if (!string.equals("getCallback(I)Lnet/sf/cglib/proxy/Callback;")) break;
return 12;
}
case 1365077639: {
if (!string.equals("CGLIB$finalize$1()V")) break;
return 14;
}
case 1517819849: {
if (!string.equals("CGLIB$toString$3()Ljava/lang/String;")) break;
return 13;
}
case 1584330438: {
if (!string.equals("CGLIB$SET_STATIC_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) break;
return 10;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) break;
return 0;
}
case 1902039948: {
if (!string.equals("notify()V")) break;
return 25;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) break;
return 1;
}
case 1984935277: {
if (!string.equals("hashCode()I")) break;
return 2;
}
case 2011844968: {
if (!string.equals("CGLIB$clone$5()Ljava/lang/Object;")) break;
return 17;
}
case 2121560294: {
if (!string.equals("doSomething()V")) break;
return 6;
}
}
return -1;
}
public int getIndex(String string, Class[] arrclass) {
String string2 = string;
Class[] arrclass2 = arrclass;
block0 : switch (string2.hashCode()) {
case -2083498450: {
if (!string2.equals("CGLIB$finalize$1")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 14;
}
}
break;
}
case -1776922004: {
if (!string2.equals("toString")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 1;
}
}
break;
}
case -1295482945: {
if (!string2.equals("equals")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("java.lang.Object")) break block0;
return 0;
}
default: {
break;
}
}
break;
}
case -1053468136: {
if (!string2.equals("getCallbacks")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 11;
}
}
break;
}
case -1039689911: {
if (!string2.equals("notify")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 25;
}
}
break;
}
case -124978608: {
if (!string2.equals("CGLIB$equals$2")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("java.lang.Object")) break block0;
return 15;
}
default: {
break;
}
}
break;
}
case -60403779: {
if (!string2.equals("CGLIB$SET_STATIC_CALLBACKS")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) break block0;
return 10;
}
default: {
break;
}
}
break;
}
case -29025554: {
if (!string2.equals("CGLIB$hashCode$4")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 16;
}
}
break;
}
case 3641717: {
if (!string2.equals("wait")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 21;
}
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("long")) break block0;
return 23;
}
case 2: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("long")) break block0;
arrclass2 = arrclass2;
if (!arrclass2[1].getName().equals("int")) break block0;
return 22;
}
default: {
break;
}
}
break;
}
case 85179481: {
if (!string2.equals("CGLIB$SET_THREAD_CALLBACKS")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) break block0;
return 9;
}
default: {
break;
}
}
break;
}
case 147696667: {
if (!string2.equals("hashCode")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 2;
}
}
break;
}
case 161998109: {
if (!string2.equals("CGLIB$STATICHOOK1")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 20;
}
}
break;
}
case 180909336: {
if (!string2.equals("CGLIB$doSomething$0")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 19;
}
}
break;
}
case 495524492: {
if (!string2.equals("setCallbacks")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) break block0;
return 8;
}
default: {
break;
}
}
break;
}
case 1154623345: {
if (!string2.equals("CGLIB$findMethodProxy")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("net.sf.cglib.core.Signature")) break block0;
return 18;
}
default: {
break;
}
}
break;
}
case 1543336190: {
if (!string2.equals("CGLIB$toString$3")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 13;
}
}
break;
}
case 1794410543: {
if (!string2.equals("doSomething")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 6;
}
}
break;
}
case 1811874389: {
if (!string2.equals("newInstance")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
String string3 = arrclass2[0].getName();
switch (string3.hashCode()) {
case -845341380: {
if (!string3.equals("net.sf.cglib.proxy.Callback")) break block0;
return 3;
}
case 1730110032: {
if (!string3.equals("[Lnet.sf.cglib.proxy.Callback;")) break block0;
return 5;
}
default: {
break;
}
}
break block0;
}
case 3: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("[Ljava.lang.Class;")) break block0;
arrclass2 = arrclass2;
if (!arrclass2[1].getName().equals("[Ljava.lang.Object;")) break block0;
arrclass2 = arrclass2;
if (!arrclass2[2].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) break block0;
return 4;
}
default: {
break;
}
}
break;
}
case 1817099975: {
if (!string2.equals("setCallback")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 2: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("int")) break block0;
arrclass2 = arrclass2;
if (!arrclass2[1].getName().equals("net.sf.cglib.proxy.Callback")) break block0;
return 7;
}
default: {
break;
}
}
break;
}
case 1902066072: {
if (!string2.equals("notifyAll")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 26;
}
}
break;
}
case 1905679803: {
if (!string2.equals("getCallback")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 1: {
arrclass2 = arrclass2;
if (!arrclass2[0].getName().equals("int")) break block0;
return 12;
}
default: {
break;
}
}
break;
}
case 1950568386: {
if (!string2.equals("getClass")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 24;
}
}
break;
}
case 1951977611: {
if (!string2.equals("CGLIB$clone$5")) break;
arrclass2 = arrclass2;
switch (arrclass2.length) {
case 0: {
return 17;
}
}
break;
}
default: {
break;
}
}
return -1;
}
public int getIndex(Class[] arrclass) {
switch (arrclass.length) {
case 0: {
return 0;
}
}
return -1;
}
public Object invoke(int n, Object object, Object[] arrobject) throws InvocationTargetException {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0 proxyTarget$$EnhancerByCGLIB$$d1fa18f0 = (ProxyTarget$$EnhancerByCGLIB$$d1fa18f0)object;
try {
switch (n) {
case 0: {
return new Boolean(proxyTarget$$EnhancerByCGLIB$$d1fa18f0.equals(arrobject[0]));
}
case 1: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.toString();
}
case 2: {
return new Integer(proxyTarget$$EnhancerByCGLIB$$d1fa18f0.hashCode());
}
case 3: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.newInstance((Callback)arrobject[0]);
}
case 4: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.newInstance((Class[])arrobject[0], (Object[])arrobject[1], (Callback[])arrobject[2]);
}
case 5: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.newInstance((Callback[])arrobject[0]);
}
case 6: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.doSomething();
return null;
}
case 7: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.setCallback(((Number)arrobject[0]).intValue(), (Callback)arrobject[1]);
return null;
}
case 8: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.setCallbacks((Callback[])arrobject[0]);
return null;
}
case 9: {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_THREAD_CALLBACKS((Callback[])arrobject[0]);
return null;
}
case 10: {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$SET_STATIC_CALLBACKS((Callback[])arrobject[0]);
return null;
}
case 11: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.getCallbacks();
}
case 12: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.getCallback(((Number)arrobject[0]).intValue());
}
case 13: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$toString$3();
}
case 14: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$finalize$1();
return null;
}
case 15: {
return new Boolean(proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$equals$2(arrobject[0]));
}
case 16: {
return new Integer(proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$hashCode$4());
}
case 17: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$clone$5();
}
case 18: {
return ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$findMethodProxy((Signature)arrobject[0]);
}
case 19: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$doSomething$0();
return null;
}
case 20: {
ProxyTarget$$EnhancerByCGLIB$$d1fa18f0.CGLIB$STATICHOOK1();
return null;
}
case 21: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.wait();
return null;
}
case 22: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.wait(((Number)arrobject[0]).longValue(), ((Number)arrobject[1]).intValue());
return null;
}
case 23: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.wait(((Number)arrobject[0]).longValue());
return null;
}
case 24: {
return proxyTarget$$EnhancerByCGLIB$$d1fa18f0.getClass();
}
case 25: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.notify();
return null;
}
case 26: {
proxyTarget$$EnhancerByCGLIB$$d1fa18f0.notifyAll();
return null;
}
}
}
catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int n, Object[] arrobject) throws InvocationTargetException {
try {
switch (n) {
case 0: {
return new ProxyTarget$$EnhancerByCGLIB$$d1fa18f0();
}
}
}
catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 26;
}
}
ASM
官方网址:https://asm.ow2.io/