【SpringBoot】SpringBoot+AOP全局打印日志(附源码)
源码
https://github.com/HelloSummer5/GlobalLogDemo
传统打日志方式
不够优雅不够美观,会造成许多日志代码冗余
@GetMapping("list")
public Result listUser(){
log.info("======进入Controller=====");
List<User> userList = userService.listUser();
log.info("======userList:{}=====", userList);
return ResponseFactory.build(userList);
}
简介
通常有两层需要加日志:controller层和service层。controller层的日志使用Log打印信息,service层的日志使用数据库记录操作日志。
实现
pom
org.springframework.boot
spring-boot-starter-aop
Controller:
package com.example.demo.controller;
import com.example.demo.common.ResponseFactory;
import com.example.demo.common.Result;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
public class TestController {@Autowired
private UserService userService;
@GetMapping("list")
public Result listUser(){
return ResponseFactory.build(userService.listUser());
}
}
Aspect类
package com.example.demo.common.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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;@Slf4j
@Aspect
@Component
public class LogAspect {@Pointcut("execution(public * com.example.demo.controller..*.*(..))")
public void log(){ }
@Before("log()")
public void doBefore(JoinPoint joinPoint){
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
log.info("<<<<<<<<<<<<<<<<<<<<<<<<");
log.info("URL : " + request.getRequestURL().toString());
log.info("HTTP_METHOD : " + request.getMethod());
log.info("IP : " + request.getRemoteAddr());
log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "ret", pointcut = "log()")
public void doAfterReturning(Object ret){
// 处理完请求,返回内容
log.info("RESPONSE : " + ret);
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>");
}
}
效果
不重要的类
- 在这我都喜欢用Result统一返回格式,具体代码见吧。
User类:
package com.example.demo.entity;
import lombok.Data;
public class User {
private String name;
private Integer age;
}
Service层:
package com.example.demo.service.impl;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;/ @ClassName UserServiceImpl @Description TODO @Auth wujinjuan @Date 2019/8/7 10:25 * @Version 1.0 /
@Slf4j
@Service
public class UserServiceImpl implements UserService {@Override
public List<User> listUser() {
List<User> userList = new ArrayList<>();
User zhangsan = new User();
zhangsan.setName("张三");
zhangsan.setAge(18);
userList.add(zhangsan);
return userList;
}
}
Result
package com.example.demo.common;
import lombok.Data;
/ @ClassName Result @Description service层开始返回Result @Auth wujinjuan @Date 2019/6/19 11:25 AM * @Version 1.0 /
@Data
public class Result {private int code;
private int count = 0;
private String msg;
private Object data;
}
返回格式工厂类:
package com.example.demo.common;
import com.example.demo.common.enums.ResultEnum;
/ @ClassName ResponseFactory @Description @Auth wujinjuan @Date 2019/6/19 11:25 AM * @Version 1.0 /
public class ResponseFactory {/** * 公共私有静态函数 * @param code * @return */
private static Result commonBuild(int code, String errmsg) {
Result result = new Result();
result.setCode(code);
if (errmsg == null || errmsg.trim().length() == 0) {
result.setMsg(ResultEnum.getMsg(code));
} else {
result.setMsg(errmsg);
}
return result;
}
/** * 指定响应码-需预先在 @ResultEnum 里定义响应码 * <pre> * { * "code":{code} * "msg":{message} * } * </pre> * @param code * @return * @see ResultEnum */
public static Result build(int code) {
Result json = commonBuild(code, ResultEnum.getMsg(code));
return json;
}
/** * 成功响应 * <p> * <pre> * { * "code":0, * "msg":"success." * } * </pre> * * @return */
public static Result build() {
Result json = commonBuild(ResultEnum.SUCCESS.getCode(), null);
return json;
}
/** * 成功响应 * <pre> * { * "code":{code} * "msg":{message} * } * </pre> * * @param data 需要返回的数据对象 * @return * @see ResultEnum */
public static Result build(Object data) {
Result json = commonBuild(ResultEnum.SUCCESS.getCode(), "请求成功");
json.setData(data);
return json;
}
/** * 自定义返回码code,构建返回数据 * * @param code * @return */
public static Result build(int code, Object data) {
Result result = commonBuild(code, null);
result.setData(data);
return result;
}
/** * 自定义返回码code,构建返回数据 * * @param code * @return */
public static Result build(int code, String msg) {
Result result = commonBuild(code, msg);
result.setData(null);
return result;
}
/** * 自定义返回码code,构建返回数据 * * @param code * @param count * @param obj * @return */
public static Result build(int code, int count, Object obj) {
Result result = commonBuild(code, null);
result.setCount(count);
result.setData(obj);
return result;
}
/** * 自定义返回码code,构建返回数据 * * @param code * @return */
public static Result build(int code, String msg, Object data) {
Result result = commonBuild(code, msg);
result.setData(data);
return result;
}
/** * 自定义返回码code,构建返回数据 * * @param code * @return */
public static Result build(int code, int count, String msg, Object data) {
Result result = commonBuild(code, msg);
result.setData(data);
result.setCount(count);
return result;
}
}
ResultEnum:
package com.example.demo.common.enums;
public enum ResultEnum {
UNKOWN_ERROR(-1,"未知错误"),
SUCCESS(0,"成功");
private Integer code;
private String msg;
ResultEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
public static String getMsg(int code) {
for (ResultEnum ele : values()) {
if(ele.getCode().equals(code)) return ele.getMsg();
}
return null;
}
}
还没有评论,来说两句吧...