Spring AOP 简析

Posted lispppppppp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP 简析相关的知识,希望对你有一定的参考价值。

 本文简单的分析了Spring AOP,最初是本人内部培训时使用。虽然用词不严谨,但相信对刚刚接触AOP的人会有一定帮助。

一. AOP的本质——源代码再加工

       在很多业务场景中都会涉及到事务,我们希望涉及事务的代码能抽取出来,而不是散落在代码的各个角落。

       我们通过以下方式来解决这个问题:

       1. 在每个需要事务的位置做一个标记,比如 @Transactional

       2. 在打包应用之前,先将源代码喂给 “源代码再加工器”

       3. “源代码再加工器” 将输入的源代码作为普通的文本处理,扫描发现@Transactional标记后,直接将该标记替换为 beginTransaction commit等事务相关代码

       4. 将“源代码再加工器”输出的文本文件当作源代码进行编译打包

      Spring AOP的思路就可以简单理解为以上4步,其本质就是“源代码再加工”, 虽然具体方式和上面有所不同,但思路是完全一样的。 

二. 使用AOP

      上文已经说明AOP的本质是“源代码再加工”, 那么使用AOP就只要关心2个问题: 在什么位置进行再加工? 进行什么样的再加工?

       1. 指定再加工的位置

              指定再加工的位置分为2层,第一层叫做Joinpoint, 表示AOP能够支持的位置,比如方法调用处,静态代码初始化块处等。

              第二层叫做Pointcut 用于在Joinpoint限定的范围之内,选出用户感兴趣的点。Pointcut用类似正则表达式的方式来表示。

       2. 指定进行什么样的再加工

              AOP支持的再加工方式有2种,第一种叫做Advice,作用再方法调用层面。比如可以实现在方法调用之前执行某些操作。

              第二种叫做Introduction,作用在类层面,可以让已经存在的类实现一个新的接口。比如:已经存在类叫做OldClass,新接口叫做NewInterface,新接口的实现类叫做DefaultImplementation。

              读者可以简单的将Introduction理解为: 将DefaultImplementation中的接口实现代码复制到OldClass中,并在OldClass的类声明中加上implements NewInterface.

       最后还有一个概念叫做Aspect,用于把上面提到的概念放到一起。Aspect本身没有意义,仅仅是作为一个容器存在。

        总结: 使用AOP时,只要用Pointcut指定再加工位置,用Advice或Introduction指定加工内容,最后把他们放到容器Aspect中。

三. 实现AOP

      AOP的实现有两种方式:

          1. 运行时代理: 在程序运行时,通过生成代理实现 

          2. load-time weaving: 需要使用专门的编译器,在编译期完成源代码的再加工

      这里以Spring的事务为例,分析第一种实现

       1. spring 内部会把一个Pointcut和一个Advice放在一起,组成Advisor

       2. <tx:annotation-driven> 标签会注册 InfrastructureAdvisorAutoProxyCreator这个BeanPostProcessor

       3. InfrastructureAdvisorAutoProxyCreator会获取到所有的Advisor,然后再postProcessBeforeInitialization方法中判断bean是否满足Pointcut指定的条件。

           如果满足,则对当前bean应用Advice, 生成代理并替代原始的bean;不满足则跳过

       4. 这样就实现了通过代理植入一些额外的代码,也就实现了源代码再加工

 

以上是关于Spring AOP 简析的主要内容,如果未能解决你的问题,请参考以下文章

spring代理简析

简析Spring MVC 数据解析

spring boot 运行流程简析

spring boot 运行流程简析

spring security使用和原理简析

spring security使用和原理简析