最近技术部忽然刮起一阵 review 代码的小风,挨个项目组过代码,按理说这应该是件挺好的事,让他人指出本人代码中的有余,查缺补漏,对晋升本身编码能力有很大帮忙,毕竟本人审查很容易“沉醉”在本人写的代码里。

不过,代码 review 的具体水平令人发指,一行一行的剖析,几乎就是个培训班啊。不夸大的说,如果我村里仅有县重点小学学历的四大爷,来听上一个月后,保障能上手开发,666~

既然组内氛围到这了,咱也得口头起来,要不哪天评审到我的代码,让人家指指点点的心里多少有点不难受,与其被动优化代码不如主动出击~

选优化代码的方向,办法入参和返回后果日志首当其冲,每个办法都会有这两个日志,一大堆冗余的代码,而且什么样的打印格局都有,十分的芜杂。

public OrderDTO getOrder(OrderVO orderVO, String name) {        log.info("订单详情入参:orderVO={},name={}", JSON.toJSONString(orderVO), name);        OrderDTO orderInfo = orderService.getOrderInfo(orderVO);        log.info("订单详情后果:orderInfo={}", JSON.toJSONString(orderInfo));        return orderInfo;}

下边咱们利用 AOP 实现申请办法的入参、返回后果日志对立打印,防止日志打印格局芜杂,同时缩小业务代码量。

一、自定义注解

自定义切面注解@PrintlnLog 用来输入日志,注解权限 @Target({ElementType.METHOD}) 限度只在办法上应用,注解中只有一个参数 description ,用来自定义方法输入日志的形容。

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})@Documentedpublic @interface PrintlnLog {    /**     * 自定义日志形容信息文案     *     * @return     */    String description() default "";}

二、切面类

接下来编写@PrintlnLog 注解对应的切面实现,doBefore()中输入办法的自定义形容、入参、申请形式、申请url、被调用办法的地位等信息,doAround() 中打印办法返回后果。

留神: 如何想指定切面在哪个环境执行,能够用@Profile 注解,只打印某个环境的日志。

@Slf4j@Aspect@Component//@Profile({"dev"}) //只对某个环境打印日志public class LogAspect {    private static final String LINE_SEPARATOR = System.lineSeparator();    /**     * 以自定义 @PrintlnLog 注解作为切面入口     */    @Pointcut("@annotation(com.chengxy.unifiedlog.config.PrintlnLog)")    public void PrintlnLog() {    }    /**     * @param joinPoint     * @author fu     * @description 切面办法入参日志打印     * @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 --------------------------");        /**         * 打印自定义办法形容         */        log.info("Method detail Description: {}", methodDetailDescription);        /**         * 打印申请入参         */        log.info("Request Args: {}", JSON.toJSONString(joinPoint.getArgs()));        /**         * 打印申请形式         */        log.info("Request method: {}", request.getMethod());        /**         * 打印申请 url         */        log.info("Request URL: {}", request.getRequestURL().toString());        /**         * 打印调用办法全门路以及执行办法         */        log.info("Request Class and Method: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());    }    /**     * @param proceedingJoinPoint     * @author xiaofu     * @description 切面办法返回后果日志打印     * @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();        /**         * 输入后果         */        log.info("{},Response result  : {}", aspectMethodLogDescPJ, JSON.toJSONString(result));        /**         * 办法执行耗时         */        log.info("Time Consuming: {} ms", System.currentTimeMillis() - startTime);        return result;    }    /**     * @author xiaofu     * @description 切面办法执行后执行     * @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 注解作用的切面办法具体细信息     * @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 注解作用的切面办法具体细信息     * @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 自定义注解参数     * @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();    }}

三、利用

咱们在须要打印入参和返回后果日志的办法,加上@PrintlnLog注解,并增加自定义办法形容。

@RestController@RequestMappingpublic class OrderController {    @Autowired    private OrderService orderService;    @PrintlnLog(description = "订单详情Controller")    @RequestMapping("/order")    public OrderDTO getOrder(OrderVO orderVO, String name) {        OrderDTO orderInfo = orderService.getOrderInfo(orderVO);        return orderInfo;    }}

代码里去掉 log.info日志打印,加上 @PrintlnLog 看一下成果,清晰明了。

Demo GitHub地址:https://github.com/chengxy-nd...

原创不易,焚烧秀发输入内容

习惯在VX看技术文章,想要获取更多Java资源的同学,能够关注我的公众号:程序员内点事,暗号:[666]