Spring AOP 日誌切面升級版
阿新 • • 發佈:2018-12-24
上一篇Spring AOP專案應用——方法入參校驗 & 日誌橫切 介紹了 spring AOP 5切面型別及應用場景。本次結合註解使用,方便又實惠。實現如下:
封裝日誌切面
@Aspect @Component public class LogAspect { private static ILog logger = LogFactory.getLogger(LogAspect.class); @Around("execution(* com.component..*.*(..)) && @annotation(com.aspect.Log)") public Object around(ProceedingJoinPoint point) throws Throwable { Long startTime=System.currentTimeMillis(); String methodName=point.getSignature().getName(); Object[] args=point.getArgs(); String[] paramNames = ((CodeSignature) point.getSignature()).getParameterNames(); try { logger.info("[ACCESS] {}: args:{}", methodName, JSON.toJSONString(args)); Object resultValue = point.proceed(); logger.info("[END] {}: result:{} {}ms ", methodName, JSON.toJSONString(args), System.currentTimeMillis() - startTime); return resultValue; } catch (Exception e) { logger.error("", e); } return null; } }
定義切面註解類
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Log {
}
呼叫處
@Log public Result<UserDto> createTrade(UserDto UserDto) { if (UserDto == null || UserDto.getOrderId() == null || UserDto.getBusinessId() == null) { return ResultWrapper.fail(ErrorCode.PARAMETER_CANNOT_NULL); } String lockKey = Constants.USER_KEY_PREFIX + UserDto.getOrderId(); return new SimpleRedisLock().execute(lockKey, Constants.DEFAULT_LOCK_TIMEOUT, () -> { Result<UserDto> result = tradeService.createTrade(UserDto); return result; }); }
Last but not least :新增aop配置生效
<aop:aspectj-autoproxy proxy-target-class="true"/>
執行效果:方法入參、返回結果日誌如下
另外我在考慮一點,併發情況下,會不會導致日誌打串了。比如方法1的入參print完還沒print result,方法2就又把入參print出來了。導致同一方法日誌不連續,不便排查線上問題。
答案:當然不會。因為。。。spring bean 是預設單例管理噠!無狀態bean(AOP 切面類也在context容器中管理)