There’s been a flurry in the tech department latelyreviewIn theory, it should be a good thing to have others point out the shortcomings of your code and make up for them. After all, it is easy to review your own code.”revel“In the code I wrote.

However, the level of detail in code review is mind-boggling, and the line by line analysis is a training course. No exaggeration to say, if my village only county key primary school education of the four uncle, to listen to a month after the guarantee can start development, 666~

Since the atmosphere in the group to this, WE also have to act, or one day to review my code, let others point a little bit uncomfortable in the heart, rather than passively optimize the code to take the initiative ~

Choose the direction of optimization code, method entry and return result log first, each method will have these two logs, a lot of redundant code, and any print format, very messy.

public OrderDTO getOrder(OrderVO orderVO, String name) {



        log.info(Order details entry: orderVO={},name={}".JSON.toJSONString(orderVO), name);



        OrderDTO orderInfo = orderService.getOrderInfo(orderVO);



        log.info("Order details result: orderInfo={}".JSON.toJSONString(orderInfo));



        return orderInfo;

}

Copy the code

Below, we use AOP to realize the unified printing of the entry parameter of the request method and the return result log, avoiding the clutter of the log printing format and reducing the amount of business code.

1. Custom annotations

The @target ({elementType.method}) annotation limits use only on methods. There is only one parameter in the annotation, description, which is a description of the output log from the defined METHOD.

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD})

@Documented

public @interface PrintlnLog {



    / * *

* Customize log description copywriting

     *

     * @return

* /


    String description() default "";

}

Copy the code

Two, section class

Next, write the section implementation corresponding to the @printlnlog annotation. In doBefore(), print the custom description of the method, input parameters, request method, request URL, and the location of the called method, and in doAround(), print the return result of the method.

Note: To specify the environment in which the slice is performed, you can use the @profile annotation to print only the logs for that environment.

@Slf4j

@Aspect

@Component

// @profile ({"dev"}) // Logs are generated only for one environment

public class LogAspect {



    private static final String LINE_SEPARATOR = System.lineSeparator();



    / * *

* Use the custom @printlnlog annotation as a facet entry

* /


    @Pointcut("@annotation(com.chengxy.unifiedlog.config.PrintlnLog)")

    public void PrintlnLog() {

    }



    / * *

     * @param joinPoint

     * @author fu

* @description Section method entry log print

     * @date 2020/7/15 10:30

* /


    @Before("PrintlnLog()")

    public void doBefore(JoinPoint joinPoint) throws Throwable {



        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();



        String methodDetailDescription = this.getAspectMethodLogDescJP(joinPoint);



        log.info("------------------------------- start --------------------------");

        / * *

* Prints custom method descriptions

* /


        log.info("Method detail Description: {}", methodDetailDescription);

        / * *

* Print request input parameters

* /


        log.info("Request Args: {}".JSON.toJSONString(joinPoint.getArgs()));

        / * *

* Print request mode

* /


        log.info("Request method: {}", request.getMethod());

        / * *

* Prints the request URL

* /


        log.info("Request URL: {}", request.getRequestURL().toString());



        / * *

Print the full path of the calling method and the execution method

* /


        log.info("Request Class and Method: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());

    }



    / * *

     * @param proceedingJoinPoint

     * @author xiaofu

* @description Section method returns result log print

     * @date 2020/7/15 10:32

* /


    @Around("PrintlnLog()")

    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {



        String aspectMethodLogDescPJ = getAspectMethodLogDescPJ(proceedingJoinPoint);



        long startTime = System.currentTimeMillis();



        Object result = proceedingJoinPoint.proceed();

        / * *

* Output results

* /


        log.info({}, Response result: {}", aspectMethodLogDescPJ, JSON.toJSONString(result));



        / * *

* Method execution time

* /


        log.info("Time Consuming: {} ms", System.currentTimeMillis() - startTime);



        return result;

    }



    / * *

     * @author xiaofu

* @description section method is executed after execution

     * @date 2020/7/15 10:31

* /


    @After("PrintlnLog()")

    public void doAfter(JoinPoint joinPoint) throws Throwable {

        log.info("------------------------------- End --------------------------" + LINE_SEPARATOR);

    }



    / * *

     * @param joinPoint

     * @author xiaofu

* @description@printlnlog Specifies the details of the section method used by the annotation

     * @date 2020/7/15 10:34

* /


    public String getAspectMethodLogDescJP(JoinPoint joinPoint) throws Exception {

        String targetName = joinPoint.getTarget().getClass().getName();

        String methodName = joinPoint.getSignature().getName();

        Object[] arguments = joinPoint.getArgs();

        return getAspectMethodLogDesc(targetName, methodName, arguments);

    }



    / * *

     * @param proceedingJoinPoint

     * @author xiaofu

* @description@printlnlog Specifies the details of the section method used by the annotation

     * @date 2020/7/15 10:34

* /


    public String getAspectMethodLogDescPJ(ProceedingJoinPoint proceedingJoinPoint) throws Exception {

        String targetName = proceedingJoinPoint.getTarget().getClass().getName();

        String methodName = proceedingJoinPoint.getSignature().getName();

        Object[] arguments = proceedingJoinPoint.getArgs();

        return getAspectMethodLogDesc(targetName, methodName, arguments);

    }



    / * *

     * @param targetName

     * @param methodName

     * @param arguments

     * @author xiaofu

* @description custom annotation parameters

     * @date 2020/7/15 11:51

* /


    public String getAspectMethodLogDesc(String targetName, String methodName, Object[] arguments) throws Exception {

        Class targetClass = Class.forName(targetName);

        Method[] methods = targetClass.getMethods();

        StringBuilder description = new StringBuilder("");

        for (Method method : methods) {

            if (method.getName().equals(methodName)) {

                Class[] clazzs = method.getParameterTypes();

                if (clazzs.length == arguments.length) {

                    description.append(method.getAnnotation(PrintlnLog.class).description());

                    break;

                }

            }

        }

        return description.toString();

    }

}

Copy the code

Three, the application

We annotate @printlnlog and add custom method descriptions for methods that need to print input arguments and return result logs.

@RestController

@RequestMapping

public class OrderController {



    @Autowired

    private OrderService orderService;



    @PrintlnLog(description = "Order Detail Controller")

    @RequestMapping("/order")

    public OrderDTO getOrder(OrderVO orderVO, String name) {



        OrderDTO orderInfo = orderService.getOrderInfo(orderVO);



        return orderInfo;

    }

}

Copy the code

Remove it from the codelog.infoLog print, plus@PrintlnLogIf you look at the effect, it’s clear. Demo GitHubAddress: https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-aop-unifiedlog

Original is not easy, burning hair output content, if there is a lost harvest, a praise to encourage it!

I sorted out hundreds of technical e-books and gave them to my friends. Pay attention to the public number reply [666] to get yourself. I set up a technology exchange group with some friends to discuss technology and share technical information, aiming to learn and progress together. If you are interested, please join us!