警告
本文最后更新于 2020-11-29,文中内容可能已过时。
spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi/spring-framework 。
链接中源码是作者从 github 下载,并以自身理解对核心流程及主要节点做了详细的中文注释。
1 AOP入口
AOP是通过 BeanPostProcessor.postProcessAfterInitialization() 实现的,来到 doCreateBean() -> initializeBean(),在初始化方法执行完成后,会调用 applyBeanPostProcessorsAfterInitialization(),这里循环调用了所有 BeanPostProcessor 的 postProcessAfterInitialization(),AOP 的入口就在其中的一个实现类,也是 AbstractAutoProxyCreator 的子类实现。
要看代理对象的生成过程,首先要看支持这个功能的类,是在哪里注册的,它源自哪里?
2 XMl配置方式BeanPostProcessor的注册
XMl方式注入AOP支持的BeanPostProcessor,是通过 <aop:aspectj-autoproxy/>
标签注入的。
根据SPI加载规则,找到 spring-aop 模块下的 META-INF/spring.handlers 文件。
可以看到以下内容:
1
http\ : //www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
来到 AopNamespaceHandler 类,源码如下:
1
2
3
4
5
6
7
8
9
10
public class AopNamespaceHandler extends NamespaceHandlerSupport {
public void init () {
registerBeanDefinitionParser ( "config" , new ConfigBeanDefinitionParser ());
// AspectJAutoProxyBeanDefinitionParser标签 <aop:aspectj-autoproxy/> 的支持,
// 在其 parse() 中注册了AOP的入口类 AnnotationAwareAspectJAutoProxyCreator,是一个 BeanPostProcessor
registerBeanDefinitionParser ( "aspectj-autoproxy" , new AspectJAutoProxyBeanDefinitionParser ());
registerBeanDefinitionDecorator ( "scoped-proxy" , new ScopedProxyBeanDefinitionDecorator ());
registerBeanDefinitionParser ( "spring-configured" , new SpringConfiguredBeanDefinitionParser ());
}
}
我们在使用Spring XML配置方式使用 <aop:aspectj-autoproxy/>
标签激活代理,在 init() 中注册了 aspectj-autoproxy
属性的解析类,在这个解析类中,注入了 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition。
源码如下:
步骤一:
1
2
3
4
5
6
7
8
9
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse ( Element element , ParserContext parserContext ) {
// 对aspectj-autoproxy属性的支持
AopNamespaceUtils . registerAspectJAnnotationAutoProxyCreatorIfNecessary ( parserContext , element );
// 添加IncludePatterns
extendBeanDefinition ( element , parserContext );
return null ;
}
}
步骤二:
1
2
3
4
5
6
7
8
9
10
public abstract class AopNamespaceUtils {
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary (
ParserContext parserContext , Element sourceElement ) {
// 这里注册了AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils . registerAspectJAnnotationAutoProxyCreatorIfNecessary (
parserContext . getRegistry (), parserContext . extractSource ( sourceElement ));
useClassProxyingIfNecessary ( parserContext . getRegistry (), sourceElement );
registerComponentIfNecessary ( beanDefinition , parserContext );
}
}
步骤三:
1
2
3
4
5
6
7
8
public abstract class AopConfigUtils {
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary (
BeanDefinitionRegistry registry , @Nullable Object source ) {
// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
return registerOrEscalateApcAsRequired ( AnnotationAwareAspectJAutoProxyCreator . class , registry , source );
}
}
可以看到,步骤三中,最后 return
语句后注册了 AnnotationAwareAspectJAutoProxyCreator。
信息
回顾:BeanPostProcessor 提前注册到IOC容器的流程。
创建 BeanFactory,完成所有 BeanDefinition 的搜集。
执行 invokeBeanFactoryPostProcessors()(BeanDefinition的后置处理)。BeanFactoryPostProcessor 及子接口 BeanDefinitionRegistryPostProcessor 实现类的方法。
执行 registerBeanPostProcessors。从 beanFactory 中获取所有的 BeanPostProcessor,优先进行 getBean() 操作,实例化。
3 注解方式BeanPostProcessor的注册
3.1 注解方式案例
先看一个案例:
切面类:
1
2
3
4
5
6
7
8
9
10
@Component @Aspect @Slf4j
public class CustomAspect {
@Pointcut ( "execution(* top.wlz922.aspect.*.*(..))" )
public void pointCut (){}
@Before ( "pointCut()" )
public void before (){
log . info ( "CustomAspect.before execute..." );
}
}
业务类:
1
2
3
4
5
6
7
@Component
@Slf4j
public class Apple {
public void showTaste (){
log . info ( "Apple is sour and sweet." );
}
}
配置类:
1
2
3
4
5
@Configuration
@EnableAspectJAutoProxy
@ComponentScan ( basePackages = "top.wlz922" )
public class AspectAnoConfiguration {
}
测试类:
1
2
3
4
5
6
7
8
9
@Slf4j
public class ApplicationContextTest {
@Test
public void testAnoAop (){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ( AspectAnoConfiguration . class );
Apple apple = context . getBean ( Apple . class );
apple . showTaste ();
}
}
执行结果:
1
2
12:23:34.294 [main] INFO top.wlz922.aspect.CustomAspect 16 - CustomAspect.before execute...
12:23:34.325 [main] INFO top.wlz922.aspect.Apple 10 - Apple is sour and sweet.
以上是一个简单的注解方式激活AOP功能的案例。
3.2 AspectJAutoProxyRegistrar的注册
下面来看注解方式,注入对应支持的 BeanPostProcessor 的入口。
这是 @EnableAspectJAutoProxy 的声明:
1
2
3
4
5
6
7
8
@Target ( ElementType . TYPE )
@Retention ( RetentionPolicy . RUNTIME )
@Documented
@Import ( AspectJAutoProxyRegistrar . class )
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass () default false ;
boolean exposeProxy () default false ;
}
可以看到,@EnableAspectJAutoProxy 上有一个 @Import,那么它在创建 BeanFactory,扫描注册 BeanDefinition 时,会把 AspectJAutoProxyRegistrar 类包装为 BeanDefinition 注册到容器中。
看 AspectJAutoProxyRegistrar 的声明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions (
AnnotationMetadata importingClassMetadata , BeanDefinitionRegistry registry ) {
// TODO 注册自动代理的支持类的BeanDefinition到容器中。
AopConfigUtils . registerAspectJAnnotationAutoProxyCreatorIfNecessary ( registry );
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils . attributesFor ( importingClassMetadata , EnableAspectJAutoProxy . class );
// 如果激活了自动代理,这里会设置AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对应的属性值
if ( enableAspectJAutoProxy != null ) {
if ( enableAspectJAutoProxy . getBoolean ( "proxyTargetClass" )) {
AopConfigUtils . forceAutoProxyCreatorToUseClassProxying ( registry );
}
if ( enableAspectJAutoProxy . getBoolean ( "exposeProxy" )) {
AopConfigUtils . forceAutoProxyCreatorToExposeProxy ( registry );
}
}
}
}
来到 registerAspectJAnnotationAutoProxyCreatorIfNecessary():
1
2
3
4
5
6
7
8
9
public abstract class AopConfigUtils {
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary (
BeanDefinitionRegistry registry , @Nullable Object source ) {
// 注入此类 AnnotationAwareAspectJAutoProxyCreator,本质还是一个BeanPostProcessor,
// 实现了BeanPostProcessor的子接口:SmartInstantiationAwareBeanPostProcessor
return registerOrEscalateApcAsRequired ( AnnotationAwareAspectJAutoProxyCreator . class , registry , source );
}
}
可以看到,在这里对 AnnotationAwareAspectJAutoProxyCreator 进行了注册。
具体的注册逻辑源码(注意参数的传递):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public abstract class AopConfigUtils {
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 ) {
// 前面注册的类没用,注册不进来,这里会根据等级返回BeanDefinition,注解方式会返回AnnotationAwareAspectJAutoProxyCreator
if ( registry . containsBeanDefinition ( AUTO_PROXY_CREATOR_BEAN_NAME )) {
BeanDefinition apcDefinition = registry . getBeanDefinition ( AUTO_PROXY_CREATOR_BEAN_NAME );
if ( ! cls . getName (). equals ( apcDefinition . getBeanClassName ())) {
// 这里会有一个比较,在注册AbstractAdvisorAutoProxyCreator时,会有一个优先级。
// 如果这里已经注册过AbstractAdvisorAutoProxyCreator,在此注册的时候,
// 会与之前的注册的进行优先级比较,优先级高的会覆盖掉优先级低的。注解的优先级最高。
int currentPriority = findPriorityForClass ( apcDefinition . getBeanClassName ());
int requiredPriority = findPriorityForClass ( cls );
if ( currentPriority < requiredPriority ) {
apcDefinition . setBeanClassName ( cls . getName ());
}
}
return null ;
}
// 创建BeanDefinition,并设置一些属性。
RootBeanDefinition beanDefinition = new RootBeanDefinition ( cls );
beanDefinition . setSource ( source );
beanDefinition . getPropertyValues (). add ( "order" , Ordered . HIGHEST_PRECEDENCE );
beanDefinition . setRole ( BeanDefinition . ROLE_INFRASTRUCTURE );
// 注册到BeanDefinitionRegistry
registry . registerBeanDefinition ( AUTO_PROXY_CREATOR_BEAN_NAME , beanDefinition );
return beanDefinition ;
}
}
首先这里会判断容器中是否包含指定名称的 BeanDefinition,如果包含,拿这次将要注册的类型与已存在的类型进行优先级比对,以优先级高的为准进行 BeanDefinition 的注册。
看一下获取优先级的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class AopConfigUtils {
private static final List < Class <?>> APC_PRIORITY_LIST = new ArrayList <> ( 3 );
static {
// 这里默认包含三个代理生成类
// Set up the escalation list...
APC_PRIORITY_LIST . add ( InfrastructureAdvisorAutoProxyCreator . class );
APC_PRIORITY_LIST . add ( AspectJAwareAdvisorAutoProxyCreator . class );
APC_PRIORITY_LIST . add ( AnnotationAwareAspectJAutoProxyCreator . class );
}
private static int findPriorityForClass ( @Nullable String className ) {
for ( int i = 0 ; i < APC_PRIORITY_LIST . size (); i ++ ) {
Class <?> clazz = APC_PRIORITY_LIST . get ( i );
if ( clazz . getName (). equals ( className )) {
return i ;
}
}
throw new IllegalArgumentException (
"Class name [" + className + "] is not a known auto-proxy creator class" );
}
}
在 AopConfigUtils 静态代码块中,初始化了三个 BeanPostProcessor 的实现,按照在 list 容器中的索引大小来确定优先级。优先级大小顺序为:
AnnotationAwareAspectJAutoProxyCreator > AspectJAwareAdvisorAutoProxyCreator > InfrastructureAdvisorAutoProxyCreator