【Spring学习】AOP实现日志记录
AOP知识点
AOP的核心原理
AOP中主要概念理解
AOP五种通知工作
实现AOP的三种方式
Spring里执行步骤
1、定义一个切面类Aspect
2、定义切点Pointcut
3、定义Advice通知
使用Spring实现AOP
org.aspectj aspectjweaver
import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/api/aop") public class AopUserController { @GetMapping("/getUserByName") public String name(@RequestParam("name") String name) { return "Hello:" + name; } @GetMapping("/getUserList") public ListgetUser() { List list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); return list; } }
import com.fasterxml.jackson.databind.ObjectMapper; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; 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; @Aspect @Component public class AopLog { private Logger logger = LoggerFactory.getLogger(this.getClass()); ThreadLocalstartTime = new ThreadLocal<>(); //定义切点 @Pointcut(value = "execution(* com.binlog.study.aop.controller.*.*(..))") public void aopWebLog() { } //使用环绕通知 @Around("aopWebLog()") public Object myLogger(ProceedingJoinPoint pjp) throws Throwable { startTime.set(System.currentTimeMillis()); //使用ServletRequestAttributes请求上下文获取方法更多 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String className = pjp.getSignature().getDeclaringTypeName(); String methodName = pjp.getSignature().getName(); //使用数组来获取参数 Object[] array = pjp.getArgs(); ObjectMapper mapper = new ObjectMapper(); //执行函数前打印日志 logger.info("调用前:{}:{},传递的参数为:{}", className, methodName, mapper.writeValueAsString(array)); logger.info("URL:{}", request.getRequestURL().toString()); logger.info("IP地址:{}", request.getRemoteAddr()); //调用整个目标函数执行 Object obj = pjp.proceed(); //执行函数后打印日志 logger.info("调用后:{}:{},返回值为:{}", className, methodName, mapper.writeValueAsString(obj)); logger.info("耗时:{}ms", System.currentTimeMillis() - startTime.get()); return obj; } }