前言
上篇我们分析了初始化时AOP的特殊处理,本篇来分析依赖注入时的特殊处理。在阅读本篇之前,需要对BeanPostProcessor这个接口熟悉。关于BeanPostProcessor,后面会专门写一篇来专业介绍它。
概述
BeanPostProcessor这个接口提供了两个方法postProcessBeforeInitialization和postProcessAfterInitialization两个方法,子类中实现它们。我们知道依赖注入分为创建bean、注入、初始化三个过程,这两个方法就是在初始化时起作用的。在初始化时,我们已经拿到了一个bean,而BeanPostProcessor的两个方法就是在invokeInitMethods前后分别做一些处理。
上文提到的AspectJAwareAdvisorAutoProxyCreator的类图,我们有必要看一下
我们可以看到AspectJAwareAdvisorAutoProxyCreator其实是BeanPostProcessor的一个实现。AOP的整个核心就是这个类(当然也可以自己扩展,而不用它),而它实现的postProcessAfterInitialization方法是我们分析的核心。AspectJAwareAdvisorAutoProxyCreator在spring经历了下面三个过程。
- 上篇文章中,我们提到在初始化的特殊处理时默认会注册AspectJAwareAdvisorAutoProxyCreator的BeanDefinition,
- 而在AbstractApplicationContext的refresh方法中会调用registerBeanPostProcessors方法向容器中注入AspectJAwareAdvisorAutoProxyCreator实例。(后面会更新一篇博文,专门分析refresh方法)
- 初始化时,AspectJAwareAdvisorAutoProxyCreator能bean进行处理,返回一个代理对象给到用户
依赖注入时的特殊处理
IOC的依赖注入时,可以分为对象创建、注入、初始化三个步骤。AOP就是在初始化时发生作用的,我们从这开始分析
- 在
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
总结
到这里我们已经结束初始化的分析了,在下一篇再看依赖注册时的特殊处理,有两个地方可以注意下
- 注册了一个AspectComponentDefinition的复杂组件定义
- 最后在注册AspectJExpressionPointcut的定义时,我们发现是原型的,并不是单例的
参考链接
- https://wenku.baidu.com/view/6ce3121da300a6c30c229f89.html(核心关注点与横切关注点)
- https://www.cnblogs.com/syf/archive/2012/05/09/2491780.html(OOP与AOP)
- https://blog.csdn.net/garfielder007/article/details/78057107(连接点用地概念)
- https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference(spring官方文档)
- http://www.cnblogs.com/xrq730/p/6753160.html((源码分析的参考文章)
- https://blog.csdn.net/elim168/article/details/78166296(@DeclareParents使用)