Spring注解驱动开发学习总结13:AOP原理 – AnnotationAwareAspectJAutoProxyCreator后置处理器注入容器的步骤

  • Post author:
  • Post category:其他


上一篇博文中,已经分析了配置类上添加

@EnableAspectJAutoProxy

注解,最终会给容器中注册了一个id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

的组件。

上一篇博文的小结如下:

1、使用AOP功能,要在配置类上加

@EnableAspectJAutoProxy

注解,而@

@EnableAspectJAutoProxy

注解类上加了@Import(

AspectJAutoProxyRegistrar

.class),也就是导入了一个

AspectJAutoProxyRegistrar

类。

2、

AspectJAutoProxyRegistrar

类中的registerBeanDefinitions方法,

最终给容器中注册了一个id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

的组件

3、注册了类型为

AnnotationAwareAspectJAutoProxyCreator

的组件,我们

理论上分析了该类的父类和所实现的接口,分析出该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法

,并且也通过测试进行了验证。

继承关系 后置处理方法 setBeanFactory方法

AnnotationAwareAspectJAutoProxyCreator
无重写 1、initBeanFactory

AspectJAwareAdvisorAutoProxyCreator
无重写 无重写

AbstractAdvisorAutoProxyCreator
无重写 1、setBeanFactory -> initBeanFactory

AbstractAutoProxyCreator
1、postProcessBeforeInstantiation;

2、postProcessAfterInitialization
1、setBeanFactory

在理论分析之后,可以在上面分析的类的方法处打上调试断点,同时对之前建立的业务类MathCalculator、切面类LogAspects打上断点。


本篇文章通过方法栈的调用来分析下这个id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

的后置处理器是怎么注入到ioc容器中的,大致的步骤有哪些?



1、注册AnnotationAwareAspectJAutoProxyCreator



1.1 查看调用栈

按照上面的分析,添加断点,还是运行之前博文中创建的测试方法testAop。

1)可以看到程序停到了

AbstractAdvisorAutoProxyCreator

类54行的setBeanFactory方法处。

2)方法栈开始于IocTest类的128行的testAop方法。


中间是方法栈的调用关系,接下来主要分析下AnnotationAwareAspectJAutoProxyCreator是怎么注入到ioc容器中的过程



在这里插入图片描述



1.2 方法栈调用分析

1、运行testAop方法

1.1 构建ioc容器:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);

在这里插入图片描述

2、运行AnnotationConfigApplicationContext方法

2.1 注册配置类:register(annotatedClasses);

2.2 刷新ioc容器:refresh();

在这里插入图片描述

3、运行refresh方法

前面准备了beanFactory,以及beanFactory的后置处理。在528行,

注册bean的后置处理器,来拦截bean的创建

:registerBeanPostProcessors(beanFactory)。

在这里插入图片描述

接下来接着看bean的后置处理器是如何创建的

3、运行registerBeanPostProcessors方法

3.1 在188行,先获取ioc容器已经定义了的所有BeanPostProcessor类型的id名称

3.2 在202行,遍历所有的BeanPostProcessor,根据是否是优先排序、排序、无排序分别加入到对应的容器中;

3.3 在224-225行,获取BeanPostProcessor,然后根据id名称获取bean:

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);,其中ppName=internalAutoProxyCreator。

这一步应该就是创建并获取bean的后置处理器,

等会要着重进来看一下这一步里面是怎么创建

id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

类的bean



3.4 在220,232,243,247,251行,把创建好的banPostProcessor注册到beanFactory中:

registerBeanPostProcessors(beanFactory,

internalAutoProxyCreator

);

beanFactory.addBeanPostProcessor

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

接着上面的3.3,查看doCreateBean方法,

来看下到底怎么创建id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

类的bean



3.3 获取BeanPostProcessor,然后根据id名称获取bean:

3.3.1 在513行,先创建bean的实例:instanceWrapper = createBeanInstance(beanName, mbd, args);,

其中beanName=

internalAutoProxyCreator



3.3.2 在553行,给bean的属性赋值:populateBean(beanName, mbd, instanceWrapper);

3.3.3 在555行,初始化bean:exposedObject = initializeBean(beanName, exposedObject, mbd);

在这里插入图片描述

在这里插入图片描述

