SpringAOP & Mybatis-plus & SpringBoot 整合
依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${user.agent.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
aspectj 文件夹
@Aspect
@Component
@Slf4j
public class AopLog {
@Autowired
private LogUserMapper logUserMapper;
private static final ThreadLocal<Date> DATE_THREAD_LOCAL = new ThreadLocal<>();
@Pointcut("execution(public * com.demo.controller.*Controller.*(..))")
public void log() {
}
@Around("log()")
public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
DATE_THREAD_LOCAL.set (new Date ());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
long startTime = System.currentTimeMillis();
Object result = point.proceed();
String header = request.getHeader("User-Agent");
UserAgent userAgent = UserAgent.parseUserAgentString(header);
final LogUser l = LogUser.builder()
.threadId(Long.toString(Thread.currentThread().getId()))
.threadName(Thread.currentThread().getName())
.ip(getIp(request))
.url(request.getRequestURL().toString())
.beginTime(DATE_THREAD_LOCAL.get ())
.endTime(new Date ())
.classMethod(String.format("%s.%s", point.getSignature().getDeclaringTypeName(),
point.getSignature().getName()))
.httpMethod(request.getMethod())
.requestParams(new ObjectMapper ().writeValueAsString (getNameAndValue(point)))
.result(new ObjectMapper ().writeValueAsString (result))
.timeCost(System.currentTimeMillis() - startTime)
.userAgent(header)
.browser(userAgent.getBrowser().toString())
.os(userAgent.getOperatingSystem().toString()).build();
addUser(l);
log.info ("0-----------------------0",DATE_THREAD_LOCAL.get ());
log.info("Request LogUser Info : {}", JSONUtil.toJsonStr(l));
return result;
}
@Transactional(value = "Exception.class")
void addUser(LogUser logUser){
logUserMapper.insert (logUser);
}
private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
final Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
final String[] names = methodSignature.getParameterNames();
final Object[] args = joinPoint.getArgs();
if (ArrayUtil.isEmpty(names) || ArrayUtil.isEmpty(args)) {
return Collections.emptyMap();
}
if (names.length != args.length) {
log.warn("{}方法参数名和参数值数量不一致", methodSignature.getName());
return Collections.emptyMap();
}
Map<String, Object> map = Maps.newHashMap();
for (int i = 0; i < names.length; i++) {
map.put(names[i], args[i]);
}
return map;
}
private static final String UNKNOWN = "unknown";
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
String comma = ",";
String localhost = "127.0.0.1";
if (ip.contains(comma)) {
ip = ip.split(",")[0];
}
if (localhost.equals(ip)) {
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.error(e.getMessage(), e);
}
}
return ip;
}
}
pojo 文件夹
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "logUser")
public class LogUser implements Serializable {
private String threadId;
private String threadName;
private String ip;
private String url;
private String httpMethod;
private String classMethod;
private String requestParams;
private String result;
private Long timeCost;
private String os;
private String browser;
private String userAgent;
private Date beginTime;
private Date endTime;
}
controller文件夹
@Slf4j
@RestController
public class TestController {
@GetMapping("/demo")
public String testDemo() {
return "demo";
}
@GetMapping("/test")
public Dict test(String who) {
return Dict.create().set("who", StrUtil.isBlank(who) ? "URL" : who);
}
@PostMapping("/testJson")
public Dict testJson(@RequestBody Map<String, Object> map) {
final String jsonStr = JSONUtil.toJsonStr(map);
log.info(jsonStr);
return Dict.create().set("json", map);
}
}
测试结果
测试一

测试二

点点关注