文中转载微信公众平台「武培轩」,创作者武培轩 。转截文中请联络武培轩微信公众号。
在新项目开发设计中常常,日志系统软件是不可或缺的,尤其是智能管理系统,针对关键的实际操作都是会有实际操作日志,殊不知这一实际操作不用我们在相对的方式 中一个一个的去完成,这肯定是不适合的,那样的实际操作毫无疑问是增加了开发量,并且不容易维护保养,因此具体新项目中一直运用AOP(Aspect Oriented Programming)即朝向横切面程序编写来纪录系统软件中的实际操作日志。
下边就来详细介绍怎样在 Spring Boot 中 应用 AOP 纪录日志:
添加依靠
最先添加 AOP 依靠:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-aop</artifactId>
- </dependency>
建立日志注释类
建立一个日志注释类,那样就可以在必须纪录日志的方式 上再加上注释就可以纪录日志了,注释內容以下:
- @Target({ElementType.PARAMETER, ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface AopLogger {
- String describe() default "";
- }
配备 AOP 横切面
界定一个 AopLoggerAspect 横切面类,用 @Aspect 申明此类为横切面类。
- @Component
- public class AopLoggerAspect {
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
- @Pointcut("@annotation(com.wupx.aop.logger.annotation.AopLogger)")
- public void aopLoggerAspect() {
- }
- /**
- * 围绕开启
- *
- * @param point
- * @return
- */
- @Around("aopLoggerAspect()")
- public Object doAround(ProceedingJoinPoint point) {
- RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
- ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
- HttpServletRequest request = servletRequestAttributes.getRequest();
- Object result = null;
- long startTime = System.currentTimeMillis();
- try {
- result = point.proceed();
- } catch (Throwable throwable) {
- throwable.printStackTrace();
- logger.error(throwable.getMessage());
- }
- String describe = getAopLoggerDescribe(point);
- if (StringUtils.isBlank(describe)) {
- describe = "-";
- }
- // 复印要求有关主要参数
- logger.info("========================================== Start ==========================================");
- logger.info("Describe : {}", describe);
- // 复印要求 url
- logger.info("URL : {}", request.getRequestURL());
- logger.info("URI : {}", request.getRequestURI());
- // 复印 Http method
- logger.info("HTTP Method : {}", request.getMethod());
- // 复印启用 controller 的全途径及其实行方式
- logger.info("Class Method : {}.{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName());
- // 复印要求的 IP
- logger.info("IP : {}", request.getRemoteAddr());
- // 复印要求入参
- logger.info("Request Args : {}", point.getArgs());
- // 复印要求出参
- logger.info("Response Args : {}", result);
- logger.info("Time Consuming : {} ms", System.currentTimeMillis() - startTime);
- logger.info("=========================================== End ===========================================");
- return result;
- }
- /**
- * 获得注释中对方式 的叙述信息内容
- *
- * @param joinPoint 相切
- * @return describe
- */
- public static String getAopLoggerDescribe(JoinPoint joinPoint) {
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- Method method = signature.getMethod();
- AopLogger controllerLog = method.getAnnotation(AopLogger.class);
- return controllerLog.describe();
- }
- }
在其中 「@Pointcut」 是界定一个相切,后边追随一个关系式,关系式能够 界定为某一 package 下的方式 ,还可以是自定义注解等。
「@Around」 为在突破口前后左右织入编码,而且能够 随意的操纵什么时候实行相切。
检测
下面撰写 Controller 层来开展检测:
- @RestController
- @RequestMapping("/user")
- public class UserController {
- private final UserService userService;
- public UserController(UserService userService) {
- this.userService = userService;
- }
- @PostMapping
- @AopLogger(describe = "加上客户")
- public String addUser(@RequestBody User user) {
- UserEntity userEntity = new UserEntity();
- BeanUtils.copyProperties(user, userEntity);
- return userService.addUser(userEntity);
- }
- }
只必须在插口上填好 @AopLogger 就可以纪录实际操作日志。
运行服务项目,根据 PostMan 要求 http://localhost:8080/user 插口,輸出的日志以下所显示:
能够 见到把入参、出参及其插口信息内容都纪录了出来,是否非常简单呢,只必须简易两步就可以完成 AOP 日志,大伙儿能够 自身实践活动下。
文中的详细编码在 https://github.com/wupeixuan/SpringBoot-Learn 的 aop-logger 文件目录下。