导入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
业务代码部分
@RestController
public class TestController {
@GetMapping("/hi")
public String sayHi(String name){
System.out.println("hi " + name);
return name;
}
}
声明切面类
@Component
//将该类声明为日志切面
@Aspect
public class LogAspect {
//声明方法为前置通知
@Before("execution(* com.aop.TestController.sayHi(..))")
//@Before("execution( * com.aop.TestController.*(..))") 表示对TestController类下的所有方法起作用
public void beforeMethod(JoinPoint joinPoint) {
//获取方法名
String methodName = joinPoint.getSignature().getName();
//获取参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("the method "+methodName+" begin with"+args);
}
//后置通知(无论方法是否出现异常均要执行)
//无法在后置通知中获取返回值
@After("execution(* com.aop.TestController.sayHi(..))")
public void afterMethod() {
System.out.println("method end");
}
//返回通知
//正常执行完毕后可获取到返回值
@AfterReturning(value = "execution(* com.aop.TestController.sayHi(..))",returning = "ret")
public void afterReturningMethod(Object ret) {
System.out.println("ret = " +ret);
}
/*
补充:
切面优先级:
当多个切面类同时作用于一个方法时,可以使用注解 @Order(1)修饰切面类,指定其优先级,值越小优先级越高。
@Component
@Aspect
@Order(1)
public class LogAspect {..}
切入点表达式的重用:
声明一个方法:
@Pointcut("execution(* com.aop.TestController.sayHi(..))")
public void pointcuts(){//什么都不用写}
使用方法:
@Before("pointcuts()")
public void beforeMethod(JoinPoint joinPoint) {..}
*/
}
测试
浏览器访问:http://127.0.0.1:8080/hi?name=kohen
打印结果:
the method sayHi begin with[kohen]
hi kohen
method end
ret = kohen