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