接着上面的3.3.3,来看一下初始化bean的函数中又做了些什么事情?

3.3.3 初始化bean:查看initBeanFactory方法

3.3.3.1 在1615行,在处理Aware接口的方法回调:invokeAwareMethods(beanName, bean)。

再查看invokeAwareMethods方法,在1647行,如果是BeanFactoryAware的类,会调用

setBeanFactory

方法。

调用

setBeanFactory

方法,这就和上一篇博文分析的是一致了。

3.3.3.2 在1620行,执行后置处理器的beanPostProcessorsBeforeInitialization方法。这也和上一篇博文分析的是一致的。

3.3.3.3 在1624行,执行初始化方法:invokeInitMethods(beanName, wrappedBean, mbd);

3.3.3.4 在1633行,执行后置处理器的beanPostProcessorsAfterInitialization方法

在这里插入图片描述

在这里插入图片描述



1.3 小结



1.3.1 上篇博文小结

再次回顾下上一篇博文的小结:

1、使用AOP功能,要在配置类上加

@EnableAspectJAutoProxy

注解,而@

@EnableAspectJAutoProxy

注解类上加了@Import(

AspectJAutoProxyRegistrar

.class),也就是导入了一个

AspectJAutoProxyRegistrar

类。

2、

AspectJAutoProxyRegistrar

类中的registerBeanDefinitions方法,

最终给容器中注册了一个id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

的组件

3、注册了类型为

AnnotationAwareAspectJAutoProxyCreator

的组件,我们

理论上分析了该类的父类和所实现的接口,分析出该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法

,并且也通过测试进行了验证。

继承关系 后置处理方法 setBeanFactory方法

AnnotationAwareAspectJAutoProxyCreator
无重写 1、initBeanFactory

AspectJAwareAdvisorAutoProxyCreator
无重写 无重写

AbstractAdvisorAutoProxyCreator
无重写 1、setBeanFactory -> initBeanFactory

AbstractAutoProxyCreator
1、postProcessBeforeInstantiation;

2、postProcessAfterInitialization
1、setBeanFactory



1.3.2 后置处理器注入ioc容器步骤分析小结


通过方法栈的调用,分析了id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

的后置处理器,注入ioc容器的步骤如下



1、运行testAop方法,构建ioc容器:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);

2、运行AnnotationConfigApplicationContext方法

2.1 注册配置类:register(annotatedClasses);

2.2 刷新ioc容器:refresh();

3、运行registerBeanPostProcessors方法

3.1 先获取ioc容器已经定义了的所有BeanPostProcessor类型的id名称

3.2 遍历所有的BeanPostProcessor,根据是否是优先排序、排序、无排序分别加入到对应的容器中;

3.3 获取BeanPostProcessor,然后根据id名称获取bean:

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);,

其中ppName=

internalAutoProxyCreator



这一步应该就是创建并获取bean的后置处理器,

等会要着重进来看一下这一步里面是怎么创建

id为

internalAutoProxyCreator

,类型为

AnnotationAwareAspectJAutoProxyCreator

类的bean



3.3.1 先创建bean的实例:instanceWrapper = createBeanInstance(beanName, mbd, args);,

其中beanName=

internalAutoProxyCreator



3.3.2 给bean的属性赋值:populateBean(beanName, mbd, instanceWrapper);

3.3.3 初始化bean:exposedObject = initializeBean(beanName, exposedObject, mbd);

3.3.3.1 在处理Aware接口的方法回调:invokeAwareMethods(beanName, bean)。

再查看invokeAwareMethods方法,如果是BeanFactoryAware的类,

会调用

setBeanFactory

方法,

这就和上一篇博文分析的是一致了



3.3.3.2 执行后置处理器的beanPostProcessorsBeforeInitialization方法。

这也和上一篇博文分析

的是一致的



3.3.3.3 执行初始化方法:invokeInitMethods(beanName, wrappedBean, mbd);

3.3.3.4 执行后置处理器的beanPostProcessorsAfterInitialization方法

3.4 把创建好的banPostProcessor注册到beanFactory中:

registerBeanPostProcessors(beanFactory,

internalAutoProxyCreator

);

beanFactory.addBeanPostProcessor



版权声明:本文为xueping_wu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。