这里写自定义目录标题
背景
验证 @Around、@Before、@After、@AfterReturning、@AfterThrowing 执行顺序
代码
Annotation
package com.xxx.aop;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface LogOperation {
}
Controller
package com.xxx.aop;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/testAop")
public class TestAopController {
@GetMapping("/get")
@LogOperation
public String get() {
log.info("TestAopController#get");
return "ok";
}
}
Aspect
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Slf4j
@Aspect
@Component
public class LogOperationAspect {
@Pointcut("@annotation(com.xxx.aop.LogOperation)")
private void methodAnnotation() {
}
@Around("methodAnnotation()")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
log.info("LogOperationAspect#aroundAdvice aroundBefore");
Object result = joinPoint.proceed();
log.info("LogOperationAspect#aroundAdvice aroundAfter");
long end = System.currentTimeMillis();
log.info("LogOperationAspect#aroundAdvice method:{}, cost:{} ms", method.getName(), end - start);
return result;
}
@Before("methodAnnotation()")
public void beforeAdvice(JoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogOperation annotation = method.getAnnotation(LogOperation.class);
log.info("LogOperationAspect#beforeAdvice execute");
}
@After("methodAnnotation()")
public void afterAdvice(JoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogOperation annotation = method.getAnnotation(LogOperation.class);
log.info("LogOperationAspect#afterAdvice execute");
}
@AfterReturning("methodAnnotation()")
public void afterReturningAdvice(JoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogOperation annotation = method.getAnnotation(LogOperation.class);
log.info("LogOperationAspect#afterReturningAdvice execute");
}
}
执行结果
结论
- @Around注解方法的前半部分业务逻辑
- @Before注解方法的业务逻辑
- 目标方法的业务逻辑
- @AfterThrowing(若目标方法有异常,执行@AfterThrowing注解方法的业务逻辑)
- @AfterReturning(若目标方法无异常,执行@AfterReturning注解方法的业务逻辑)
- @After(不管目标方法有无异常,都会执行@After注解方法的业务逻辑)
- @Around注解方法的后半部分业务逻辑
tips;本文未演示@AfterThrowing
注解执行顺序