April 20, 2018

spring AOP原理之:

@EnableAspectJAutoProxy注解

接下来的三篇文章,我们来讲AOP这个小可爱。

1. 怎么开启spring AOP?

答案是使用@EnableAspectJAutoProxy注解开启AOP:

EnableAspectJAutoProxy注解注册了AspectJAutoProxyRegistrar.class类:

AspectJAutoProxyRegistrar.class类:

AspectJAutoProxyRegistrar#registerBeanDefinitions方法做了2件事:注册AnnotationAwareAspectJAutoProxyCreator,解析@EnableAspectJAutoProxy注解。其中AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary方法完成了AOP的所有逻辑。

2. AspectJAutoProxyRegistrar#registerBeanDefinitions方法什么时候被调用?

在了解AOP的逻辑之前,我们先来了解AspectJAutoProxyRegistrar#registerBeanDefinitions方法什么时候被调用的。

我们前面已经说过,Chapter1这个spring boot项目使用的IOC容器是:AnnotationConfigServletWebServerApplicationContext,

在AnnotationConfigServletWebServerApplicationContext#refresh刷新容器方法方法中,会执行invokeBeanFactoryPostProcessors方法:

接着执行PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法:

接着执行PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors方法:(ConfigurationClassPostProcessor是spring boot配置类后置处理器)

接着执行ConfigurationClassPostProcessor#processConfigBeanDefinitions方法:

在该方法中,candidates集合只有一个chapter1Application实例,parser.parse(candidates)方法会加载chapter1Application实例的所有配置类,所以耗时比较长,configClasses集合表示Chapter1Application的实例的拥有109个配置类。

接着执行ConfigurationClassBeanDefinitionReader#ConfigurationClassBeanDefinitionReader方法:

该方法会遍历configClasses集合中的配置类,当遍历到chapter1Application实例时,会解析Chapter1Application类,得到所有通过@Import注解注册的importBeanDefinitionRegistrars集合,该集合自然包含AspectJAutoProxyRegistrar.class类。

在spring boot里以下两种方式可以用来手动注入bean:

1.实现BeanDefinitionReader接口;

2.实现ImportBeanDefinitionRegistrar接口;

最终看到调用了AspectJAutoProxyRegistrar#registerBeanDefinitions方法:

AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary方法负责将AnnotationAwareAspectJAutoProxyCreator注册到IOC容器,安排!