Spring AOP 源码探究
1. JDK动态代理
下面测试需要用到的一些基础类
1public interface IUserService {
2 void hello();
3}
4
5
6public class UserService implements IUserService {
7 @Override
8 public void hello() {
9 System.out.println("hello");
10 }
11}
JDK代理的方法
JDK代理对象需要有一个接口,在newProxyInstance中的new Class[]{},需要加上执行代理类的接口
1public void jdkProxy(){
2 IUserService proxy = (IUserService) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IUserService.class}, new InvocationHandler() {
3 @Override
4 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
5 return null;
6 }
7 });
8 proxy.hello();
9}
2. CGLIB动态代理
CGLIB代理的方法
1public void cglibProxy(){
2 UserService userService = new UserService();
3 Enhancer enhancer = new Enhancer();
4 enhancer.setSuperclass(UserService.class);
5 enhancer.setCallback(new MethodInterceptor() {
6 @Override
7 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
8
9 if(method.getName().equals("hello")){
10 System.out.println("before hello");
11 }
12
13 userService.hello();
14
15 return null;
16 }
17 });
18 IUserService proxy = (IUserService) enhancer.create();
19 proxy.hello();
20}
3. 通过ProxyFactory设置动态代理
ProxyFactory代理的方法
1public void springAop(){
2 UserService userService = new UserService();
3 ProxyFactory proxyFactory = new ProxyFactory(userService);
4 proxyFactory.setTarget(userService);
5 proxyFactory.addAdvice(new MethodBeforeAdvice() {
6 @Override
7 public void before(Method method, Object[] args, Object target) throws Throwable {
8 System.out.println("before hello");
9 }
10 });
11
12 // ☆ ->
13 IUserService proxy = (IUserService) proxyFactory.getProxy();
14 proxy.hello();
15}
在addAdvice方法中可以是一下几种类型,当然我们也可以实现这些接口根据自己的需求自定义 对应的方法
-
MethodBeforeAdvice1public interface MethodBeforeAdvice extends BeforeAdvice { 2 void before(Method method, Object[] args, @Nullable Object target) throws Throwable; 3} -
AfterReturningAdvice1public interface AfterReturningAdvice extends AfterAdvice { 2 void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable; 3} -
ThrowsAdvice: 注意这个接口中没有可以实现的方法,而且这个接口还是继承了AfterAdvice1public interface ThrowsAdvice extends AfterAdvice { 2}虽然这个Advice的接口中没有可以实现的方法,但是从这个接口的注释中我们可以知道,实现了这个接口之后,会通过反射的方式调用一下方法:
public void afterThrowing(Exception ex)public void afterThrowing(RemoteException)public void afterThrowing(Method method, Object[] args, Object target, Exception ex)public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)
从上面的方法可以看出,当我们在写
afterThrowing方法的时候,要么之后一个参数,要么是4个,其中的Exception表示,只有是这个Exception才会来调用这个方法。相当于是一个过滤的作用。 -
MethodInterceptor: 这个是org.aopalliance.intercept;这个包下面的,不是cglib下面的。1@FunctionalInterface 2public interface MethodInterceptor extends Interceptor { 3 @Nullable 4 Object invoke(@Nonnull MethodInvocation invocation) throws Throwable; 5}这个接口实现了之后就更加的自由了,我们可以自己通过使用
invocation.proceed()的调用来完成各种顺序的操作。比如实现Around。这里有一点需要注意,如果我们addAdvice()了多个Advice,那么当我们在调用
invocation.proceed()的时候,会优先调用后续的Advice的内容,然后执行被代理的方法,最后执行invocation.proceed()这个方法之后的代码。我们添加进入的Advice,最终都会被封装成一个MethodInterceptor,每次在低调用invocation.proceed()的时候都会去判断当前是不是最后一个,如果是最后一个,就直接调用被代理的方法,如果不是则继续获取下一个MethodInterceptor去执行。部分源码如下:1// org.springframework.aop.framework.ReflectiveMethodInvocation#proceed 2 3// 当调用我拿了最后一个interceptor就会执行被代理的方法 4if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { 5 return invokeJoinpoint(); 6} 7 8// currentInterceptorIndex初始值为-1 9// 取出第一个MethodInterceptor 10Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);MethodInterceptor非常重要,在后面我们可以知道,所有的我们添加的Advisor到最后都会被封装成MethodInterceptor,即使你使用的事addAdvice的方法,添加了Advice,也会在被封装为Advisor,最后成为MethodInterceptor。1@Override 2public void addAdvice(int pos, Advice advice) throws AopConfigException { 3 Assert.notNull(advice, "Advice must not be null"); 4 if (advice instanceof IntroductionInfo) { 5 // We don't need an IntroductionAdvisor for this kind of introduction: 6 // It's fully self-describing. 7 addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice)); 8 } 9 else if (advice instanceof DynamicIntroductionAdvice) { 10 // We need an IntroductionAdvisor for this kind of introduction. 11 throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor"); 12 } 13 else { 14 addAdvisor(pos, new DefaultPointcutAdvisor(advice)); 15 } 16}上面第14行的DefaultPointcutAdvisor,是一个匹配所有方法的Advisor,所以通过addAdvice()这个方法添加的advice,也会被封装成为一个default的advisor
3.1. 指定方法执行指定代理
- Advice只是一段代理逻辑
- Advicer则可以通过Pointcut来决定这段代理逻辑在什么时候会触发,比如说在什么方法调用的时候会触发。所以Advisor可以看成Advice+Pointcut
- 可以通过methodName来控制
- 也可以通过被代理的类的类型targetClass来控制
1public void springAopSpecific(){
2 UserService userService = new UserService();
3 ProxyFactory proxyFactory = new ProxyFactory(userService);
4 proxyFactory.setTarget(userService);
5 proxyFactory.addAdvisor(new PointcutAdvisor() {
6 @Override
7 public Pointcut getPointcut() {
8 return new StaticMethodMatcherPointcut() {
9 @Override
10 public boolean matches(Method method, Class<?> targetClass) {
11 // 只有方法名为hello的才会被代理
12 return method.getName().equals("hello");
13 }
14 };
15 }
16
17 @Override
18 public Advice getAdvice() {
19 return new MethodBeforeAdvice() {
20 @Override
21 public void before(Method method, Object[] args, Object target) throws Throwable {
22 System.out.println("before hello");
23 }
24 };
25 }
26
27 @Override
28 public boolean isPerInstance() {
29 return false;
30 }
31 });
32
33 // ☆ ->
34 IUserService proxy = (IUserService) proxyFactory.getProxy();
35 proxy.nihao();
36 System.out.println("======================================");
37 proxy.hello();
38}
39
40// 输出
41// nihao
42// ======================================
43// before hello
44// hello
4. 为Spring中的Bean动态代理
4.1. ProxyFactoryBean
1@Bean
2public ProxyFactoryBean userService() {
3 ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
4 proxyFactoryBean.setTarget(new UserService());
5 proxyFactoryBean.setProxyTargetClass(true);
6 return proxyFactoryBean;
7}
可以看到已经为UserService生成了CGLIB的代理对象。
4.2. BeanNameAutoProxyCreator
1@Bean
2public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
3 BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
4 beanNameAutoProxyCreator.setBeanNames("userSer*");
5 beanNameAutoProxyCreator.setInterceptorNames("testBeforeAdvice");
6 return beanNameAutoProxyCreator;
7}

