实现AOP的切面主要有以下几个要素:
使用@Aspect注解将一个java类定义为切面类
使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。
根据需要在切入点不同位置的切入内容
使用@Before在切入点开始处切入内容
使用@After在切入点结尾处切入内容
使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
Controller 控制层
package com.example.demo.Controller;
import com.example.demo.properties.Student;
import com.example.demo.service.StudentService;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/**
*学生
*/
@RestController
@RequestMapping("/student")
public class StudentController {
@Resource
private StudentService studentService;
@RequestMapping("/add")
public String addStudent(@Valid Student student, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return bindingResult.getFieldError().getDefaultMessage();
}else{
studentService.add(student);
return "添加成功";
}
}
}
Aspect 切面
package com.example.demo.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.omg.CORBA.Object;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
@Aspect
@Component
public class RequestAspect {
private Logger logger= LoggerFactory.getLogger(RequestAspect.class);
@Pointcut("execution(public * com.example.demo.Controller.*.*(..))")
public void logPointCut() {
}
@Before("logPointCut()")
public void doBefore(JoinPoint joinPoint){
// 接收到请求,记录请求内容
ServletRequestAttributes attributes= (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request=attributes.getRequest();
// 记录下请求内容
logger.info("请求地址 : " + request.getRequestURL().toString());
logger.info("HTTP METHOD : " + request.getMethod());
logger.info("IP : " + request.getRemoteAddr());
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+ joinPoint.getSignature().getName());
logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
}
@After("logPointCut()")
public void doAfter(JoinPoint joinPoint){
logger.info("方法执行后...");
}
@AfterReturning(returning = "object",pointcut = "logPointCut()")
public void doAfterReturning(Object object){
logger.info("返回值:"+object);
}
}