spring-aop使用记录

spring里,切面通知总共分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)和环绕通知(Around)五种。我自己写了个例子,了解了下它的原理

1.首先是具体执行的方法:

@Service
public class HelloService {

    public String sayHello(String content){
        System.out.println("HelloService: "+content);
        // if(true) throw new RuntimeException("test");
        return "return content: " + content;
    }
}

2.切面代码:

@Aspect
@Component
public class TestAspect {

    @Pointcut("execution(* cn.ye.service..*(..))")
    public void pointcut(){}

    @Before(value = "pointcut() && args(param)", argNames = "joinPoint,param")
    public void before(JoinPoint joinPoint, String param){
        System.out.println("2 before....");
        System.out.println("param:" + param);
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("1 around before....");
        Object result = joinPoint.proceed();
        System.out.println("3 around after....");
        return result;
    }

    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        System.out.println("4 after...");
    }

    @AfterReturning(value = "pointcut()", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue){
        System.out.println("5 afterReturning...");
        System.out.println("return value: " + returnValue);
    }

    @AfterThrowing(value = "pointcut()", throwing = "ex")
    public void afterThrowing(Exception ex){
        System.out.println("5 after Throwing..." + ex);
    }
}

3. 如果正常执行,则结果为:

1 around before....
2 before....
param:Ye
HelloService: Ye
3 around after....
4 after...
5 afterReturning... //如果抛异常,则本步骤输出 5 after Throwing...java.lang.RuntimeException: test

从上面的结果可以看出,执行的顺序为 around前置逻辑-> before-> 具体逻辑-> around后置逻辑-> after-> afterReturning/afterThrowing

4.接下来可以分析下具体的通知:

  • before通知-AspectJMethodBeforeAdvice,从代码可以看出该通知只是执行前置拦截,除非抛出异常,否则不会导致提前返回

  • around通知-AspectJAroundAdvice,可以执行前置后置拦截,可以取到返回值

  • after通知-AfterReturningAdviceInterceptor->AspectJAfterAdvice,方法执行后在finally中执行,获取不到返回值

  • afterReturing通知-AfterReturningAdviceInterceptor->AspectJAfterReturningAdvice,可以取到返回值

  • afterThrowing通知-AspectJAfterThrowingAdvice,当出现异常的时候可以取到异常对象,但不影响异常的抛出

 

 5.综上,可以看出:

  • before和after通知都是在方法执行前后添加处理逻辑,如果不抛异常是不会影响程序执行逻辑的
  • around和afterReturning通知可以取到返回值,其中around通知可以让程序提前返回
  • aroundThrowing通知可以获取到程序执行中抛出的异常,但这里捕获异常不会对程序逻辑有影响

 

posted @ 2019-05-09 16:05  ye213  阅读(290)  评论(0编辑  收藏  举报