静态代理(简单描述)
先定义一个接口,里面定义目标方法
//目标类要实现的接口
public interface ITarget {
//目标方法
void doFunc(String words);
}
定义一个代理类
public class StaticProxy implements ITarget{
private ITarget target = null;
//关联要增强的目标类
public StaticProxy(ITarget target){
this.target = target;
}
//在这里增强目标类的目标方法
@Override
public void doFunc() {
...
...
...
//增强目标方法
target.doFunc();
...
...
...
}
}
以后,任意的一个ITarget接口的子类,都可以注入给StaticProxy类,然后实现一套增强,不再赘述。
动态代理
代理类在程序运行时创建的代理方式被成为 动态代理。也就是说,这种情况下,代理类并不是像静态代理一样,是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。
动态代理是spring AOP的实现原理,spring有两种动态代理模式,cglib和jdk,我们先来将java jdk的动态代理。
jdk的动态代理
首先,我们需要知道,jdk的动态代理只能代理实现了接口的类 没有实现接口的类不能实现JDK动态代理。其次,我们还要了解一个重要的中介接口InvocationHandler,这是jdk的动态代理的基石,它的定义如下:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
我们先来写一个jdk的动态代理实例,再来讨论其中的原理吧
jdk动态代理实例
我们先来定义一个目标类,或者说委托类,或者又叫被代理类,它实现了我们上面定义的那个接口ITarget:
public class Entrust implements ITarget {
public void doFunc(String words){
System.out.println(words);
}
}
再定义一个中介类,实现InvocationHandler接口,这个中介类,持有被代理的对象,在invoke中利用反射,调用目标类的方法:
public class JdkDynamicProxyHandler implements InvocationHandler {
//invocationHandler持有的被代理对象
T target;
public JdkDynamicProxyHandler(T target) {
this.target = target;
}
/**
* proxy:代表动态代理对象
* method:代表正在执行的方法
* args:代表调用目标方法时传入的实参
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do before");
Object result = method.invoke(target, args);
System.out.println("do after");
return result;
}
}
好了,我们现在来写一个代理demo:
public static void main(String[] a){
//创建一个实例对象,这个对象是被代理的对象
ITarget attorney = new Attorney();
//创建一个与代理对象相关联的InvocationHandler
InvocationHandler jdkDynamicProxyHandler = new JdkDynamicProxyHandler(attorney);
//创建一个代理对象proxy来代理attorney,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
ITarget proxy = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class>[]{ITarget.class}, jdkDynamicProxyHandler);
//代理执行上交班费的方法
proxy.doFunc("hello word");
//将生成的代理类写到桌面
writeProxyClassToHardDisk("/home/ls/Desktop/$Proxy22.class");
}
public static void writeProxyClassToHardDisk(String path) {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy22", Attorney.class.getInterfaces());
FileOutputStream out = null;
try {
out = new FileOutputStream(path);
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后输出:
原理剖析
我们来看看Proxy.newProxyInstance方法
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//验证一些参数
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
* 从缓存里面获取某个类的代理类,如果该类的代理类不存在,就根据该类的类型创建一个
* 如果要深挖逻辑,可以看看ProxyClassFactory的apply方法。
* 其实生成代理类字节码文件的工作是通过 ProxyGenerate类中的generateProxyClass方法来完成的。
*/
Class> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*
* /** parameter types of a proxy class constructor */
* private static final Class>[] constructorParams = { InvocationHandler.class };
*
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//看上面的注释,constructorParams={ InvocationHandler.class },
//这是在生成代理类的构造函数,获得一个参数为InvocationHandler的构造方法
final Constructor> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//这行代码的意思是将h,也就是实现InvocationHandler的实现类,
//我们传入的是jdkDynamicProxyHandler,注入到cons中。
//然后newInstance生成一个已经组装过参数的代理类。
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
我们最应该关注的是 Class> cl = getProxyClass0(loader, intfs);这句,这里产生了代理类,后面代码中的构造器也是通过这里产生的类来获得,可以看出,这个类的产生就是整个动态代理的关键,由于是动态生成的类文件,我这里不具体进入分析如何产生的这个类文件,只需要知道这个类文件时缓存在java虚拟机中的。
我们对这个代理类进行反编译:(本次使用http://www.javadecompilers.co...)
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import aopLearn.ITarget;
import java.lang.reflect.Proxy;
//
// Decompiled by Procyon v0.5.30
//
public final class $Proxy22 extends Proxy implements ITarget
{
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
/**
*注意这里是生成代理类的构造方法,方法参数为InvocationHandler类型,看到这,是不是就有点明白了
*为何代理对象调用方法都是执行InvocationHandler中的invoke方法,而InvocationHandler又持有一个
*被代理对象的实例
*
*super(paramInvocationHandler),是调用父类Proxy的构造方法。
*父类持有:protected InvocationHandler h;
*Proxy构造方法:
* protected Proxy(InvocationHandler h) {
* Objects.requireNonNull(h);
* this.h = h;
* }
*
*/
public $Proxy22(final InvocationHandler invocationHandler) {
super(invocationHandler);
}
//这个静态块本来是在最后的,我把它拿到前面来,方便描述
static {
try {
//doFunc通过反射得到的名字m3
$Proxy22.m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
$Proxy22.m3 = Class.forName("aopLearn.ITarget").getMethod("doFunc", Class.forName("java.lang.String"));
$Proxy22.m2 = Class.forName("java.lang.Object").getMethod("toString", (Class>[])new Class[0]);
$Proxy22.m0 = Class.forName("java.lang.Object").getMethod("hashCode", (Class>[])new Class[0]);
}
catch (NoSuchMethodException ex) {
throw new NoSuchMethodError(ex.getMessage());
}
catch (ClassNotFoundException ex2) {
throw new NoClassDefFoundError(ex2.getMessage());
}
}
public final boolean equals(final Object o) {
try {
return (boolean)super.h.invoke(this, $Proxy22.m1, new Object[] { o });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
/**
*
*这里调用代理对象的doFunc方法,直接就调用了InvocationHandler中的invoke方法,并把m3传了进去。
*this.h.invoke(this, m3, null);这里简单,明了。
*代理对象持有一个InvocationHandler对象,InvocationHandler对象持有一个被代理的对象,
*再联系到InvacationHandler中的invoke方法。其实就是代理对象调用InvocationHandler,
* InvocationHandler对象反射调用委托类对象。
*/
public final void doFunc(final String s) {
try {
super.h.invoke(this, $Proxy22.m3, new Object[] { s });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final String toString() {
try {
return (String)super.h.invoke(this, $Proxy22.m2, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final int hashCode() {
try {
return (int)super.h.invoke(this, $Proxy22.m0, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
}
看完了这些,我们来想一下,为什么jdk的动态代理,一定要委托类实现一个接口?这是因为我们可以看到,我们生成的代理类Proxy22 extends Proxy implements ITarget,已经继承了Proxy类,而java中不能多继承,为了让$Proxy22和委托类建立联系,只能实现一个接口。这里的建立联系,是指通过接口,得到委托类方法的反射等,并且,委托类实现自接口的方法,才能被增强。
故而,本质上来说,jdk的动态代理,是为接口产生代理。
在spring AOP中,我们使用jdk动态代理时当然也要定义InvocationHandler的实现类对象,spring中的是org.springframework.aop.framework.JdkDynamicAopProxy类。
cglib的动态代理
cglib的动态代理针对类来实现代理,对指定目标产生一个子类 通过方法拦截技术拦截所有父类方法的调用。我们要使用cglib代理必须引入cglib的jar包。
cglib动态代理实例
同样,定义一个跟上面例子一样的委托类。
public class Entrust {
public void doFunc(String words){
System.out.println(words);
}
}
实现MethodInterceptor接口生成方法拦截器
public class EntrustInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object o = proxy.invokeSuper(obj,args);
System.out.println("after");
return o;
}
}
实例如下:
public static void main(String[] a){
//cglib自带的debug工具,可以将代理类输出到指定路径
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/ls/Desktop/cglib");
Enhancer enhancer = new Enhancer();
//继承被代理类
enhancer.setSuperclass(Entrust.class);
enhancer.setCallback(new EntrustInterceptor());
//生成的代理类对象
Entrust entrust = (Entrust) enhancer.create();
//在调用我们代理类中的方法时会被我们实现的方法拦截器拦截
entrust.doFunc("hello word");
}
输出结果如下:
原理剖析
CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。
我们看到,代理类对象是由Enhancer类创建的。Enhancer是CGLIB的字节码增强器,可以很方便的对类进行拓展,创建代理对象的几个步骤:
- 生成代理类的二进制字节码文件;
- 加载二进制字节码,生成Class对象( 例如使用Class.forName()方法 );
- 通过反射机制获得实例构造,并创建代理类对象
我们来看看将代理类Class文件反编译之后的Java代码,一个动态代理,产生了三个类:
主要的代理类是
Entrust$$EnhancerByCGLIB$$832e20ab
//
// Decompiled by Procyon v0.5.30
//
package com.lufax.util.aopCache.cglibProxy;
import net.sf.cglib.core.Signature;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
/**
* 生成的代理类Entrust$$EnhancerByCGLIB$$832e20ab继承被代理类Entrust。
* 在这里我们需要注意一点:如果委托类被final修饰,那么它不可被继承,即不可被代理;
* 同样,如果委托类中存在final修饰的方法,那么该方法也不可被代理;
*
*/
public class Entrust$$EnhancerByCGLIB$$832e20ab extends Entrust 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$doFunc$0$Method;
private static final MethodProxy CGLIB$doFunc$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];
final Class> forName = Class.forName("com.lufax.util.aopCache.cglibProxy.Entrust$$EnhancerByCGLIB$$832e20ab");
final Class> forName2;
final Method[] methods = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (forName2 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$finalize$1$Method = methods[0];
CGLIB$finalize$1$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()V", "finalize", "CGLIB$finalize$1");
CGLIB$equals$2$Method = methods[1];
CGLIB$equals$2$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
CGLIB$toString$3$Method = methods[2];
CGLIB$toString$3$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
CGLIB$hashCode$4$Method = methods[3];
CGLIB$hashCode$4$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()I", "hashCode", "CGLIB$hashCode$4");
CGLIB$clone$5$Method = methods[4];
CGLIB$clone$5$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
final Class> forName3;
CGLIB$doFunc$0$Method = ReflectUtils.findMethods(new String[] { "doFunc", "(Ljava/lang/String;)V" }, (forName3 = Class.forName("com.lufax.util.aopCache.cglibProxy.Entrust")).getDeclaredMethods())[0];
CGLIB$doFunc$0$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "(Ljava/lang/String;)V", "doFunc", "CGLIB$doFunc$0");
}
//代理类会为委托方法生成两个方法,一个是重写的doFunc方法,
//另一个是CGLIB$doFunc$0方法,我们可以看到它是直接调用父类的doFunc方法;
final void CGLIB$doFunc$0(final String s) {
super.doFunc(s);
}
//当执行代理对象的doFunc方法时,会首先判断一下是否存在实现了MethodInterceptor接口的CGLIB$CALLBACK_0;
//如果存在,则将调用MethodInterceptor中的intercept方法,如图2.1。
public final void doFunc(final String s) {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
//这里开始调用我们定义的EntrustInterceptor中的intercept方法。
//参数1、代理对象;2、委托类方法;3、方法参数;4、代理方法的MethodProxy对象(注意这个对象)。
cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Method, new Object[] { s }, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Proxy);
return;
}
super.doFunc(s);
}
final void CGLIB$finalize$1() throws Throwable {
super.finalize();
}
protected final void finalize() throws Throwable {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Proxy);
return;
}
super.finalize();
}
final boolean CGLIB$equals$2(final Object o) {
return super.equals(o);
}
public final boolean equals(final Object o) {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
final Object intercept = cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Method, new Object[] { o }, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Proxy);
return intercept != null && (boolean)intercept;
}
return super.equals(o);
}
final String CGLIB$toString$3() {
return super.toString();
}
public final String toString() {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
return (String)cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Proxy);
}
return super.toString();
}
final int CGLIB$hashCode$4() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
final Object intercept = cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Proxy);
return (intercept == null) ? 0 : ((Number)intercept).intValue();
}
return super.hashCode();
}
final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
return cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Proxy);
}
return super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(final Signature signature) {
final String string = signature.toString();
switch (string.hashCode()) {
case -1574182249: {
if (string.equals("finalize()V")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Proxy;
}
break;
}
case -508378822: {
if (string.equals("clone()Ljava/lang/Object;")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Proxy;
}
break;
}
case 346793840: {
if (string.equals("doFunc(Ljava/lang/String;)V")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Proxy;
}
break;
}
case 1826985398: {
if (string.equals("equals(Ljava/lang/Object;)Z")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Proxy;
}
break;
}
case 1913648695: {
if (string.equals("toString()Ljava/lang/String;")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Proxy;
}
break;
}
case 1984935277: {
if (string.equals("hashCode()I")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Proxy;
}
break;
}
}
return null;
}
public Entrust$$EnhancerByCGLIB$$832e20ab() {
CGLIB$BIND_CALLBACKS(this);
}
public static void CGLIB$SET_THREAD_CALLBACKS(final Callback[] array) {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$THREAD_CALLBACKS.set(array);
}
public static void CGLIB$SET_STATIC_CALLBACKS(final Callback[] cglib$STATIC_CALLBACKS) {
CGLIB$STATIC_CALLBACKS = cglib$STATIC_CALLBACKS;
}
private static final void CGLIB$BIND_CALLBACKS(final Object o) {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = (Entrust$$EnhancerByCGLIB$$832e20ab)o;
if (!entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$BOUND) {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$BOUND = true;
Object o2;
if ((o2 = Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$THREAD_CALLBACKS.get()) != null || (o2 = Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$STATIC_CALLBACKS) != null) {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])o2)[0];
}
}
}
public Object newInstance(final Callback[] array) {
CGLIB$SET_THREAD_CALLBACKS(array);
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}
public Object newInstance(final Callback callback) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[] { callback });
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}
public Object newInstance(final Class[] array, final Object[] array2, final Callback[] array3) {
CGLIB$SET_THREAD_CALLBACKS(array3);
switch (array.length) {
case 0: {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}
default: {
throw new IllegalArgumentException("Constructor not found");
}
}
}
public Callback getCallback(final int n) {
CGLIB$BIND_CALLBACKS(this);
Object cglib$CALLBACK_0 = null;
switch (n) {
case 0: {
cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0;
break;
}
default: {
cglib$CALLBACK_0 = null;
break;
}
}
return (Callback)cglib$CALLBACK_0;
}
public void setCallback(final int n, final Callback callback) {
switch (n) {
case 0: {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
break;
}
}
}
public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[] { this.CGLIB$CALLBACK_0 };
}
public void setCallbacks(final Callback[] array) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)array[0];
}
static {
CGLIB$STATICHOOK1();
}
}
逻辑进入到我们在EntrustInterceptor 中定义的intercept方法
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object o = proxy.invokeSuper(obj,args);
System.out.println("after");
return o;
}
我们看看MethodProxy的invokeSuper方法:
/**
* Invoke the original (super) method on the specified object.
* @param obj the enhanced object, must be the object passed as the first
* argument to the MethodInterceptor
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an InvocationTargetException
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
//f2是由CGlib生成的,在输出的class中有这个类。
//它就是Entrust$$EnhancerByCGLIB$$832e20ab$$FastClassByCGLIB$$817a77c.class
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
我们把
Entrust$$EnhancerByCGLIB$$832e20ab$$FastClassByCGLIB$$817a77c.class
也反编译出来,然后贴出invoke方法,注意case14调用了
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0((String)array[0]);:
public Object invoke(final int n, final Object o, final Object[] array) throws InvocationTargetException {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = (Entrust$$EnhancerByCGLIB$$832e20ab)o;
try {
switch (n) {
case 0: {
entrust$$EnhancerByCGLIB$$832e20ab.setCallbacks((Callback[])array[0]);
return null;
}
case 1: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$SET_STATIC_CALLBACKS((Callback[])array[0]);
return null;
}
case 2: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$SET_THREAD_CALLBACKS((Callback[])array[0]);
return null;
}
case 3: {
return entrust$$EnhancerByCGLIB$$832e20ab.getCallback(((Number)array[0]).intValue());
}
case 4: {
return entrust$$EnhancerByCGLIB$$832e20ab.getCallbacks();
}
case 5: {
entrust$$EnhancerByCGLIB$$832e20ab.doFunc((String)array[0]);
return null;
}
case 6: {
entrust$$EnhancerByCGLIB$$832e20ab.setCallback(((Number)array[0]).intValue(), (Callback)array[1]);
return null;
}
case 7: {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$findMethodProxy((Signature)array[0]);
}
case 8: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$STATICHOOK1();
return null;
}
case 9: {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1();
return null;
}
case 10: {
return entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3();
}
case 11: {
return new Integer(entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4());
}
case 12: {
return entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5();
}
case 13: {
return new Boolean(entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2(array[0]));
}
case 14: {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0((String)array[0]);
return null;
}
case 15: {
return new Boolean(entrust$$EnhancerByCGLIB$$832e20ab.equals(array[0]));
}
case 16: {
return entrust$$EnhancerByCGLIB$$832e20ab.toString();
}
case 17: {
return new Integer(entrust$$EnhancerByCGLIB$$832e20ab.hashCode());
}
case 18: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Callback)array[0]);
}
case 19: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Class[])array[0], (Object[])array[1], (Callback[])array[2]);
}
case 20: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Callback[])array[0]);
}
case 21: {
Entrust.main((String[])array[0]);
return null;
}
case 22: {
entrust$$EnhancerByCGLIB$$832e20ab.wait(((Number)array[0]).longValue(), ((Number)array[1]).intValue());
return null;
}
case 23: {
entrust$$EnhancerByCGLIB$$832e20ab.wait(((Number)array[0]).longValue());
return null;
}
case 24: {
entrust$$EnhancerByCGLIB$$832e20ab.wait();
return null;
}
case 25: {
return entrust$$EnhancerByCGLIB$$832e20ab.getClass();
}
case 26: {
entrust$$EnhancerByCGLIB$$832e20ab.notify();
return null;
}
case 27: {
entrust$$EnhancerByCGLIB$$832e20ab.notifyAll();
return null;
}
}
}
catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
事实证明,最后确实是进入了case14,调用了代理类的代理doFunc方法,最后再回到EntrustInterceptor.invoke中。完成逻辑
Spring AOP
未完待续