在上面的截图中我们可以看到UserService也产生了代理对象,但是使用的是JDK的动态代理。
当我们把UserService上的IUserSerivce接口去掉之后就会使用CGLIB的动态代理,如下图所示:

4.3. DefaultAdvisorAutoProxyCreator
1@Bean
2public DefaultPointcutAdvisor defaultPointcutAdvisor() {
3 NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
4 pointcut.addMethodName("hello");
5
6 DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
7 defaultPointcutAdvisor.setPointcut(pointcut);
8 defaultPointcutAdvisor.setAdvice(new TestBeforeAdvice());
9 return defaultPointcutAdvisor;
10}
11
12@Bean
13public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
14 DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
15 return defaultAdvisorAutoProxyCreator;
16}
这里可以只为有指定方法的对象生成代理,只有有这个方法的bean才会生成对应的代理对象。

上面的代码中DefaultAdvisorAutoProxyCreator这个类可以直接使用@Import(DefaultAdvisorAutoProxyCreator.class)注解导入,可以实现同样的效果
4.4. Target和TargetSource
正常我们在使用ProxyFactory的时候,调用setTarget(target),底层还是会将target封装成targetSource
1public void setTarget(Object target) {
2 setTargetSource(new SingletonTargetSource(target));
3}
4.4.1. @Lazy
lazy注解的底层实际上正是使用了new了一个targetSource,实现懒加载,此时的代理对象的target并不是真正的target,而是为了被代理对象不为空而由spring生成的一个targetSource对象。
当在调用targetSource的getTarget()方法的时候,才会从BeanFacotry中找到真正的bean对象。
ContextAnnotationAutowireCandidateResolver#buildLazyResolutionProxy()
1protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
2
3 // ...
4 TargetSource ts = new TargetSource() {
5 @Override
6 public Class<?> getTargetClass() {
7 return descriptor.getDependencyType();
8 }
9 @Override
10 public boolean isStatic() {
11 return false;
12 }
13 @Override
14 public Object getTarget() {
15 Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null);
16 Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
17 // ...
18 return target;
19 }
20 @Override
21 public void releaseTarget(Object target) {
22 }
23 };
24
25 ProxyFactory pf = new ProxyFactory();
26
27 // 设置一个targetSource
28 pf.setTargetSource(ts);
29 Class<?> dependencyType = descriptor.getDependencyType();
30 if (dependencyType.isInterface()) {
31 pf.addInterface(dependencyType);
32 }
33 return pf.getProxy(dlbf.getBeanClassLoader());
34}
4.5. Introduction
比如说我现在有一个UserService的类,我需要动态的为他新增一个接口,这个时候我们就可以用到introduction。
1@Aspect
2@Component
3public class TestAspect {
4 @DeclareParents(value = "org.springframework.gang.service.UserService", defaultImpl = IntroUserService.class)
5 public IIntroUserService introUserService;
6}
7
8public interface IIntroUserService {
9 public void intro();
10}
11
12public class IntroUserService implements IIntroUserService{
13 public void intro() {
14 System.out.println("intro");
15 }
16}
在上面的代码中,我们为UserService这个类动态的新增了一个IIntroUserService这个接口,那么接口有了,这个接口里面的方法的实现内容怎么确定呢,这个接口的实现内容需要放在另外一个实现类中,即@DeclareParents的参数中有一个defaultImpl参数。
完成了上面的代码后,我们就可以测试一下:
1public class Main {
2 public static void main(String[] args) {
3 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
4 IIntroUserService userService = (IIntroUserService) context.getBean("userService");
5 userService.intro();
6 }
7}
这时候,从context中拿到的就IIntroUserService这种类型的userService的代理对象了,此时就可以调用新增接口中的intro()方法了。
上面就是AOP中introduction的大概内容
5. 代理对象创建
从ProxyFactory方法进入
1public void springAop(){
2 UserService userService = new UserService();
3 ProxyFactory proxyFactory = new ProxyFactory(userService);
4 proxyFactory.setTarget(userService);
5 proxyFactory.addAdvice(new MethodBeforeAdvice() {
6 @Override
7 public void before(Method method, Object[] args, Object target) throws Throwable {
8 System.out.println("before hello");
9 }
10 });
11
12 // ☆ ->
13 IUserService proxy = (IUserService) proxyFactory.getProxy();
14 proxy.hello();
15}
在getProxy()方法中
1public Object getProxy() {
2 // ☆ ->
3 return createAopProxy().getProxy();
4}
-
createAopProxy():决定是使用JDK动态代理还是CGLIB动态代理
1@Override 2public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 3 if ( 4 !NativeDetector.inNativeImage() && 5 ( 6 config.isOptimize() || 7 config.isProxyTargetClass() || 8 hasNoUserSuppliedProxyInterfaces(config) 9 ) 10 ) { 11 Class<?> targetClass = config.getTargetClass(); 12 if (targetClass == null) { 13 throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation."); 14 } 15 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { 16 return new JdkDynamicAopProxy(config); 17 } 18 return new ObjenesisCglibAopProxy(config); 19 } else { 20 return new JdkDynamicAopProxy(config); 21 } 22}可以看出:
- CGLIB动态代理条件:
- 如果ProxyFactory的isOptimize设置为了true(setOptimize()方法设置) ,spring会认为cglib比jdk动态代理要快
- isProxyTargetClass设置为true
- 或者被代理的对象没有实现接口(需要通过
addInterface()方法设置的) - 不是在
GraalVM上虚拟机上运行的
- JDK动态代理条件:
- 被代理的类是接口, 或者被代理的类是进行过JDK动态代理的类, 则只能进行JDK动态代理
- 其他情况都会进行JDK动态代理
- CGLIB动态代理条件:
-
getProxy():获取代理对象
- JdkDynamicAopProxy
- ObjenesisCglibAopProxy
两种代理方式的代理方法执行都是在invoke()这个方法中:
- org.springframework.aop.framework.JdkDynamicAopProxy#invoke
- ?
5.1. JDK代理对象创建
在下面的方法中会更具ClassFilter和MethodMatcher来过滤Advice
DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
1public class TestPointcutAdvisor implements PointcutAdvisor {
2 @Override
3 public Advice getAdvice() {
4 return new TestBeforeAdvice();
5 }
6
7 @Override
8 public boolean isPerInstance() {
9 return false;
10 }
11
12 @Override
13 public Pointcut getPointcut() {
14 return new Pointcut() {
15 @Override
16 public ClassFilter getClassFilter() {
17 return new ClassFilter() {
18 @Override
19 public boolean matches(Class<?> clazz) {
20 return false;
21 }
22 };
23 }
24
25 @Override
26 public MethodMatcher getMethodMatcher() {
27 return new MethodMatcher() {
28 @Override
29 public boolean matches(Method method, Class<?> targetClass) {
30 return false;
31 }
32
33 @Override
34 public boolean isRuntime() {
35 return false;
36 }
37
38 @Override
39 public boolean matches(Method method, Class<?> targetClass, Object... args) {
40 return false;
41 }
42 };
43 }
44 };
45 }
46}
Advice转换成对应的MethodInterceptor
DefaultAdvisorAdapterRegistry#getInterceptors
1 @Override
2 public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
3 List<MethodInterceptor> interceptors = new ArrayList<>(3);
4 Advice advice = advisor.getAdvice();
5 // 如果advice已经是MethodInterceptor对象了则直接加到Interceptors中
6 if (advice instanceof MethodInterceptor) {
7 interceptors.add((MethodInterceptor) advice);
8 }
9
10 // 如果不是
11 // 则将Advice转换成MethodInterceptor,并添加到Interceptors中
12 // adapters 有三种:
13 // 1. AfterReturningAdviceAdapter --转换--> AfterReturningAdviceInterceptor (MethodInterceptor)
14 // 2. MethodBeforeAdviceAdapter ...
15 // 3. ThrowsAdviceAdapter ...
16 for (AdvisorAdapter adapter : this.adapters) {
17 if (adapter.supportsAdvice(advice)) {
18 interceptors.add(adapter.getInterceptor(advisor));
19 }
20 }
21 if (interceptors.isEmpty()) {
22 throw new UnknownAdviceTypeException(advisor.getAdvice());
23 }
24 return interceptors.toArray(new MethodInterceptor[0]);
25 }
在AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter 、ThrowsAdviceAdapter三个类中的都会有一个getInterceptor(),这是在这个方法中将Advice转成了对应的MethodInterceptor的,最后实际上执行的代理方法正式对应MethodInterceptor的invoke()方法,详细如下:
-
AfterReturningAdviceAdapter1// AfterReturningAdviceAdapter.java 2public MethodInterceptor getInterceptor(Advisor advisor) { 3 AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice(); 4 return new AfterReturningAdviceInterceptor(advice); 5} 6 7// AfterReturningAdviceInterceptor.java 8public Object invoke(MethodInvocation mi) throws Throwable { 9 Object retVal = mi.proceed(); 10 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); 11 return retVal; 12} -
MethodBeforeAdviceAdapter1// MethodBeforeAdviceAdapter.java 2public MethodInterceptor getInterceptor(Advisor advisor) { 3 MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); 4 return new MethodBeforeAdviceInterceptor(advice); 5} 6 7// MethodBeforeAdviceInterceptor.java 8public Object invoke(MethodInvocation mi) throws Throwable { 9 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); 10 return mi.proceed(); 11} -
ThrowsAdviceAdapter1// ThrowsAdviceAdapter.java 2public MethodInterceptor getInterceptor(Advisor advisor) { 3 return new ThrowsAdviceInterceptor(advisor.getAdvice()); 4} 5 6// ThrowsAdviceInterceptor.java 7public Object invoke(MethodInvocation mi) throws Throwable { 8 try { 9 return mi.proceed(); 10 } catch (Throwable ex) { 11 Method handlerMethod = getExceptionHandler(ex); 12 if (handlerMethod != null) { 13 invokeHandlerMethod(mi, ex, handlerMethod); 14 } 15 throw ex; 16 } 17}
5.2. CGLIB代理对象创建
ProxyFactory#getProxy() 方法选择CGLIB的实现后即可进入CGLIB代理相关的方法
1@Override
2public Object getProxy(@Nullable ClassLoader classLoader) {
3
4 // ...
5
6 // 拿到被代理的类
7 Class<?> rootClass = this.advised.getTargetClass();
8 Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
9
10 Class<?> proxySuperClass = rootClass;
11 // 如果被代理的类的本身就已经是在Cglib所生成的代理类了
12 if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
13 // 获取真正的被代理类
14 proxySuperClass = rootClass.getSuperclass();
15 // 获取被代理类所实现的接口
16 Class<?>[] additionalInterfaces = rootClass.getInterfaces();
17 for (Class<?> additionalInterface : additionalInterfaces) {
18 this.advised.addInterface(additionalInterface);
19 }
20 }
21
22 // Validate the class, writing log messages as necessary.
23 validateClassIfNecessary(proxySuperClass, classLoader);
24
25 // Configure CGLIB Enhancer...
26 Enhancer enhancer = createEnhancer();
27 if (classLoader != null) {
28 enhancer.setClassLoader(classLoader);
29 if (classLoader instanceof SmartClassLoader &&
30 ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
31 enhancer.setUseCache(false);
32 }
33 }
34
35 // 被代理类, 代理类的父亲
36 enhancer.setSuperclass(proxySuperClass);
37 // 代理类额外要实现的接口
38 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
39 enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
40 enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
41
42 // ☆ ->
43 // 获取和被代理类所匹配的Advisor
44 Callback[] callbacks = getCallbacks(rootClass);
45 Class<?>[] types = new Class<?>[callbacks.length];
46 for (int x = 0; x < types.length; x++) {
47 types[x] = callbacks[x].getClass();
48 }
49 // fixedInterceptorMap only populated at this point, after getCallbacks call above
50 enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
51 enhancer.setCallbackTypes(types);
52
53 // Generate the proxy class and create a proxy instance.
54 return createProxyClassAndInstance(enhancer, callbacks);
55
56 // ...
57
58}
上面的代码中从44行的getCallbacks()方法中返回了和代理类相匹配的Advisor。
1private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
2 // ...
3
4 // 会进入到下面的方法:org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept
5 Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
6
7 // ...
8}
在CglibAopProxy中有个内部类DynamicAdvisedInterceptor,包含了的intercept()方法将会被调用,和JdkDynamicAopProxy中的invoke()方法有着异曲同工的作用。都会调用this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);获取到所有的Advisor。
6. 一些名词汇总
Aspect:表示切面,比如被@Aspect注解的类就是切面Join Point:表示连节点,表示程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在SpiringAop中,一个连节点通常表示一个方法的执行Advice:表示通知,特定连节点上采取的动作,Advice分为不同的理性Pointcut:表示切点,用来匹配一个或者多个连节点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式锁匹配的连接点上Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口Target object:目标对象被代理对象Aop Proxy:表示代理工厂,用来的创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译期时期,或者运行时,比如Spring AOP
7. Spring AOP 大致流程

