Spring 之通知的类型以及切面的优先级

本文介绍Spring AOP的基本概念及其实现方式,通过一个简单的加减乘除计算器示例,展示了如何使用前置通知、后置通知、返回通知、异常通知以及环绕通知等AOP特性来增强代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring AOP编程,即面向切面编程,那么什么是切面?先看下面的例子:

一个简单的加减乘除

public interface Calculate {
     int  add(int x,int y);
     int  sub(int x,int y);
     int  mul(int x,int y);
     int  div(int x,int y);
}
public class CalculateImpl implements Calculate {
	public int add(int x, int y) {
		return x+y;
	}
	public int sub(int x, int y) {
		return x-y;
	}
	public int mul(int x, int y) {
		return x*y;
	}
	public int div(int x, int y) {
		return x/y;
	}
}

如果在每次返回值之前,都要验证输入值的合法性,那么简单的实现就是在各个方法里加上相应的验证代码,这样整个方法就会显得很臃肿。并且一旦方法多了,其维护的难度也就很大了。如果还有其他业务方法,那么就更加不利于代码的维护了。

这里写图片描述

如上图,对于在很多方法都要执行的操作,我们把他们给抽离出来,如下:
这里写图片描述


Spring AOP之通知的类型:
AOP的基础是动态代理,其通知类型分为:前置通知,后置通知,返回通知,异常通知以及环绕通知。在进行aop编程的时候,需要引入相应的jar包,其对应maven的依赖为:

<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.9</version>
</dependency>

配置文件中除开启扫描外,还需加入:

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

如果是使用的注解的方式,则需要添加如下的注解:

@EnableAspectJAutoProxy

切面类的实现如下:

//切面类:
@Aspect
@Component
public class LoggingAspect {
	
	@Pointcut("execution(public * com.sg.aop.Calculate.*(..))")
	public void declarePointCut(){}
	
	  /**
	  * 前置通知
	  * @param joinpoint
	  */
	 @Before("declarePointCut()")
     public void beforeMethod(JoinPoint joinpoint){
		 String shortString = joinpoint.getSignature().toShortString();
		 Object[] args = joinpoint.getArgs();  //获取传递的参数列表
		 Object target = joinPoint.getTarget().getClass().getName();  //目标对象
         Object th= joinPoint.getThis().getClass().getName();         //被代理的对象
         String modifiers =  Modifier.toString(joinPoint.getSignature().getModifiers());  //获取修饰符的类型
		 List<Object> asList = Arrays.asList(args);
		 System.out.println("开始调用方法"+shortString+asList);
     }
	 
	 
	 /**
	  * 无论是否发生异常,后置通知一定会执行
	  * 后置通知无法获取方法的执行结果
	  * @param joinpoint
	  */
	 @After("declarePointCut()")
	 public void AfterMethod(JoinPoint joinpoint){
		 System.out.println("调用方法之后");
	 }
	 
	 /**
	  * 返回通知,可以获取方法的返回值
	  * 只有在方法没有异常的时候,才会调用
	  * @param joinpoint
	  * @param result
	  */
	 @AfterReturning(value="declarePointCut()",returning="result")
	 public void AfterReturning(JoinPoint joinpoint,Object result){
		 System.out.println("方法的返回值为:"+result);
	 }
	 
	 /**
	  * 异常通知
	  * 其中Exception为异常的类型,意味发生此类异常的时候,才会进行捕捉
	  * @param joint
	  * @param e
	  * @return
	  */
	 @AfterThrowing(value="declarePointCut()",throwing="e")
	 public Object AfterThrowing(JoinPoint joint,Exception e){
		 System.out.println("发生了异常");
		 return e;
	 }
	 
	 @Around(value = "declarePointCut()")
	 public Object AroundAOP(ProceedingJoinPoint proceding){
		 Object proceed=null;
		 try {
			 System.out.println("before");
			 proceed= proceding.proceed();
			 System.out.println("after");
		} catch (Throwable e) {
			e.printStackTrace();
			System.out.println("exception");
		}
		 System.out.println("returing");
		 return proceed;
	 } 
}

对于不同的切面的优先级,需要在相应的类上加上order注解,数字越小,优先级越高。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值