Недавно технический отдел внезапно взорвался на некоторое время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
Реализуйте унифицированную печать входных параметров и возвращайте журналы результатов метода запроса, избегайте загроможденного формата печати журнала и сократите объем бизнес-кода.
1. Пользовательские аннотации
Пользовательская аннотация аспекта@PrintlnLog
Используется для вывода журналов, аннотирования разрешений@Target({ElementType.METHOD})
Ограничение применяется только к методам, а в аннотации только один параметрdescription
, который используется для настройки описания журнала вывода метода.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @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();
}
}
3. Применение
Нам нужно распечатать входные параметры и вернуть метод журнала результатов, плюс@PrintlnLog
аннотацию и добавьте описание пользовательского метода.
@RestController
@RequestMapping
public 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-nds/Springboot-Notebook/tree/master/springboot-aop-unifiedlog
Оригинальность не так проста, сжигание волос на выходе, если есть потеря, пожалуйста, дайте лайк, чтобы поощрить это!
Разобраны и розданы друзьям сотни различных технических электронных книг. Подпишитесь на официальный аккаунт, чтобы ответить [666], чтобы получить его самостоятельно. Мы создали группу технического обмена с друзьями, чтобы обсуждать технологии и делиться технической информацией, стремясь вместе учиться и развиваться. Если вам интересно, присоединяйтесь к нам!