1 概述
2 Spring Boot自動(dòng)配置下AnnotationAwareAspectJAutoProxyCreator的注冊(cè)
1 概述
了解過(guò)Spring源碼的都知道Spring是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)AOP的,Spring中實(shí)現(xiàn)動(dòng)態(tài)代理有兩種方式,分別為JDK原生動(dòng)態(tài)代理和CGLIB,這里不對(duì)動(dòng)態(tài)代理的具體實(shí)現(xiàn)進(jìn)行介紹,主要介紹Spring實(shí)現(xiàn)動(dòng)態(tài)代理的相關(guān)入口。
在進(jìn)行接下來(lái)的介紹之前,我們要先看下Spring在創(chuàng)建一個(gè)Bean的實(shí)例之后時(shí)如何對(duì)Bean進(jìn)行初始化的,AbstractAutowireCapableBeanFactory在實(shí)例化一個(gè)Bean之后,會(huì)分別調(diào)用populateBean和initializeBean進(jìn)行Bean的依賴(lài)注入和初始化,這里我們僅僅看initializeBean的實(shí)現(xiàn):
//AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//如何Bean實(shí)現(xiàn)了一些Aware接口,則調(diào)用相應(yīng)的方法,比如
//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()) {
//調(diào)用注冊(cè)到BeanFactory里的BeanPostProcessor的
//postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//如果Bean有初始化方法,則調(diào)用初始化方法
//這里也有個(gè)重要的方法,如果Bean實(shí)現(xiàn)了InitializingBean接口
//那么方法里會(huì)識(shí)別出來(lái)并調(diào)用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()) {
//調(diào)用注冊(cè)到BeanFactory里的BeanPostProcessor的
//postProcessAfterInitialization
//這里就是本文要介紹的AOP入口實(shí)現(xiàn)的地方
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
好了,通過(guò)上面源碼注釋可以發(fā)現(xiàn),Spring AOP是通過(guò)BeanPostProcessor.applyBeanPostProcessorsAfterInitialization在Bean實(shí)例化時(shí)進(jìn)行處理的,那么肯定會(huì)有一個(gè)負(fù)責(zé)實(shí)現(xiàn)動(dòng)態(tài)代理創(chuàng)建的BeanPostProcessor接口實(shí)現(xiàn)負(fù)責(zé)處理相關(guān)邏輯,其實(shí)這個(gè)接口實(shí)現(xiàn)類(lèi)就是AnnotationAwareAspectJAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator的相關(guān)方法會(huì)在需要的時(shí)候進(jìn)行代理類(lèi)的創(chuàng)建。
那么,AnnotationAwareAspectJAutoProxyCreator是在何時(shí)注冊(cè)到Spring BeanFactory中的呢?
2 Spring Boot自動(dòng)配置下AnnotationAwareAspectJAutoProxyCreator的注冊(cè)
Spring Boot通過(guò)注解EnableAutoConfiguration進(jìn)行自動(dòng)配置并引入相關(guān)組件,在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 {
}
}
可見(jiàn)AopAutoConfiguration的兩個(gè)內(nèi)部類(lèi)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中注冊(cè)了上文提到的AnnotationAwareAspectJAutoProxyCreator。
后續(xù)在創(chuàng)建Bean時(shí)會(huì)使用AnnotationAwareAspectJAutoProxyCreator進(jìn)行AOP代理的創(chuàng)建