Spring AOP 源码分析之入口

目录

一、@EnableAspectJAutoProxy

1.1 proxy-target-class

1.2 expose-proxy

1.3 AspectJAutoProxyRegistrar

二、AnnotationAwareAspectJAutoProxyCreator

2.1 AopConfigUtils

2.2 APC类型的介绍

2.3 APC 的注册

2.4 总结

一、@EnableAspectJAutoProxy

我们知道如果想要使用 Spring AOP 功能需要开启 @EnableAspectJAutoProxy 这个注解。所以程序入口就需要从这个注解开始分析。


                                                                                              (图1) 

1.1 proxy-target-class

Spring AOP 部分使用 JDK 动态代理或者 CGLIB 来为目标对象创建代理(建议尽量使用JDK 的动态代理)。

如果被代理的目标对象实现了至少一个接口,则会使用 JDK 动态代理。所有该目标类型的接口实现类都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB 代理。

如果你希望强制使用 CGLIB 代理(例如希望代理目标对象的所有方法,而不只是实现自接口的方法),那也可以。

但是需要考虑以下两个问题。

  • 无法通知( advise ) Final 方法,因为它们不能被覆写。
  • 你需要将CGLIB 二进制友行包放在classpath 下面

 

1.2 expose-proxy

有时候目标对象内部的自我调用将无法实施切面中的增强,如下示例:

public interface AService {
    public void a () ;
    public void b () ;
}
@Service
public class AServiceimpl implements AService{
    @Transactional (propagation=Propagation.REQUIRED )
    public void a () {
        this.b() ;
    }
    @Transactional (propagation=Propagation.REQUIRES_NEW)
    public void b () {
    }
}    

此处的 this 指向目标对象,因此调用 this.b() 将不会执行 b 事务切面,即不会执行事务增强。因 b() 方法的事务定义的 “ @Transactional (propagation=Propagation.REQUIRES_NEW)” 将不会生效。为了解决这个问题,我们可以将 @EnableAspectJAutoProxy(exposeProxy=true)

 

1.3 AspectJAutoProxyRegistrar

  • 由于本类在是 @Import 注解中导入的,所以开启 @EnableAspectJAutoProxy 同时也导入了 AspectJAutoProxyRegistrar 类的实例。
  • 由于本类实现了 ImportBeanDefinitionRegistrar 这个接口,所以这个类的作用就是完成 AnnotationAwareAspectJAutoProxyCreator 的注册。
  • 如果 @EnableAspectJAutoProxy 注解中配置了 proxy-target-class 或 expose-proxy,会保存到 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition 对应的属性中。例如: proxyTargetClass 或 exposeProxy

                                                                                              (图1.3.1) 

                                                                                        (图1.3.2)

二、AnnotationAwareAspectJAutoProxyCreator

在(图1) 中的代码中看到 AnnotationAwareAspectJAutoProxyCreator 的注册是在 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary 这个中进行的。

首先我们需要了解下 AopConfigUtils 这个类

  • 声明动态代理创建器(APC) 全局唯一 AUTO_PROXY_CREATOR
  • 设置三种不同的动态代理创建器(APC)优先级顺序

 

2.1 AopConfigUtils

                                                                                      (图2.1.1)

2.2 APC类型的介绍

AutoProxyCreator 简称 APC。

  • AnnotationAwareAspectJAutoProxyCreator

级别高级,用于处理以 @AspectJ 注解形式开启AOP。

  • AspectJAwareAdvisorAutoProxyCreator

级别中级,用于处理以 <aop:aspectj-autoproxy proxy-target-class="true"/> xml 配置形式开启AOP。

  • InfrastructureAdvisorAutoProxyCreator

级别初级,用于处理以 @EnableTransactionManagement 注解形式开启事务。因为事务底层也是AOP实现的。

 

2.3 APC 的注册

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary 这个方法只是做了一个封装。

重要的是它将 AnnotationAwareAspectJAutoProxyCreator.class 注册到 beanFactory 中。

                                                                                  (图2.3.1)

AopConfigUtils.registerOrEscalateApcAsRequired

  • 如果 beanFactory 全局唯一 AUTO_PROXY_CREATOR 已经存在,当遇到更高级的 AutoProxyCreator,则替换为高级的 AutoProxyCreator 并返回。
  • 如果 beanFactory 全局唯一 AUTO_PROXY_CREATOR 不存在,则将 AnnotationAwareAspectJAutoProxyCreator 通过 BeanDefinitionRegistry 对象注册到 beanFactory 中。

 

2.4 总结

到这里我们就完成了 AnnotationAwareAspectJAutoProxyCreator 动态代理创建器注册部分的源码分析。

由于Spring 创建 Bean 的过程包含注册、创建和实例化。下一遍文章我们将分析动态代理创建器(APC)。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值