spring aop的@Before,@Around,@After,@AfterReturn,@AfterThrowing执行顺序

1.AOP的基本概念

切面(Aspect) :通知和切入点共同组成了切面(aspect)。可以从注解方式来理解,代码如下。 


@aspect为类上面的注解——切面 
@pointcut(…)——切入点。为此类内一个空方法上面的注解。可以把拦截的地址表达式表示为方法签名,利于使用起来方便。 
@before@after等——通知。为此类下面的方法上面的注解。 

三者在一块组成一个切面。

连接点(Joinpoint) :程序能够应用通知的一个point,这些“point”就是连接点,例如方法被调用时、异常被抛出时等等。——可以理解为被aop拦截的类或者方法就是连接点。

通知(Advice) :通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。——可以理解为被注解有@Before等advice注解的安全校验的方法,拦截了过来的请求要做什么逻辑的校验。

切入点(Pointcut) :通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称。——可以理解为切面切向哪里?是个类或者某层的包路径。 
目标对象(Target Object) :即被通知的对象。 
AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理;反之,采用CGLIB代理。 
织入(Weaving)把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机: 
  (1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才能做到,例如AspectJ的织入编译器; 
  (2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码; 

  (3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理是使用了JDK的动态代理。

2 注解说明

2.1 @Aspect

作用是把当前类标识为一个切面供容器读取

2.2 @Before
标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有

2.3 @AfterReturning

后置增强,相当于AfterReturningAdvice,方法正常退出时执行

2.4 @AfterThrowing

异常抛出增强,相当于ThrowsAdvice

2.5 @After

final增强,不管是抛出异常或者正常退出都会执行

2.6 @Around

环绕增强,相当于MethodInterceptor

2.7 @DeclareParents

引介增强,相当于IntroductionInterceptor

3 advice(通知)注解的执行先后顺序

这里说下简单情况——针对一个方法只被一个aspect类拦截时,aspect类内部的 advice 将按照以下的顺序进行执行情况如下:

执行到核心业务方法或者类时,会先执行AOP。在aop的逻辑内,先走@Around注解的方法。然后是@Before注解的方法,然后这两个都通过了,走核心代码,核心代码走完,无论核心有没有返回值,都会走@After方法。然后如果程序无异常,正常返回就走@AfterReturn,有异常就走@AfterThrowing。

4 更多切点函数

除了execution(),Spring中还支持其他多个函数,这里列出名称和简单介绍,以方便根据需要进行更详细的查询

4.1 @annotation()

表示标注了指定注解的目标类方法

例如 @annotation(org.springframework.transaction.annotation.Transactional) 表示标注了@Transactional的方法

4.2 args()

通过目标类方法的参数类型指定切点

例如 args(String) 表示有且仅有一个String型参数的方法

4.3 @args()

通过目标类参数的对象类型是否标注了指定注解指定切点

如 @args(org.springframework.stereotype.Service) 表示有且仅有一个标注了@Service的类参数的方法

4.4 within()

通过类名指定切点

如 with(examples.chap03.Horseman) 表示Horseman的所有方法

4.5 target()

通过类名指定,同时包含所有子类

如 target(examples.chap03.Horseman)  且Elephantman extends Horseman,则两个类的所有方法都匹配

4.6 @within()

匹配标注了指定注解的类及其所有子类

如 @within(org.springframework.stereotype.Service) 给Horseman加上@Service标注,则Horseman和Elephantman 的所有方法都匹配

4.7 @target()

所有标注了指定注解的类

如 @target(org.springframework.stereotype.Service) 表示所有标注了@Service的类的所有方法

4.8 this()

大部分时候和target()相同,区别是this是在运行时生成代理类后,才判断代理类与指定的对象类型是否匹配

参考博文: 
1. 小曹学spring–基于@AspectJ和Schema的AOP  
2. 彻底征服 Spring AOP 之 理论篇  
3. 利用Spring AOP自定义注解解决日志和签名校验  
4. Spring AOP @Before @Around @After 等 advice 的执行顺序

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值