Spring AOP : 自动代理创建机制 (APC)

有时候我们会遇到相似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定义;
    1. 不存在, 则执行APC bean定义注册逻辑;
    2. 存在, 则
      • 即将注册的APC类优先级较高,则会使用这次注册的APC类代理已注册APC bean定义中的bean class
      • 即将注册的APC类优先级较低,则什么都不做,直接返回;

你可能感兴趣的:(spring,Spring,AOP)