有时候我们会遇到相似bean定义的情况: 这些bean需要被同样的一组拦截器包裹 。如果需要这样定义的bean数量很大,那么我们需要写大量重复度很高的xml配置行或者配置代码来定义这些bean,这显然是个可以优化解决的问题。为此,Spring AOP提供了自动代理创建机制。该机制通过往容器中添加一个APC来完成该任务。一个APC其实是一个SmartInstantiationAwareBeanPostProcessor,它会介入每个bean的实例化和初始化,检测bean的特征,如果该bean符合某些特征,比如有拦截器需要应用到该bean,那么该APC就会为它自动创建一个代理对象,使用相应的拦截器包裹住该bean。
在Spring AOP相应的APC实现机制中,首先,框架内置实现了三个自动代理创建器(auto proxy creator,缩写为APC):
| 实现类 | 优先级 |
|---|---|
InfrastructureAdvisorAutoProxyCreator | 0 – 最低优先级 |
AspectJAwareAdvisorAutoProxyCreator | 1 |
AnnotationAwareAspectJAutoProxyCreator | 2 – 最高优先级 |
以上信息可以参考
AopConfigUtils.APC_PRIORITY_LIST静态属性定义。
其次,Spring AOP提供了将这些APC注册到容器中的ImportBeanDefinitionRegistrar,比如AspectJAutoProxyRegistrar,AutoProxyRegistrar等等。这些ImportBeanDefinitionRegistrar进而被框架定义的@Enable*注解所使用,这里可以参考:
@Enable*注解 | 使用到的APC bean注册器 |
|---|---|
@EnableAspectJAutoProxy | 直接导入AspectJAutoProxyRegistrar |
@EnableGlobalMethodSecurity | 间接导入AutoProxyRegistrar |
@EnableReactiveMethodSecurity | 间接导入AutoProxyRegistrar |
@EnableTransactionManagement | 间接导入AutoProxyRegistrar |
@EnableCaching | 间接导入AutoProxyRegistrar |
最后,开发者,或者框架的某个部分,会引用上面所提到的@Enable*注解,从而导致APC注册器向容器登记相应的APC bean。进而容器启动时,APC机制就开始为我们提供服务解决文章开篇所提到的问题了。
另外,需要注意的是,在同一个Spring IoC容器中,最多只会注册一个APC bean,但实际上,容器启动过程中可能有多处在向容器注册APC bean,所使用的实现类可能是以上三者之一。那么容器最终会使用哪个APC实现类呢 ?这一点可以参考框架真正的APC bean注册逻辑AopConfigUtils#registerAutoProxyCreatorIfNecessary。简单来讲,每次APC注册行为逻辑是这样的 :
- 检测是否存在已经注册的
APC bean定义;- 不存在, 则执行
APC bean定义注册逻辑; - 存在, 则
- 即将注册的
APC类优先级较高,则会使用这次注册的APC类代理已注册APC bean定义中的bean class; - 即将注册的
APC类优先级较低,则什么都不做,直接返回;
- 即将注册的
- 不存在, 则执行

本文介绍Spring AOP中的自动代理创建机制,包括三种自动代理创建器的优先级及其实现原理。此外还介绍了如何通过@Enable*注解将这些自动代理创建器注册到Spring容器中。
2552

被折叠的 条评论
为什么被折叠?



