目录
官方文档:7. Aspect Oriented Programming with Spring
spring aop像一个拦截器,可以对被拦截的方法(join point)做增强处理,而且对连接点无代码入侵。在使用aop编程时,先分析业务以便定义PointCut,然后定义切面类和advice。示例如下:
连接点所在的类:
package com.example.demo.aopdemo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return "hello " + name;
}
}
切面类:
package com.example.demo.aopdemo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
@Aspect
@Component
public class HelloAspect {
// 定义切点,切点是joinpoint集合,每个joinpoint是一个被切面拦截的方法
@Pointcut(value = "execution( * com.example.demo.aopdemo.HelloController.*(..))")
public void helloPointCut() {
}
@Around("helloPointCut()")
public Object aroundHello(ProceedingJoinPoint pjp) throws Throwable {
String className = pjp.getTarget().getClass().toString();
String methodName = pjp.getSignature().getName();
Object[] parameters = pjp.getArgs();
ObjectMapper mapper = new ObjectMapper();
System.out.println("调用前:" + className + "." + methodName + "传递的参数为" + mapper.writeValueAsString(parameters));
Object obj = pjp.proceed();
System.out.println("调用后 :" + className + "." + methodName + "返回值" + mapper.writeValueAsString(obj));
return obj;
}
// 前置通知, 在方法执行之前执行
@Before("helloPointCut()")
public void beforeHello() {
System.out.println("beforeHello");
}
// 后置通知, 在方法执行之后执行
@After("helloPointCut()")
public void afterHello() {
System.out.println("afterHello");
}
// 返回通知, 在方法返回结果之后执行
@AfterReturning(pointcut = "helloPointCut()", returning = "result")
public void afterReturnHello(Object result) {
System.out.println("afterHelloreturn:" + result.toString());
}
// 异常通知, 在方法抛出异常之后
@AfterThrowing(pointcut = "helloPointCut()", throwing = "ex")
public void AfterThrowingHello(Exception ex) {
System.out.println("AfterThrowingHello" + ex.getMessage());
}
}