Spring框架中aop的五种代理增强注解方法的区别和联系

本文介绍了Spring框架中aop的五种代理增强注解方法,包括它们的区别和联系。区别主要体现在环绕注解方法可以获取目标方法的返回值和异常信息,而其他注解方法则分别对应不同的增强时机。联系在于所有注解方法都有相同的切入点表达式,并且可以使用JoinPoint作为参数进行通用处理。

五种代理增强注解方法

//前置增强(又称前置通知):在目标方法执行之前执行
	@Before("execution(public int com.jd.calculator.CalculatorService.*(..))")
	public void before(JoinPoint joinPoint) {
		Object target=joinPoint.getTarget();
		String methodName = joinPoint.getSignature().getName();
		Object[] params = joinPoint.getArgs();
		
		System.out.println(target.getClass().getName()+":The "+methodName+" method begins.");
		System.out.println(target.getClass().getName()+":Parameters of the "+methodName+" method: ["+params[0]+","+params[1]+"]");
	}


//后置增强(又称后置通知):在目标方法执行后执行,无论目标方法运行期间是否出现异常。注意:后置增强无法获取目标方法执行结果,可以在返回增强中获取
	@After("execution(public int com.jd.calculator.CalculatorService.*(..))")
	public void after(JoinPoint joinPoint) {
		Object target=joinPoint.getTarget();
		String methodName = joinPoint.getSignature().getName();
		System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
	}


//返回增强(又称返回通知):在目标方法正常结束后执行,可以获取目标方法的执行结果
	@AfterReturning(value="execution(public int com.jd.calculator.CalculatorService.*(..))",returning="result")
	public void afterReturning(JoinPoint joinPoint,Object result) {
		Object target=joinPoint.getTarget();
		String methodName = joinPoint.getSignature().getName();
		System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
	}

//异常增强(又称异常通知):目标方法抛出异常之后执行,可以访问到异常对象,且可以指定在出现哪种异常时才执行增强代码
	@AfterThrowing(value="execution(public int com.jd.calculator.CalculatorService.*(..))",	throwing="e")
	public void afterThrowing(JoinPoint joinPoint,Exception e) {//e变量数据类型为Exception,ArithmeticException异常时Exception的子类,所以目标方法出现异常时afterThrowing方法可以执行;如果e的数据类型为NullPointerException,则目标方法出现异常后afterThrowing方法不会执行
		Object target=joinPoint.getTarget();
		String methodName = joinPoint.getSignature().getName();
		System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
	}


//环绕增强:目标方法执行前后都可以织入增强处理
	@Around("execution(public int com.jd.calculator.CalculatorService.*(..))")
	public Object around(ProceedingJoinPoint joinPoint) {
		Object result = null;
		Object target=joinPoint.getTarget();//目标对象
		String methodName = joinPoint.getSignature().getName();
		Object[] params = joinPoint.getArgs();

		try {
			try {
				//前置增强
				System.out.println(target.getClass().getName()+":The "+methodName+" method begins.");
				System.out.println(target.getClass().getName()+":Parameters of the "+methodName+" method: ["+params[0]+","+params[1]+"]");
				//执行目标对象内的方法
				result = joinPoint.proceed();
			}finally {
				//后置增强
				System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
			}
			//返回增强
			System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
		} catch (Throwable e) {
			//异常增强
			System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
		}
		
		return result;
	}
}

区别

很明显环绕注解方法相对于其他四个注解方法的第一个参数类型不同,实际上,由public abstract interface org.aspectj.lang.ProceedingJoinPoint extends org.aspectj.lang.JoinPoint很明显看出前者ProceedingJoinPoint是后者JoinPoint的子类,并且可以使用proceed()方法获取目标方法的返回值。
同时环绕方法实质上将前面四种方法前置、后置、返回、异常增强包含在内,顺序为

try {
	try {
		doBefore();// @Before注解所修饰的方法
		method.invoke();// 执行目标对象内的方法
	} finally {
		doAfter();// @After注解所修饰的方法
	}
	doAfterReturning();// @AfterReturning注解所修饰的方法
} catch (Exception e) {
	doAfterThrowing();// @AfterThrowing注解所修饰的方法
}

同时除了增强注解的名称不同外,@AfterRuturning多了参数方法的返回值参数(对应其可以获取目标方法的返回值),@AfterThrowing多了异常参数(对应其可以获取目标方法的异常信息)

注:目标方法的异常必须为@AfterThrowing的异常及其子类,否则无法获取其信息

联系

由上面实例可知,所有的增强注释都有同样的切入点公式,即execution(返回值类型 目标方法名或目标类路径加名或注释(…))
并且其方法参数joinPoint的方法

		Object target=joinPoint.getTarget();
		String methodName = joinPoint.getSignature().getName();
		Object[] params = joinPoint.getArgs();

都通用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值