Spring注解驱动开发学习总结13:AOP原理 – AnnotationAwareAspectJAutoProxyCreator后置处理器注入容器的步骤
上一篇博文中,已经分析了配置类上添加
@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