【SpringBoot】SpringBoot+AOP全局打印日志(附源码)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【SpringBoot】SpringBoot+AOP全局打印日志(附源码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6571字,纯文字阅读大概需要10分钟。
内容图文
源码
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
<!-- AOP依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 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;
}
}
内容总结
以上是互联网集市为您收集整理的【SpringBoot】SpringBoot+AOP全局打印日志(附源码)全部内容,希望文章能够帮你解决【SpringBoot】SpringBoot+AOP全局打印日志(附源码)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。