- 动态代理原理
为了实现在某各类方法调用的前后做一些事情(输出日志等),同时又不用在改变类的代码,还可以统一操作一批类。
Java动态代理原理就是动态的生成字节码技术,Java Class其实就是二进制文件,我们可以利用classloader动态加载这个二进制文件,然后生成Java对象,生成原理就是生成Java的各个部分如Java魔数,版本号,各个字段,Java虚方法,构造方法和其他方法。 - Java动态原理实现方法
为一个类生成动态代理的方式有两种:
基于接口实现:
jdk动态代理:生成的代理类继承Proxy类,Proxy类里有一个InvocationHandeler h对象,调用代理对象的方法就会调用h.invoke(m,args)方法,具体自己要加的代码在h.invoke方法里写
生成过程:
我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成代理类的字节码。ProxyGenerator这个类存放在sun.misc包下
private byte[] generateClassFile() {
//第一步, 将所有的方法组装成ProxyMethod对象
//首先为代理类生成toString, hashCode, equals等代理方法
addProxyMethod(hashCodeMethod, Object.class);
addProxyMethod(equalsMethod, Object.class);
addProxyMethod(toStringMethod, Object.class);
//遍历每一个接口的每一个方法, 并且为其生成ProxyMethod对象
for (int i = 0; i < interfaces.length; i++) {
Method[] methods = interfaces[i].getMethods();
for (int j = 0; j < methods.length; j++) {
addProxyMethod(methods[j], interfaces[i]);
}
}
//对于具有相同签名的代理方法, 检验方法的返回值是否兼容
for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
checkReturnTypes(sigmethods);
}
//第二步, 组装要生成的class文件的所有的字段信息和方法信息
try {
//添加构造器方法
methods.add(generateConstructor());
//遍历缓存中的代理方法
for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
for (ProxyMethod pm : sigmethods) {
//添加代理类的静态字段, 例如:private static Method m1;
fields.add(new FieldInfo(pm.methodFieldName,
"Ljava/lang/reflect/Method;", ACC_PRIVATE | ACC_STATIC));
//添加代理类的代理方法
methods.add(pm.generateMethod());
}
}
//添加代理类的静态字段初始化方法
methods.add(generateStaticInitializer());
} catch (IOException e) {
throw new InternalError("unexpected I/O Exception");
}
//验证方法和字段集合不能大于65535
if (methods.size() > 65535) {
throw new IllegalArgumentException("method limit exceeded");
}
if (fields.size() > 65535) {
throw new IllegalArgumentException("field limit exceeded");
}
//第三步, 写入最终的class文件
//验证常量池中存在代理类的全限定名
cp.getClass(dotToSlash(className));
//验证常量池中存在代理类父类的全限定名, 父类名为:"java/lang/reflect/Proxy"
cp.getClass(superclassName);
//验证常量池存在代理类接口的全限定名
for (int i = 0; i < interfaces.length; i++) {
cp.getClass(dotToSlash(interfaces[i].getName()));
}
//接下来要开始写入文件了,设置常量池只读
cp.setReadOnly();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
try {
//1.写入魔数
dout.writeInt(0xCAFEBABE);
//2.写入次版本号
dout.writeShort(CLASSFILE_MINOR_VERSION);
//3.写入主版本号
dout.writeShort(CLASSFILE_MAJOR_VERSION);
//4.写入常量池
cp.write(dout);
//5.写入访问修饰符
dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER);
//6.写入类索引
dout.writeShort(cp.getClass(dotToSlash(className)));
//7.写入父类索引, 生成的代理类都继承自Proxy
dout.writeShort(cp.getClass(superclassName));
//8.写入接口计数值
dout.writeShort(interfaces.length);
//9.写入接口集合
for (int i = 0; i < interfaces.length; i++) {
dout.writeShort(cp.getClass(dotToSlash(interfaces[i].getName())));
}
//10.写入字段计数值
dout.writeShort(fields.size());
//11.写入字段集合
for (FieldInfo f : fields) {
f.write(dout);
}
//12.写入方法计数值
dout.writeShort(methods.size());
//13.写入方法集合
for (MethodInfo m : methods) {
m.write(dout);
}
//14.写入属性计数值, 代理类class文件没有属性所以为0
dout.writeShort(0);
} catch (IOException e) {
throw new InternalError("unexpected I/O Exception");
}
//转换成二进制数组输出
return bout.toByteArray();
}
生成结果
import com.foo.proxy.Rechargable;
import com.foo.proxy.Vehicle;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
生成的动态代理类的组织模式是继承Proxy类,然后实现需要实现代理的类上的所有接口,而在实现的过程中,则是通过将所有的方法都交给了InvocationHandler来处理
*/
public final class ElectricCarProxy extends Proxy
implements Rechargable, Vehicle
{
private static Method m1;
private static Method m3;
private static Method m4;
private static Method m0;
private static Method m2;
public ElectricCarProxy(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
throws
{
try
{ // 方法功能实现交给InvocationHandler处理
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void recharge()
throws
{
try
{
// 方法功能实现交给InvocationHandler处理
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void drive()
throws
{
try
{
// 方法功能实现交给InvocationHandler处理
this.h.invoke(this, m4, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
throws
{
try
{
// 方法功能实现交给InvocationHandler处理
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
throws
{
try
{
// 方法功能实现交给InvocationHandler处理
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
static
{
try
{ //为每一个需要方法对象,当调用相应的方法时,分别将方法对象作为参数传递给InvocationHandler处理
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("com.foo.proxy.Rechargable").getMethod("recharge", new Class[0]);
m4 = Class.forName("com.foo.proxy.Vehicle").getMethod("drive", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}
————————————————
版权声明:本文为CSDN博主「亦山」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luanlouis/article/details/24589193
基于继承实现
cglib方式:cglib基于asm方式实现,asm操作的时汇编语言,使用者必须了解Java class类的结构。
cglib方式不用Java类实现接口,而是生成的代理对象继承自Java类,调用动态代理对象时就是调用super.method();
cglib实现方式:
public class CglabProxyCatTest {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\cglib");
//创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数
Enhancer enhancer = new Enhancer();
//设置目标类的字节码文件
enhancer.setSuperclass(Cat.class);
Cat target = new Cat();
//设置回调函数
enhancer.setCallback(new MyMethodInterceptor(target));
//这里的creat方法就是正式创建代理类
Cat proxyCat = (Cat) enhancer.create();
target.setCat(proxyCat);
//调用代理类的eat方法
proxyCat.water("huamao");
}
}
public class MyMethodInterceptor implements MethodInterceptor {
//被代理对象
private Object target;
public MyMethodInterceptor(Object target) {
this.target = target;
}
/**
*
* @param o cglig生成的代理对象
* @param method 被代理对象的方法
* @param objects 参数
* @param methodProxy 封装了代理对象和被代理对象class信息
* 和方法签名的对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib before:" + method.getName());
//methodProxy.invokeSuper(o,objects);
methodProxy.invoke(target,objects);
//method.invoke(target,objects);
System.out.println("cglib after" + method.getName());
return o;
}
}
在intercept里有两种调用被代理对象方法的方式,分别为
methodProxy.invokeSuper(o,objects);
methodProxy.invoke(target,objects);
这两种方式差异很大,第一种方式可以在被代理对象内部方法调用也会被增强,而第二种不会,但是spring使用第二种方式,所以在spring框架内使用aop方法内部嵌套增强时,内部调用时不会被增强的;
大致原理如下:
invoke方法传入的是被代理对象Cat,然后在Cat内部的water()方法里调用eat()方法是不会走intercept()方法增强的,invokeSuper传入的是代理对象 Cat
E
n
h
a
n
c
e
r
B
y
C
G
L
I
B
EnhancerByCGLIB
EnhancerByCGLIB379ad336;我们看下代理对象的eat()方法:
public final void eat(String var1) {
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$eat$0$Method, new Object[]{var1}, CGLIB$eat$0$Proxy);
} else {
super.eat(var1);
}
}
还是会调用到MyMethodInterceptor的intercepter方法的;
cglib会生成3个代理对象类,包括两个FastClass和一个代理对象;两个FastClass一个为被代理对象的FastClass,另一个为代理对象的,他们的作用主要是为了快速找到对象里的方法,比反射的效率高点;
被代理对象的代码为:
public class Cat {
private Cat cat;
public void setCat(Object cat) {
this.cat = (Cat) cat;
}
public void eat(String name){
System.out.println("eat," + name);
}
//这种方法嵌套,spring是使用 methodProxy.invoke(target,objects);
//是无法增强的,而 methodProxy.invokeSuper(o,objects);可以
public void water(String name) {
System.out.println("water" + name);
eat(name);
}
}
生成的三个类里面的代码为:
代理对象类:
public class Cat$$EnhancerByCGLIB$$379ad336 extends Cat implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$eat$0$Method;
private static final MethodProxy CGLIB$eat$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$setCat$1$Method;
private static final MethodProxy CGLIB$setCat$1$Proxy;
private static final Method CGLIB$water$2$Method;
private static final MethodProxy CGLIB$water$2$Proxy;
private static final Method CGLIB$equals$3$Method;
private static final MethodProxy CGLIB$equals$3$Proxy;
private static final Method CGLIB$toString$4$Method;
private static final MethodProxy CGLIB$toString$4$Proxy;
private static final Method CGLIB$hashCode$5$Method;
private static final MethodProxy CGLIB$hashCode$5$Proxy;
private static final Method CGLIB$clone$6$Method;
private static final MethodProxy CGLIB$clone$6$Proxy;
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("com.xiaolong.dto.Cat$$EnhancerByCGLIB$$379ad336");
Class var1;
Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$equals$3$Method = var10000[0];
CGLIB$equals$3$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$3");
CGLIB$toString$4$Method = var10000[1];
CGLIB$toString$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$4");
CGLIB$hashCode$5$Method = var10000[2];
CGLIB$hashCode$5$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$5");
CGLIB$clone$6$Method = var10000[3];
CGLIB$clone$6$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$6");
var10000 = ReflectUtils.findMethods(new String[]{"eat", "(Ljava/lang/String;)V", "setCat", "(Ljava/lang/Object;)V", "water", "(Ljava/lang/String;)V"}, (var1 = Class.forName("com.xiaolong.dto.Cat")).getDeclaredMethods());
CGLIB$eat$0$Method = var10000[0];
CGLIB$eat$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)V", "eat", "CGLIB$eat$0");
CGLIB$setCat$1$Method = var10000[1];
CGLIB$setCat$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)V", "setCat", "CGLIB$setCat$1");
CGLIB$water$2$Method = var10000[2];
CGLIB$water$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)V", "water", "CGLIB$water$2");
}
final void CGLIB$eat$0(String var1) {
super.eat(var1);
}
public final void eat(String var1) {
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$eat$0$Method, new Object[]{var1}, CGLIB$eat$0$Proxy);
} else {
super.eat(var1);
}
}
final void CGLIB$setCat$1(Object var1) {
super.setCat(var1);
}
public final void setCat(Object var1) {
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$setCat$1$Method, new Object[]{var1}, CGLIB$setCat$1$Proxy);
} else {
super.setCat(var1);
}
}
final void CGLIB$water$2(String var1) {
super.water(var1);
}
public final void water(String var1) {
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$water$2$Method, new Object[]{var1}, CGLIB$water$2$Proxy);
} else {
super.water(var1);
}
}
final boolean CGLIB$equals$3(Object var1) {
return super.equals(var1);
}
public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var2 = var10000.intercept(this, CGLIB$equals$3$Method, new Object[]{var1}, CGLIB$equals$3$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
}
final String CGLIB$toString$4() {
return super.toString();
}
public final String toString() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$4$Method, CGLIB$emptyArgs, CGLIB$toString$4$Proxy) : super.toString();
}
final int CGLIB$hashCode$5() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$5$Method, CGLIB$emptyArgs, CGLIB$hashCode$5$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}
final Object CGLIB$clone$6() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return var10000 != null ? var10000.intercept(this, CGLIB$clone$6$Method, CGLIB$emptyArgs, CGLIB$clone$6$Proxy) : super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch(var10000.hashCode()) {
case -1020676995:
if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
return CGLIB$setCat$1$Proxy;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$6$Proxy;
}
break;
case -84291256:
if (var10000.equals("water(Ljava/lang/String;)V")) {
return CGLIB$water$2$Proxy;
}
break;
case 685027751:
if (var10000.equals("eat(Ljava/lang/String;)V")) {
return CGLIB$eat$0$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$3$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$4$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$5$Proxy;
}
}
return null;
}
public Cat$$EnhancerByCGLIB$$379ad336() {
CGLIB$BIND_CALLBACKS(this);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
CGLIB$THREAD_CALLBACKS.set(var0);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
CGLIB$STATIC_CALLBACKS = var0;
}
private static final void CGLIB$BIND_CALLBACKS(Object var0) {
Cat$$EnhancerByCGLIB$$379ad336 var1 = (Cat$$EnhancerByCGLIB$$379ad336)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
}
var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
}
}
public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336;
switch(var1.length) {
case 0:
var10000.<init>();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
default:
throw new IllegalArgumentException("Constructor not found");
}
}
public Callback getCallback(int var1) {
CGLIB$BIND_CALLBACKS(this);
MethodInterceptor var10000;
switch(var1) {
case 0:
var10000 = this.CGLIB$CALLBACK_0;
break;
default:
var10000 = null;
}
return var10000;
}
public void setCallback(int var1, Callback var2) {
switch(var1) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
default:
}
}
public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[]{this.CGLIB$CALLBACK_0};
}
public void setCallbacks(Callback[] var1) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
}
static {
CGLIB$STATICHOOK1();
}
}
代理对象的FastClass:
public class Cat$$EnhancerByCGLIB$$379ad336$$FastClassByCGLIB$$40e34fe3 extends FastClass {
public Cat$$EnhancerByCGLIB$$379ad336$$FastClassByCGLIB$$40e34fe3(Class var1) {
super(var1);
}
public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -2071771415:
if (var10000.equals("CGLIB$clone$6()Ljava/lang/Object;")) {
return 24;
}
break;
case -2053042819:
if (var10000.equals("CGLIB$water$2(Ljava/lang/String;)V")) {
return 19;
}
break;
case -1870561232:
if (var10000.equals("CGLIB$findMethodProxy(Lorg/springframework/cglib/core/Signature;)Lorg/springframework/cglib/proxy/MethodProxy;")) {
return 16;
}
break;
case -1745842178:
if (var10000.equals("setCallbacks([Lorg/springframework/cglib/proxy/Callback;)V")) {
return 7;
}
break;
case -1663710620:
if (var10000.equals("CGLIB$equals$3(Ljava/lang/Object;)Z")) {
return 20;
}
break;
case -1641413109:
if (var10000.equals("newInstance([Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 4;
}
break;
case -1457535688:
if (var10000.equals("CGLIB$STATICHOOK1()V")) {
return 22;
}
break;
case -1411783143:
if (var10000.equals("CGLIB$hashCode$5()I")) {
return 23;
}
break;
case -1034266769:
if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
return 15;
}
break;
case -1025895669:
if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
return 14;
}
break;
case -1020676995:
if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
return 11;
}
break;
case -988317324:
if (var10000.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 6;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return 3;
}
break;
case -433745506:
if (var10000.equals("CGLIB$eat$0(Ljava/lang/String;)V")) {
return 17;
}
break;
case -84291256:
if (var10000.equals("water(Ljava/lang/String;)V")) {
return 12;
}
break;
case 610042816:
if (var10000.equals("newInstance(Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 5;
}
break;
case 685027751:
if (var10000.equals("eat(Ljava/lang/String;)V")) {
return 10;
}
break;
case 1132856532:
if (var10000.equals("getCallbacks()[Lorg/springframework/cglib/proxy/Callback;")) {
return 9;
}
break;
case 1246779367:
if (var10000.equals("setCallback(ILorg/springframework/cglib/proxy/Callback;)V")) {
return 13;
}
break;
case 1364367423:
if (var10000.equals("getCallback(I)Lorg/springframework/cglib/proxy/Callback;")) {
return 8;
}
break;
case 1703013677:
if (var10000.equals("CGLIB$setCat$1(Ljava/lang/Object;)V")) {
return 18;
}
break;
case 1729170762:
if (var10000.equals("CGLIB$toString$4()Ljava/lang/String;")) {
return 21;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return 0;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return 1;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return 2;
}
}
return -1;
}
public int getIndex(String var1, Class[] var2) {
switch(var1.hashCode()) {
case -2083343934:
if (var1.equals("CGLIB$water$2")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 19;
}
}
}
break;
case -1776922004:
if (var1.equals("toString")) {
switch(var2.length) {
case 0:
return 1;
}
}
break;
case -1295482945:
if (var1.equals("equals")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 0;
}
}
}
break;
case -1053468136:
if (var1.equals("getCallbacks")) {
switch(var2.length) {
case 0:
return 9;
}
}
break;
case -905816044:
if (var1.equals("setCat")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 11;
}
}
}
break;
case -124978607:
if (var1.equals("CGLIB$equals$3")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 20;
}
}
}
break;
case -60403779:
if (var1.equals("CGLIB$SET_STATIC_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 15;
}
}
}
break;
case -29025553:
if (var1.equals("CGLIB$hashCode$5")) {
switch(var2.length) {
case 0:
return 23;
}
}
break;
case 100184:
if (var1.equals("eat")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 10;
}
}
}
break;
case 85179481:
if (var1.equals("CGLIB$SET_THREAD_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 14;
}
}
}
break;
case 94756189:
if (var1.equals("clone")) {
switch(var2.length) {
case 0:
return 3;
}
}
break;
case 112903447:
if (var1.equals("water")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 12;
}
}
}
break;
case 147696667:
if (var1.equals("hashCode")) {
switch(var2.length) {
case 0:
return 2;
}
}
break;
case 161998109:
if (var1.equals("CGLIB$STATICHOOK1")) {
switch(var2.length) {
case 0:
return 22;
}
}
break;
case 495524492:
if (var1.equals("setCallbacks")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 7;
}
}
}
break;
case 682758500:
if (var1.equals("CGLIB$setCat$1")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 18;
}
}
}
break;
case 1111931649:
if (var1.equals("CGLIB$eat$0")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 17;
}
}
}
break;
case 1154623345:
if (var1.equals("CGLIB$findMethodProxy")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("org.springframework.cglib.core.Signature")) {
return 16;
}
}
}
break;
case 1543336191:
if (var1.equals("CGLIB$toString$4")) {
switch(var2.length) {
case 0:
return 21;
}
}
break;
case 1811874389:
if (var1.equals("newInstance")) {
switch(var2.length) {
case 1:
String var10001 = var2[0].getName();
switch(var10001.hashCode()) {
case -1997738671:
if (var10001.equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 4;
}
break;
case 1364160985:
if (var10001.equals("org.springframework.cglib.proxy.Callback")) {
return 5;
}
}
case 2:
default:
break;
case 3:
if (var2[0].getName().equals("[Ljava.lang.Class;") && var2[1].getName().equals("[Ljava.lang.Object;") && var2[2].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
return 6;
}
}
}
break;
case 1817099975:
if (var1.equals("setCallback")) {
switch(var2.length) {
case 2:
if (var2[0].getName().equals("int") && var2[1].getName().equals("org.springframework.cglib.proxy.Callback")) {
return 13;
}
}
}
break;
case 1905679803:
if (var1.equals("getCallback")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("int")) {
return 8;
}
}
}
break;
case 1951977612:
if (var1.equals("CGLIB$clone$6")) {
switch(var2.length) {
case 0:
return 24;
}
}
}
return -1;
}
public int getIndex(Class[] var1) {
switch(var1.length) {
case 0:
return 0;
default:
return -1;
}
}
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
379ad336 var10000 = (379ad336)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
return new Boolean(var10000.equals(var3[0]));
case 1:
return var10000.toString();
case 2:
return new Integer(var10000.hashCode());
case 3:
return var10000.clone();
case 4:
return var10000.newInstance((Callback[])var3[0]);
case 5:
return var10000.newInstance((Callback)var3[0]);
case 6:
return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
case 7:
var10000.setCallbacks((Callback[])var3[0]);
return null;
case 8:
return var10000.getCallback(((Number)var3[0]).intValue());
case 9:
return var10000.getCallbacks();
case 10:
var10000.eat((String)var3[0]);
return null;
case 11:
var10000.setCat(var3[0]);
return null;
case 12:
var10000.water((String)var3[0]);
return null;
case 13:
var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
return null;
case 14:
379ad336.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
return null;
case 15:
379ad336.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
return null;
case 16:
return 379ad336.CGLIB$findMethodProxy((Signature)var3[0]);
case 17:
var10000.CGLIB$eat$0((String)var3[0]);
return null;
case 18:
var10000.CGLIB$setCat$1(var3[0]);
return null;
case 19:
var10000.CGLIB$water$2((String)var3[0]);
return null;
case 20:
return new Boolean(var10000.CGLIB$equals$3(var3[0]));
case 21:
return var10000.CGLIB$toString$4();
case 22:
379ad336.CGLIB$STATICHOOK1();
return null;
case 23:
return new Integer(var10000.CGLIB$hashCode$5());
case 24:
return var10000.CGLIB$clone$6();
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
379ad336 var10000 = new 379ad336;
379ad336 var10001 = var10000;
int var10002 = var1;
try {
switch(var10002) {
case 0:
var10001.<init>();
return var10000;
}
} catch (Throwable var3) {
throw new InvocationTargetException(var3);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 24;
}
}
被代理对象的FastClass:
public class Cat$$FastClassByCGLIB$$160d4ae1 extends FastClass {
public Cat$$FastClassByCGLIB$$160d4ae1(Class var1) {
super(var1);
}
public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -1020676995:
if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
return 1;
}
break;
case -84291256:
if (var10000.equals("water(Ljava/lang/String;)V")) {
return 2;
}
break;
case 685027751:
if (var10000.equals("eat(Ljava/lang/String;)V")) {
return 0;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return 3;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return 4;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return 5;
}
}
return -1;
}
public int getIndex(String var1, Class[] var2) {
switch(var1.hashCode()) {
case -1776922004:
if (var1.equals("toString")) {
switch(var2.length) {
case 0:
return 4;
}
}
break;
case -1295482945:
if (var1.equals("equals")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 3;
}
}
}
break;
case -905816044:
if (var1.equals("setCat")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 1;
}
}
}
break;
case 100184:
if (var1.equals("eat")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 0;
}
}
}
break;
case 112903447:
if (var1.equals("water")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.String")) {
return 2;
}
}
}
break;
case 147696667:
if (var1.equals("hashCode")) {
switch(var2.length) {
case 0:
return 5;
}
}
}
return -1;
}
public int getIndex(Class[] var1) {
switch(var1.length) {
case 0:
return 0;
default:
return -1;
}
}
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
Cat var10000 = (Cat)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
var10000.eat((String)var3[0]);
return null;
case 1:
var10000.setCat(var3[0]);
return null;
case 2:
var10000.water((String)var3[0]);
return null;
case 3:
return new Boolean(var10000.equals(var3[0]));
case 4:
return var10000.toString();
case 5:
return new Integer(var10000.hashCode());
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
Cat var10000 = new Cat;
Cat var10001 = var10000;
int var10002 = var1;
try {
switch(var10002) {
case 0:
var10001.<init>();
return var10000;
}
} catch (Throwable var3) {
throw new InvocationTargetException(var3);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 5;
}
}
3.两种方式对比
jdk动态代理要求代理对象必须实现接口,有一定的局限性,而cglib则无此要求,但是cglib依赖于第三方jar包,并且cglib提供的invokeSuper方法可以实现内部嵌套增强,而jdk无此方法。