spring Aop通知遇到的问题Springboot 版本问题

**

spring Aop通知执行顺序问题

今天在测试spring Aop日志通知发现SpringBoot 2.3.0版本的通知和2.3.2版本的通知执行顺序不一样简单来说一下
在这里插入图片描述

springboot2.3.0版本

这个图是我了解的执行的顺序,也是2.3.0版本的执行过程

在这里插入图片描述
这个是导入的包的版本

@Component
@Aspect
public class SysTimeAspect {

	@Pointcut("bean(sysUserServiceImpl)")
	public void doTime(){}
	@Before("doTime()")
	public void doBefore(JoinPoint jp){
		System.out.println("time doBefore()");
	}
	@After("doTime()")
	public void doAfter(){
		System.out.println("time doAfter()");
	}
	/**核心业务正常结束时执行* 说明:假如有after,先执行after,再执行returning*/
	@AfterReturning("doTime()")
	public void doAfterReturning(){
		System.out.println("time doAfterReturning");
	}

	/**核心业务出现异常时执行说明:假如有after,先执行after,再执行Throwing*/
	@AfterThrowing("doTime()")
	public void doAfterThrowing(){
		System.out.println("time doAfterThrowing");
	}
	@Around("doTime()")
	public Object doAround(ProceedingJoinPoint jp)
			throws Throwable{
		System.out.println("doAround.before");
		try{
			Object obj=jp.proceed();
			System.out.println("doAround.after");
			return obj;
		}catch(Throwable e){
			System.out.println(e.getMessage());
			throw e;
		}
	}
}

这里写了一个测试运行结果如下
在这里插入图片描述

这里的执行顺序是先执行@Around注解的方法,在连接点方法jp.proceed()执行之前输出doAround.before然后在执行@Before注解的方法,输出time doBefore(),然后执行连接点方法jp.proceed(),方法成功运行后继续执行@Around注解的方法里还未走完的代码,输出doAround.after,再执行@After注解的方法,输出time doAfter(),最后在执行@AfterReturning的方法,输出time doAfterReturning。如果要是连接点方法**jp.proceed()**出现异常则执行@AfterThrowing注解的方法。

springboot2.3.2版本

可是当我改成2.3.2版本时在这里插入图片描述
输出结果
在这里插入图片描述
在springboot2.3.2版本里是在连接点方法**jp.proceed()**执行成功后,先执行@AfterReturning下的方法,在执行@After下的方法,最后在输出的doAround.after
在这里插入图片描述
最后顺便说一下切入点表达式的增强

Spring中通过切入点表达式定义具体切入点,其常用AOP切入点表达式定义及说明:
表-1 Spring AOP 中切入点表达式说明

指示符作用
bean用于匹配指定bean对象的所有方法
within用于匹配指定包下所有类内的所有方法
execution用于按指定语法规则匹配到具体方法
@annotation用于匹配指定注解修饰的方法

bean表达式

bean表达式一般应用于类级别,实现粗粒度的切入点定义,案例分析:

  1. bean(“userServiceImpl”)指定一个userServiceImpl类中所有方法。
  2. bean("*ServiceImpl")指定所有后缀为ServiceImpl的类中所有方法。
  3. 说明:bean表达式内部的对象是由spring容器管理的一个bean对象,表达式内部的名字应该是spring容器中某个bean的name。

within表达式

within表达式应用于类级别,实现粗粒度的切入点表达式定义,案例分析:

  1. within(“aop.service.UserServiceImpl”)指定当前包中这个类内部的所有方法。
  2. within(“aop.service.*”) 指定当前目录下的所有类的所有方法。
  3. within(“aop.service…*”) 指定当前目录以及子目录中类的所有方法。
  4. within表达式应用场景分析:
    1)对所有业务bean都要进行功能增强,但是bean名字又没有规则。
    2)按业务模块(不同包下的业务)对bean对象进行业务功能增强。

execution表达式

execution表达式应用于方法级别,实现细粒度的切入点表达式定义,案例分析:

  1. 语法:execution(返回值类型 包名.类名.方法名(参数列表))。
  2. execution(void aop.service.UserServiceImpl.addUser())匹配addUser方法。
  3. execution(void aop.service.PersonServiceImpl.addUser(String))
    方法参数必须为String的addUser方法。
  4. execution(* aop.service….(…)) 万能配置。

@annotation表达式

@annotaion表达式应用于方法级别,实现细粒度的切入点表达式定义,案例分析

  1. @annotation(anno.RequiredLog) 匹配有此注解描述的方法。
  2. @annotation(anno.RequiredCache) 匹配有此注解描述的方法。
    其中:RequiredLog为我们自己定义的注解,当我们使用@RequiredLog注解修饰业务层方法时,系统底层会在执行此方法时进行日扩展操作。

**
总结一下aop:在不改变原有代码的条件下,对功能进行扩展.
专业术语:
切面(aspect): 横切面对象,一般为一个具体类对象(可以借助@Aspect声明)。
通知(Advice):在切面的某个特定连接点上执行的动作(扩展功能),例如around,before,after等。
连接点(joinpoint):程序执行过程中某个特定的点,一般指向被拦截到的目标方法。
切入点(pointcut):对多个连接点(Joinpoint)一种定义,一般可以理解为多个连接点的集合。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值