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