通过阅读本文,你首先将学习如下基础知识点:
- 什么是代理
- 什么是静态代理和动态代理
- 静态代理和动态代理的区别
- java中常见的动态代理实现以及动态代理的内在实质
在对上述概念有一定的了解之后,我们将在本地搭建一个简单的Spring项目,就可以正式开始Spring AOP的学习之旅。你将在这一部分学习到:
- Spring AOP使用示例
- 预览生成的Aop代理对象
- Aop代理对象的生成过程
- Aop代理对象的调用过程
Spring AOP的实现依赖动态代理。理解动态代理,就需要理解什么是代理
什么是代理
什么是代理?以租房为例,租房过程涉及三方,分别是客户(Client)、中介(Proxy)、房东(RealSubject),从房东(RealSubject)的视角看,他仅提供房屋出租;中介(Proxy)为房东提供了代理服务包含:联系租客、带客看房、拟定合同、签订合同、善后维护,这就是代理的好处:能为被代理对象提供额外的服务(增强)。
什么是静态代理和动态代理
静态代理
代理模式关系如图所示:
代理模式调用关系如下:
静态代理
编译前,代理Proxy类已经存在,并和目标对象Target绑定。示例代码如下:
java
public interface Subject {
void provideService();
}
public class RealSubject implements Subject {
@Override
public void provideService() {
System.out.printf("提供服务");
}
}
public class Proxy implements Subject {
private Subject realSubject;
public LandLordProxy(Subejct realSubject) {
this.realSubject = realSubject;
}
@Override
public void provideService() {
System.out.printf("提供前置增强处理\n");
this.realSubject.provideService();
System.out.printf("提供后置增强处理\n");
}
}
// 调用
public static void main(String[] args) {
Subject realSubject = new RealSubject()
Proxy proxy = new Proxy(realSubject);
proxy.provideService();
}
动态代理
编译前,代理Proxy类是不存在的,需要借助工具编译时动态生成代理对象,并与目标对象绑定。 动态代理常见实现方式是:1. jdk动态代理;2. cglib动态代理。以下分别从使用示例、运行结果、代理类源码这三个方面进行介绍,并分析这两种动态代理的区别。
jdk动态代理
使用jdk动态代理的示例代码,如下:
java
public interface Subject {
void provideService();
}
public class RealSubject implements Subject {
@Override
public void provideService() {
System.out.println("提供服务");
}
}
public class DynamicProxyInvocationHandler implements InvocationHandler {
private Subject realSubject;
public DynamicProxyInvocationHandler(Subject realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.printf("提供前置增强处理\n");
method.invoke(realSubject, args);
System.out.printf("提供后置增强处理\n");
return null;
}
}
// 调用
public static void main(String[] args) {
// 该设置会将动态生成的代理对象保存在文件中
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Subject realSubject = new RealSubject();
Subject dynamicProxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), new Class[]{Subject.class}, new DynamicProxyInvocationHandler(realSubject));
dynamicProxy.provideService();
}
上述代码执行如下:
生成的动态代理类代码如下:
java
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void provideService() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("proxy.Subject").getMethod("provideService");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
可以看到,代理类$Proxy0实现了Subject接口,内部持有InvocationHandler对象,代理类所有方法的内部实现,实际上调的是InvacationHandler的invoke方法,最终会执行我们的增强逻辑以及被代理类的原有逻辑。
cglib动态代理
使用cglib动态代理的示例代码如下:
java
public interface TargetInterface {
void doSomething();
}
public class TargetClass implements TargetInterface {
@Override
public void doSomething() {
System.out.println("提供服务");
}
}
public class CglibDynamicProxy {
public static Object getProxy(TargetInterface targetInterface) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetInterface.getClass());
enhancer.setCallback((MethodInterceptor) (o, method, args, methodProxy) -> {
System.out.println("提供前置增强处理");
Object result = methodProxy.invokeSuper(o, args);
System.out.println("提供后置增强处理");
return result;
});
return enhancer.create();
}
}
// 调用
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"/target/classes");
TargetInterface target = new TargetClass();
TargetInterface proxy = (TargetInterface)CglibDynamicProxy.getProxy(target);
proxy.doSomething();
}
执行结果如下:
生成的动态代理对象代码如下:
java
public class TargetClass$$EnhancerByCGLIB$$ece06fc1 extends TargetClass 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$doSomething$0$Method;
private static final MethodProxy CGLIB$doSomething$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$equals$1$Method;
private static final MethodProxy CGLIB$equals$1$Proxy;
private static final Method CGLIB$toString$2$Method;
private static final MethodProxy CGLIB$toString$2$Proxy;
private static final Method CGLIB$hashCode$3$Method;
private static final MethodProxy CGLIB$hashCode$3$Proxy;
private static final Method CGLIB$clone$4$Method;
private static final MethodProxy CGLIB$clone$4$Proxy;
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("proxy.cglib.TargetClass$$EnhancerByCGLIB$$ece06fc1");
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$1$Method = var10000[0];
CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
CGLIB$toString$2$Method = var10000[1];
CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
CGLIB$hashCode$3$Method = var10000[2];
CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
CGLIB$clone$4$Method = var10000[3];
CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
CGLIB$doSomething$0$Method = ReflectUtils.findMethods(new String[]{"doSomething", "()V"}, (var1 = Class.forName("proxy.cglib.TargetClass")).getDeclaredMethods())[0];
CGLIB$doSomething$0$Proxy = MethodProxy.create(var1, var0, "()V", "doSomething", "CGLIB$doSomething$0");
}
final void CGLIB$doSomething$0() {
super.doSomething();
}
public final void doSomething() {
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$doSomething$0$Method, CGLIB$emptyArgs, CGLIB$doSomething$0$Proxy);
} else {
super.doSomething();
}
}
final boolean CGLIB$equals$1(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$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
}
final String CGLIB$toString$2() {
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$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
}
final int CGLIB$hashCode$3() {
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$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}
final Object CGLIB$clone$4() 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$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch (var10000.hashCode()) {
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$4$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$1$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$2$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$3$Proxy;
}
break;
case 2121560294:
if (var10000.equals("doSomething()V")) {
return CGLIB$doSomething$0$Proxy;
}
}
return null;
}
public TargetClass$$EnhancerByCGLIB$$ece06fc1() {
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) {
TargetClass$$EnhancerByCGLIB$$ece06fc1 var1 = (TargetClass$$EnhancerByCGLIB$$ece06fc1)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);
TargetClass$$EnhancerByCGLIB$$ece06fc1 var10000 = new TargetClass$$EnhancerByCGLIB$$ece06fc1();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
TargetClass$$EnhancerByCGLIB$$ece06fc1 var10000 = new TargetClass$$EnhancerByCGLIB$$ece06fc1();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
TargetClass$$EnhancerByCGLIB$$ece06fc1 var10000 = new TargetClass$$EnhancerByCGLIB$$ece06fc1;
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();
}
}
可以看到生成的代理类的doSomething()方法,在调用doSomething()时,实际上就会走到MethodInterceptor的intercept()方法,最终走我们的增强逻辑
jdk动态代理和cglib动态代理的区别
- 生成代理类的方式不同。通过上述代理类的代码可以发现:
- jdk动态代理通过实现目标接口生成代理类
- cglib通过继承目标类生成代理类
- 底层机制不同
- jdk动态代理,通过反射机制实现生成代理类。
- cglib动态代理,利用ASM架构,修改目标类的字节码、并生成子类字节码的方式生成代理类。
- 底层机制不同,导致使用方式不同
- 如果想要使用JDK动态代理,那么被代理类必须实现接口,否则不能使用。
- 如果想要使用CGlib动态代理,那么被代理类不能使用final修饰类和方法。
Spring AOP概览
我们已经了解什么动态代理,并且从上帝视角我们得知:Spring AOP的底层实现借助于动态代理技术。那么现在我们自然会想问:1. Spring AOP怎么使用?2. Spring AOP生成怎样的代理类,生成代理类的过程?3. Spring AOP怎么执行我们定义的增强逻辑?
Spring AOP的使用
为了让我们在代码层面对Spring Aop有个直观的认识,下面将列举2个简单的使用示例,分别说明切面为接口、切面类的情况。需要引入的相关依赖,已放在文章的末尾。
切面为接口
以下是切面为接口的Spring AOP使用示例:
java
public interface MyTestInterface {
void test();
}
@Component
public class MytTestInterfaceImpl implements MyTestInterface {
@Override
public void test() {
System.out.println("这是MytTestInterfaceImpl在执行");
}
}
@Component
@Aspect
public class MyTestClazzAop {
@Pointcut("execution(* proxy.aop.MyTestInterface.test(..))")
public void pt() {}
@Before("pt()")
public void before(JoinPoint jp) {
System.out.println("这是前置增强");
}
@After("pt()")
public void after() {
System.out.println("这是后置增强");
}
}
@Configuration
@EnableAspectJAutoProxy
public class TestConfig {
}
public class App {
public static void main(String[] args) {
// proxy.aop换成你项目中实际的package
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("proxy.aop");
MyTestInterface bean = applicationContext.getBean(MyTestInterface.class);
bean.test();
}
}
以上代码,首先定义一个接口MyTestInterface,再定义了一个实现类MytTestInterfaceImpl,MytTestInterfaceImpl实现了test接口并打印了一行日志。然后再定义了MyTestAop,MyTestAop先指定了切面,并且定义了前置和后置增强,增强逻辑就是打印了两行日志。最后,我们通过IoC容器获取MyTestInterface类型的bean,调用test()打印的日志如下:
java
这是前置增强
这是MytTestInterfaceImpl在执行
这是后置增强
切面为类
以下是切面为类的Spring AOP使用示例:
java
@Component
public class MyTestClazz {
public void test() {
System.out.println("这是MyTestClazz在执行");
}
}
@Component
@Aspect
public class MyTestClazzAop {
@Pointcut("execution(* proxy.aop.MyTestClazz.test(..))")
public void pt(){}
@Before("pt()")
public void before(JoinPoint jp) {
System.out.println("这是前置增强");
}
@After("pt()")
public void after() {
System.out.println("这是后置增强");
}
}
@Configuration
@EnableAspectJAutoProxy
public class TestConfig {
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("proxy.aop");
MyTestClazz bean = applicationContext.getBean(MyTestClazz.class);
bean.test();
}
}
执行结果如下
java
这是前置增强
这是MyTestClazz在执行
这是后置增强
Spring AOP代理类的生成
预览Spring AOP代理类
上述介绍了SpringAOP两种使用方式,一种切面为接口,一种切面为类。这两种使用方式对Spring来说,生成的代理类有何不同呢?要了解它们之间有差异,先对比下面三种情况applicationContext.getBean获取的类。
- 不使用Spring AOP,获取的是类MyTestInterfaceImpl对象,以此为基准。
- 切面为接口,获取的是类$Proxy{数字},由jdk动态代理生成(属性是JdkDynamicAopProxy可知)
- 切面为类,获取的是类MyTestClazz <math xmlns="http://www.w3.org/1998/Math/MathML"> E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB </math>EnhancerBySpringCGLIB74260093,由cglib动态代理生成(看类名可知)。
创建Spring AOP代理类的生成过程
注册AnnotationAwareAspectJAutoProxyCreator
在上面的使用实例中,开启Spring AOP需要引入注解@EnableAspectJAutoProxy,看名字猜作用,这个注解的作用大概是:开启Aspectj自动代理。这个注解的作用是将AnnotaitonAwareAspectJAutoProxyCreator注入bean容器。 注册AnnotaitonAwareAspectJAutoProxyCreator的过程如图所示
@EnableAspectJAutoProxy注解定义如下:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
@Import(AspectJAutoProxyRegistrar.class)引入了AspectJAutoProxyRegistrar类,再次看类名猜作用:AspectJ自动代理注册器。AspectJAutoProxyRegistrar类定义如下:
java
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,从类名可推断AspectJAutoProxyRegistrar具备了将BeanDefinition注册到容器的能力。重点看接口的具体实现,AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)做了注册BeanDefinition的动作。registerAspectJAnnotationAutoProxyCreatorIfNecessary的定义如下
java
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
这里调用引入了registerOrEscalateApcAsRequired方法,将AnnotationAwareAspectJAutoProxyCreator.class作为参数传入。大胆猜测应该是将AnnotationAwareAspectJAutoProxyCreator注册到容器中。registerOrEscalateApcAsRequired方法的具体实现如下
java
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
逻辑清晰:将AnnotationAwareAspectJAutoProxyCreator.class作为注册到容器中,beanName叫做org.springframework.aop.config.internalAutoProxyCreator。看到这,我们发现@EnableAspectJAutoProxy最终将AnnotationAwareAspectJAutoProxyCreator注册到容器。AnnotationAwareAspectJAutoProxyCreator的继承结构如下
从上到下看,AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,所以具备了对bean后置处理的能力,那有理由猜测:是不是在生成MyTestInterface或MyTestClazz的bean时,通过bean后置处理器将生了对应的代理类呢?接下重点关注BeanPostProcessor接口的实现。另外AnnotationAwareAspectJAutoProxyCreator继承了ProxyProcessorSupport,那ProxyProcessroSupport在这当中起到了什么作用?
后置处理器生成代理类
首先定位到AnnotationAwareAspectJAutoProxyCreator实现BeanPostProcessor接口的逻辑,BeanPostProccessor的接口定义如下
java
public interface BeanPostProcessor {
/**
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other {@code BeanPostProcessor} callbacks.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
根据方法名,BeanPostProcessor提供了两个方法,分别是在bean初始化之前和之后执行。而AnnotationAwareAspectJAutoProxyCreator对这两个接口方法实现如下
java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
这里虽然列出了postProcessBeforeInstantiation和postProcessAfterInitialization的实现,但实际上在debug的过程中,真正生成代理类对象的地方时postProcessAfterInitialization。postProcessBeforeInstantiation的作用暂时不提,有时间再去了解。
获取AopProxy对象
以下是获取AopProxy对象的过程:
这里重点看postProcessAfterInitialization的实现,代码最终会走到wrapIfNecessary()方法,其内部实现如下
java
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
由于我们针对切面定义Aop,那么当切面涉及的bean执行21行代码时,specificInterceptors不为null,所以在22行处的判断成立,将执行23-27行的逻辑。主要看24行的createProxy方法,方法定义如下
java
/**
* Create an AOP proxy for the given bean.
* @param beanClass the class of the bean
* @param beanName the name of the bean
* @param specificInterceptors the set of interceptors that is
* specific to this bean (may be empty, but not null)
* @param targetSource the TargetSource for the proxy,
* already pre-configured to access the bean
* @return the AOP proxy for the bean
* @see #buildAdvisors
*/
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
主体逻辑是,初始化一个ProxyFactory对象proxyFactory,在specificInterceptors转成advisors数组后,将advisors设置到proxyFactory属性中,调用proxyFactory.getProxy()得到代理对象,getProxy方法定义如下
java
/**
* Create a new proxy according to the settings in this factory.
* <p>Can be called repeatedly. Effect will vary if we've added
* or removed interfaces. Can add and remove interceptors.
* <p>Uses the given class loader (if necessary for proxy creation).
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return the proxy object
*/
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
逻辑很简单,看createAorProxy()定义如下
java
/**
* Subclasses should call this to get a new AOP proxy. They should <b>not</b>
* create an AOP proxy with {@code this} as an argument.
*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
逻辑依然很简单,再看createAopProxy方法的实现
java
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
上述代码很清晰,如果targetClass如果是接口,则返回JdkDynamicAopPorxy对象,否则返回ObjenesisCglibAopProxy对象。
调用该AopProxy的getProxy方法
- JdkDynamicAopProxy的getProxy方法
java
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
可以看到,通过调用Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)生成代理对象,与我们编写的jdk动态代理示例类似。需要注意的是Proxy.newProxyInstance()的第3个参数传入的是this,说明JdkDynamicAopProxy是InvocationHandler的实现类,事实也正是如此
至于InvocationHandler的invoke方法将会在后续介绍。
- CglibAopProxy的getProxy()方法
Enhancer是不是很熟悉,我们在cglib动态代理示例中就用到了Enhancer。简单来说就是初始化Enhancer对象,设置Enhancer的Callback,最后调用Enhancer对象的create方法创建代理类。
java
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
java
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
Spring AOP代理类的方法执行
Spring AOP代理类的方法执行,是指增强逻辑的执行,进一步来说就是执行@before@after注解标记的方法。
执行委托MethodInvocation实现类
回到动态代理章节,我们介绍了,如果是jdk动态代理生成的代理类,方法调用时实际执行的是InvocationHandler类的invoke();如果是cglib动态代理生成的代理类,方法调用实际执行的是MethodInterceptor类的interceptor()。
ReflectiveMethodInvocation
JdkDynamicAopProxy的invoke()
java
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
41行代理获取得到interception chain,54-57行将拦截器链作为参数初始化ReflectiveMethodInvocation,最终执行ReflectiveMethodInvocation的proceed()。
CglibMethodInvocation
CglibAopProxy的getProxy()如下
java
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
51行的getCallBacks()就是获取MethodInterceptor类(MethodInterceptor是CallBack接口的实现类)。getCallBacks()定义如下
java
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
第8行的初始化了DynamicAdvisedInterceptor,它的继承结构如下
DynamicAdvisedInterceptor既然是MethodInterceptor的实现类,看下它的intercept()的实现
java
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
29行代码初始化CglibMethodInvocation类,最终将代理逻辑委托给CglibMethodInvocation类的proceed()。看CglibMethodInvocation的继承关系如图:
执行MethodInterceptor链的invoke方法
代理类的方法执行最终委托给ReflectiveMethodInvation类的proceed()执行,代码如下
java
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
代码的整体逻辑是,依次执行this.interceptorsAndDynamicMethodMatchers,通过debug我们知道这个列表实际数据如下图
重点关注AspectJAfterAdvice类对象、MethodBeforeAdviceInterceptor类对象,有两个我们很熟悉的词:before和After,问题1:这两个对象是由MyTestClazzAop内@before和@after修饰方法封装成的么? 截图中AspectJAfterAdvice是在MethodBeforeAdviceInterceptor,如果依次遍历执行,应该先打印"这是后置增强",而实际我们知道先打印的是"这是前置增强",这是如何实现的?
java
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
java
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
我们看这两个类的invoke()的mi参数是谁?再结合ReflectiveMethodInvation#proceed()中的代码((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); mi就是ReflectiveMethodInvation对象。之所以先执行AspectJAfterAdvice#invoke却能后打印"这是后置增强",是因为在AspectJAfterAdvice#invoke内部先执行了mi.proceed(),这时又回到ReflectiveMethodInvation#proceed(),然后执行MethodBeforeAdviceInterceptor#invoke,先执行this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis())打印"这是前置增强",递归回到AspectJAfterAdvice#invoke执行invokeAdviceMethod(getJoinPointMatch(), null, null)打印"这是后置增强"。 最后再思考一下"这是MytTestInterfaceImpl在执行"是在哪里执行呢?在ReflectiveMethodInvation#proceed()的return invokeJoinpoint();