8. Spring Bean代理对象创建流程
1@Import(AspectJAutoProxyRegistrar.class)
2public @interface EnableAspectJAutoProxy {
3 ...
4}
引入了 AspectJAutoProxyRegistrar.class
在AspectJAutoProxyRegistrar中, 通过在初始化容器实例化对象之前, 回调registerBeanDefinitions()的方法,向BeanDefinition中注册一个 AnnotationAwareAspectJAutoProxyCreator.class
1@Override
2public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
3 ...
4 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
5 ...
6}

在上图中我们看到AnnotationAwareAspectJAutoProxyCreator是实现了BeanPostProcessor接口的,
而实现BeanPostProcessor后,当Spring在Bean的初始化后会调用其postProcessAfterInitialization()方法,AOP逻辑由此开始。
接着进入postProcessAfterInitialization() 这个方法的逻辑
找到了AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator 中的这个方法 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
1@Override
2public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
3 if (bean != null) {
4 Object cacheKey = getCacheKey(bean.getClass(), beanName);
5 if (this.earlyProxyReferences.remove(cacheKey) != bean) {
6
7 // ☆ ->
8 return wrapIfNecessary(bean, beanName, cacheKey);
9 }
10 }
11 return bean;
12}
继续进入方法中wrapIfNecessary()
1protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
2 // 判断当前bean是否存在匹配的advice, 如果存在则要生成一个代理对象
3 // 此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
4 // 代理对象在执行的时候, 还会根据当前执行的方法去匹配
5 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
6 if (specificInterceptors != DO_NOT_PROXY) {
7
8 // advisedBeans记录了某个Bean已经进行过AOP了
9 this.advisedBeans.put(cacheKey, Boolean.TRUE);
10
11 // ☆ ->
12 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
13 this.proxyTypes.put(cacheKey, proxy.getClass());
14 return proxy;
15 }
16
17 this.advisedBeans.put(cacheKey, Boolean.FALSE);
18 return bean;
19 }
继续进入createProxy()方法
1protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
2 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
3 return bean;
4 }
5
6 // advisedBeans表示已经判断过来的的bean, false表示此bean不需要进行Aop
7 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
8 return bean;
9 }
10
11 // 当前正在创建Bean不用进行AOP, 比如切面Bean
12 // shouldSkip() 是模板方法, 子类可以去扩展的
13 // org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.isInfrastructureClass
14 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
15 this.advisedBeans.put(cacheKey, Boolean.FALSE);
16
17 // 直接返回
18 return bean;
19 }
20
21 // ☆ ->
22 // 判断当前bean是否存在匹配的advice, 如果存在则要生成一个代理对象
23 // 此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
24 // 代理对象在执行的时候, 还会根据当前执行的方法去匹配
25 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
26 if (specificInterceptors != DO_NOT_PROXY) {
27
28 // advisedBeans记录了某个Bean已经进行过AOP了
29 this.advisedBeans.put(cacheKey, Boolean.TRUE);
30
31 // ☆ ->
32 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
33 this.proxyTypes.put(cacheKey, proxy.getClass());
34 return proxy;
35 }
36
37 this.advisedBeans.put(cacheKey, Boolean.FALSE);
38 return bean;
39 }
该方法做了如下事情:
- 进入方法后判断当前Bean是需要进行AOP,advisedBeans相当于是一个缓存,在下面判断过的bean会放入这个map中,避免再次到下面去判断。
- 判断当前bean是否存在匹配的advice, 匹配的条件是向根据类名,再根据方法名(如果有必要的话),如果存在则要生成一个代理对象,此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
- 通过
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()这个方法找到所有的Advisor
1@Override
2protected List<Advisor> findCandidateAdvisors() {
3 // Add all the Spring advisors found according to superclass rules.
4 // 找到所有Advisor类型的Bean对象
5 List<Advisor> advisors = super.findCandidateAdvisors();
6
7 // Build Advisors for all AspectJ aspects in the bean factory.
8 // 再从所有的切面中解析得到Advisor对象
9 if (this.aspectJAdvisorsBuilder != null) {
10
11 // 解析AspectJ中定义的切面方法, 并加到advisors中
12 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
13 }
14 return advisors;
15}
在该方法中会调用BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors() 把Bean都解析成Advisor, 并在list中返回
buildAspectJAdvisors()代码如下:
1public List<Advisor> buildAspectJAdvisors() {
2 List<String> aspectNames = this.aspectBeanNames;
3
4 if (aspectNames == null) {
5 synchronized (this) {
6 aspectNames = this.aspectBeanNames;
7 if (aspectNames == null) {
8 List<Advisor> advisors = new ArrayList<>();
9 aspectNames = new ArrayList<>();
10 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
11 this.beanFactory, Object.class, true, false);
12 for (String beanName : beanNames) {
13 if (!isEligibleBean(beanName)) {
14 continue;
15 }
16
17 Class<?> beanType = this.beanFactory.getType(beanName, false);
18 if (beanType == null) {
19 continue;
20 }
21
22 // 判断类上是否有AspectJ注解
23 if (this.advisorFactory.isAspect(beanType)) {
24 aspectNames.add(beanName);
25
26 // 切面的注解信息
27 AspectMetadata amd = new AspectMetadata(beanType, beanName);
28
29 // 如果@Aspect不是perthis、pertarget, 那么一个切面只会生成一个对象(单例),
30 // 并且会将该切面中的所对应的Advisor对象进行缓存
31 if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
32 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
33
34 // ☆ ->
35 // 利用BeanFactoryAspectInstanceFactory来解析Aspect类
36 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
37 if (this.beanFactory.isSingleton(beanName)) {
38
39 // 缓存切面所对应的所有Advisor对象
40 this.advisorsCache.put(beanName, classAdvisors);
41 } else {
42 this.aspectFactoryCache.put(beanName, factory);
43 }
44 advisors.addAll(classAdvisors);
45 } else {
46 // Per target or per this.
47 if (this.beanFactory.isSingleton(beanName)) {
48 throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
49 }
50 MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
51 this.aspectFactoryCache.put(beanName, factory);
52
53 // 利用PrototypeAspectInstanceFactory来解析Aspect类
54 // PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory
55 // 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,
56 // 除此之外没有其他区别
57 //
58 // 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
59 advisors.addAll(this.advisorFactory.getAdvisors(factory));
60 }
61 }
62 }
63 this.aspectBeanNames = aspectNames;
64 return advisors;
65 }
66 }
67 }
68
69 if (aspectNames.isEmpty()) {
70 return Collections.emptyList();
71 }
72
73 // 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
74 List<Advisor> advisors = new ArrayList<>();
75 for (String aspectName : aspectNames) {
76 List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
77 if (cachedAdvisors != null) {
78 advisors.addAll(cachedAdvisors);
79 } else {
80 MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
81 advisors.addAll(this.advisorFactory.getAdvisors(factory));
82 }
83 }
84 return advisors;
85}
上面方法中: List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
1 @Override
2 public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
3
4 ......
5
6 // 获取切面类中[没有]加@Pointcut的方法,进行遍历生成Advisor, 并排序
7 for (Method method : getAdvisorMethods(aspectClass)) {
8 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
9 if (advisor != null) {
10 advisors.add(advisor);
11 }
12 }
13
14 // 如果是pertarget或perthis,则会多生成一个Advisor并放在最前面
15 // 在一个代理对象调用方法的时候,就会执行该Advisor,并且会利用lazySingletonAspectInstanceFactory来生成一个切面Bean
16 if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
17 Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
18 advisors.add(0, instantiationAdvisor);
19 }
20
21 // 找到哪些字段上加了@DeclareParents注解,把这些字段以及对于的注解解析封装为Advisor,生成代理对象时会把对于的接口添加到ProxyFactory中
22 for (Field field : aspectClass.getDeclaredFields()) {
23 Advisor advisor = getDeclareParentsAdvisor(field);
24 if (advisor != null) {
25 advisors.add(advisor);
26 }
27 }
28
29 return advisors;
30 }
在上面的代码中: getAdvisorMethods(aspectClass) 会获取切面类中没有加@Pointcut的方法,进行遍历生成Advisor, 并排序。
排序规则:
1static {
2 // 先更具下面的注解排序
3 Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
4 new InstanceComparator<>(
5 Around.class,
6 Before.class,
7 After.class,
8 AfterReturning.class,
9 AfterThrowing.class
10 ),
11 (Converter<Method, Annotation>) method -> {
12 AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
13 return (ann != null ? ann.getAnnotation() : null);
14 });
15
16 // 再根据方法名排序
17 Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
18 adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
19}
继续回到 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName); 该方法返回的对象是Advisor的实现类InstantiationModelAwarePointcutAdvisorImpl 。
在InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice() 方法中会根据方法上的注解生成对应的Advice。
1// 按不同的注解类型得到不同的Advice
2switch (aspectJAnnotation.getAnnotationType()) {
3 case AtPointcut:
4 if (logger.isDebugEnabled()) {
5 logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
6 }
7 return null;
8 case AtAround:
9 springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
10 break;
11 case AtBefore:
12 springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
13 break;
14 case AtAfter:
15 springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
16 break;
17 case AtAfterReturning:
18 springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
19 AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
20 if (StringUtils.hasText(afterReturningAnnotation.returning())) {
21 springAdvice.setReturningName(afterReturningAnnotation.returning());
22 }
23 break;
24 case AtAfterThrowing:
25 springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
26 AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
27 if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
28 springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
29 }
30 break;
31 default:
32 throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
33}
各注解对应的MethodInterceptor
@Before:对应的是AspectJMethodBeforeAdvice,在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor- 先执行advice对应的方法
- 再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
@After:对应的是AspectJAfterAdvice,直接实现了MethodInterceptor- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 再执行advice对应的方法
@Around:对应的是AspectJAroundAdvice,直接实现了MethodInterceptor- 直接执行advice对应的方法,由@Around自己决定要不要继续往后面调用
@AfterThrowing:对应的是AspectJAfterThrowingAdvice,直接实现了MethodInterceptor- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 如果上面抛了Throwable,那么则会执行advice对应的方法
@AfterReturning:对应的是AspectJAfterReturningAdvice,在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 执行上面的方法后得到最终的方法的返回值
- 再执行Advice对应的方法
在AspectJ中有五种注解,而Spring中中只有四种Advice