基于注解的AOP(下篇)

Spring发展到现在,基本上能用XML的配置,注解也是可以做到的。回顾下上篇的标签aop:aspectaop:pointcut aop:beforeaop:after-returningaop:after-throwingaop:afteraop:around如果使用注解的该怎么写?

前置、后置、异常、最终通知

/**
 * @Aspect表示是切面,等同于XML中aop:aspect标签
 */
// @EnableAspectJAutoProxy
@Aspect
@Component
public class Logger {

	/**
	 * 切点表达式,对应XML种aop:pointcut标签
	 */
	@Pointcut("execution(* com.youngledo.service.impl.CustomerServiceImpl.*(..))")
	private void pointcut() {}

	/**
	 * pointcut()是上面切点表达式的方法签名,必须这么写
	 */
	@Before("pointcut()")
	public void beforeInfo(JoinPoint joinPoint) {
		System.out.println("前置通知:信息开始");
	}

	@AfterReturning("pointcut()")
	public void afterReturningInfo() {
		System.out.println("返回通知:信息开始");
	}

	@AfterThrowing(value = "pointcut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
		System.out.println("异常通知:信息开始");
	}

	@After("pointcut()")
	public void afterFinallyInfo() {
		System.out.println("最终通知:信息开始");
	}
}

  1. 执行后正常情况下分别输出:
    前置通知:信息开始
    最终通知:信息开始
    返回通知:信息开始
    

这个结果是没有问题的,之所以有人说:“为什么最终通知返回通知之前执行呢?”这个还是因为Spring框架把返回通知放在了最后执行,即finally后面。那再看下异常情况下,又是什么样的执行顺序呢?

  1. 执行后异常情况下分别输出:
    前置通知:信息开始
    最终通知:信息开始
    异常通知:信息开始
    

有没有发现异常通知也是在最终通知之后执行,按照常理应该是在catch块种执行才对吧,能解释得通得伙伴留个言。

环绕通知

上面只说了4种类型的通知,就剩最强大的aop:around通知了。

@Aspect
@Component
public class Logger {

	/**
	 * 切点表达式
	 */
	@Pointcut("execution(* com.youngledo.service.impl.CustomerServiceImpl.*(..))")
	private void pointcut() {}

	/**
	 * @param pjp 该参数是Spring框架为我们封装的代理对象,使用该对象的proceed方法可以调用被代理对象的方法。
	 * 因此我们可以根据自己实际业务在该方法之前、之后、异常、最终(finally)的时候来增加功能。
	 */
	@Around("pointcut()")
	public Object aroundInfo(ProceedingJoinPoint pjp) {
		System.out.println("前置");
		try {
			// 调用被代理对象的方法,获取返回值
			Object result = pjp.proceed();
		} catch(Throwable t) {
			System.out.println("异常");
		} finally {
			System.out.println("最终");
		}
		System.out.println("后置");
 		return result;
	}
}

可以看出环绕通知得灵活性更高,因此我们一般使用该通知来实现。

注意点

再梳理下XML标签与注解得对应关系

XML标签注解解释
aop:config@EnableAspectJAutoProxy开启AOP自动代理
aop:aspect@Aspect切面
aop:pointcut@Pointcut切点表达式
aop:before@Before前置通知
aop:after-returning@AfterReturning返回通知
aop:after-throwing@AfterThrowing异常通知
aop:after@After最终通知
aop:around@Around环绕通知

需要注意的是@EnableAspectJAutoProxy是必须的,如果没配置AOP不生效,或者在XML中配置<aop:aspectj-autoproxy />。并且该注解一般放在统一配置类上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

养-乐多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值