[SpringBoot] SpringBoot+AOP Global Print Log (with source code)

Source code

https://github.com/HelloSummer5/GlobalLogDemo

Traditional Logging Method

Not elegant enough, not beautiful enough, will cause a lot of log code redundancy

@GetMapping("list")
public Result listUser(){
    log.info("======Get into Controller=====");
    List<User> userList = userService.listUser();
    log.info("======userList:{}=====", userList);
    return ResponseFactory.build(userList);
}

brief introduction

Usually there are two layers that need to be logged: the controller layer and the service layer. Log s in the controller layer print information using logs, while logs in the service layer record operation logs using databases.

Realization

  • pom
<!-- AOP rely on -->
 <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());
    }
}
  • Class 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){
        // Receive the request and record the content of the request
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // Record the content of the request
        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){
        // Processing the request and returning the content
        log.info("RESPONSE : " + ret);
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>");
    }
}

Effect

Unimportant classes

  • In this case, I like to return to the format with Result. See the specific code.
  • Class User:
package com.example.demo.entity;

import lombok.Data;

public class User {
    private String name;
    private Integer age;
}
  • Service layer:
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("Zhang San");
        zhangsan.setAge(18);
        userList.add(zhangsan);
        return userList;
    }

}
  • Result
package com.example.demo.common;

import lombok.Data;

/**
 * @ClassName Result
 * @Description service Layer begins to return to 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;

}

  • Return Format Factory Class:
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 {
    /**
     * Public Private Static Functions
     * @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;
    }

    /**
     * Specify Response Codes - Define Response Codes in @ResultEnum beforehand
     * <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;
    }

    /**
     * Successful response
     * <p>
     * <pre>
     * {
     *     "code":0,
     *     "msg":"success."
     * }
     * </pre>
     *
     * @return
     */
    public static Result build() {
        Result json = commonBuild(ResultEnum.SUCCESS.getCode(), null);
        return json;
    }

    /**
     * Successful response
     * <pre>
     *     {
     *         "code":{code}
     *         "msg":{message}
     *     }
     * </pre>
     *
     * @param data Data objects to be returned
     * @return
     * @see ResultEnum
     */
    public static Result build(Object data) {
        Result json = commonBuild(ResultEnum.SUCCESS.getCode(), "Request successful");
        json.setData(data);
        return json;
    }

    /**
     * Customize return code to build return data
     *
     * @param code
     * @return
     */
    public static Result build(int code, Object data) {
        Result result = commonBuild(code, null);
        result.setData(data);
        return result;
    }

    /**
     * Customize return code to build return data
     *
     * @param code
     * @return
     */
    public static Result build(int code, String msg) {
        Result result = commonBuild(code, msg);
        result.setData(null);
        return result;
    }

    /**
     * Customize return code to build return data
     *
     * @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;
    }

    /**
     * Customize return code to build return data
     *
     * @param code
     * @return
     */
    public static Result build(int code, String msg, Object data) {
        Result result = commonBuild(code, msg);
        result.setData(data);
        return result;
    }

    /**
     * Custom return code, build return data
     *
     * @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,"unknown error"),
    SUCCESS(0,"Success");

    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;
    }
}

Keywords: JSON Lombok Java github

Added by incubi on Mon, 07 Oct 2019 21:28:39 +0300