Springboot使用AOP记日志
项目架构
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件application.properties
server.port=80
server.servlet.context-path=/api
spring.jackson.default-property-inclusion=non_null
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false
启动类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
切面Aspect
ControllerLogAspect.java
package com.example.demo.aspect;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.example.demo.service.LogService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Aspect
@Component
public class ControllerLogAspect {
@Autowired
LogService logService;
@Pointcut("execution(* com.example.demo.controller..*.*(..))")
public void logController() {
}
@AfterReturning(returning = "result", pointcut = "logController()")
public void doAfterReturning(Object result) throws Throwable {
log.info("记正常日志到日志文件 {}", result.toString());
logService.insertLog(result);
}
}
ExceptionLogAspect.java
package com.example.demo.aspect;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.example.demo.service.LogService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Aspect
@Component
public class ExceptionLogAspect {
@Autowired
LogService logService;
@Pointcut("execution(* com.example.demo.exception..*.*(..))")
public void logException() {
}
@AfterReturning(returning = "result", pointcut = "logException()")
public void doAfterReturning(Object result) throws Throwable {
log.info("记异常日志到日志文件 {}", result.toString());
logService.insertLog(result);
}
}
控制器Controller
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.Result;
@RestController
@RequestMapping("test")
public class TestController {
@RequestMapping("1")
public @ResponseBody Result test1() {
return new Result(200, "OK", null);
}
@RequestMapping("2")
public @ResponseBody Result test2() {
return new Result(200, "OK", null);
}
}
实体类Entity
package com.example.demo.entity;
import java.text.SimpleDateFormat;
import java.util.UUID;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class Result {
private String id;
private int code;
private String message;
private String timestamp;
private Object data;
public Result() {
super();
this.id = UUID.randomUUID().toString();
this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(System.currentTimeMillis());
}
public Result(int code, String message, Object data) {
super();
this.id = UUID.randomUUID().toString();
this.code = code;
this.message = message;
this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(System.currentTimeMillis());
this.data = data;
}
public Result(String id, int code, String message, String timestamp, Object data) {
super();
this.id = id == null ? UUID.randomUUID().toString() : id;
this.code = code;
this.message = message;
this.timestamp = timestamp == null
? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(System.currentTimeMillis())
: timestamp;
this.data = data;
}
}
全局异常处理Exception
package com.example.demo.exception;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.demo.entity.Result;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
log.error("内部错误", e);
return new Result(500, "Internal Server Error", null);
}
}
接口Service
package com.example.demo.service;
public interface LogService {
void insertLog(Object result);
}
package com.example.demo.service.impl;
import org.springframework.stereotype.Service;
import com.example.demo.service.LogService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class LogServiceImpl implements LogService {
@Override
public void insertLog(Object result) {
log.info("记日志到数据库 {}", result.toString());
}
}