1 概述
2 Spring Boot自动配置下AnnotationAwareAspectJAutoProxyCreator
的注册
1 概述
了解过Spring源码的都知道Spring是通过动态代理实现AOP的,Spring中实现动态代理有两种方式,分别为JDK原生动态代理和CGLIB,这里不对动态代理的具体实现进行介绍,主要介绍Spring实现动态代理的相关入口。
在进行接下来的介绍之前,我们要先看下Spring在创建一个Bean的实例之后时如何对Bean进行初始化的,AbstractAutowireCapableBeanFactory
在实例化一个Bean之后,会分别调用populateBean
和initializeBean
进行Bean的依赖注入和初始化,这里我们仅仅看initializeBean
的实现:
//AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//如何Bean实现了一些Aware接口,则调用相应的方法,比如
//BeanFactoryAware的setBeanFactory方法等
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用注册到BeanFactory里的BeanPostProcessor的
//postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//如果Bean有初始化方法,则调用初始化方法
//这里也有个重要的方法,如果Bean实现了InitializingBean接口
//那么方法里会识别出来并调用afterPropertiesSet方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用注册到BeanFactory里的BeanPostProcessor的
//postProcessAfterInitialization
//这里就是本文要介绍的AOP入口实现的地方
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
好了,通过上面源码注释可以发现,Spring AOP是通过BeanPostProcessor.applyBeanPostProcessorsAfterInitialization
在Bean实例化时进行处理的,那么肯定会有一个负责实现动态代理创建的BeanPostProcessor
接口实现负责处理相关逻辑,其实这个接口实现类就是AnnotationAwareAspectJAutoProxyCreator
,AnnotationAwareAspectJAutoProxyCreator
的相关方法会在需要的时候进行代理类的创建。
那么,AnnotationAwareAspectJAutoProxyCreator
是在何时注册到Spring BeanFactory中的呢?
2 Spring Boot自动配置下AnnotationAwareAspectJAutoProxyCreator
的注册
Spring Boot通过注解EnableAutoConfiguration
进行自动配置并引入相关组件,在spring.factories
中EnableAutoConfiguration
就配置了AopAutoConfiguration
。AopAutoConfiguration
就是AnnotationAwareAspectJAutoProxyCreator
引入的地方。
//AopAutoConfiguration
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
可见AopAutoConfiguration
的两个内部类JdkDynamicAutoProxyConfiguration
和CglibAutoProxyConfiguration
都被Configuration
注解,且也都被EnableAspectJAutoProxy
注解,EnableAspectJAutoProxy
源码如下:
//EnableAspectJAutoProxy
@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;
}
EnableAspectJAutoProxy
的注解@Import(AspectJAutoProxyRegistrar.class)
向Spring BeanFactory中注册了上文提到的AnnotationAwareAspectJAutoProxyCreator
。
后续在创建Bean时会使用AnnotationAwareAspectJAutoProxyCreator
进行AOP代理的创建