1. 程式人生 > >Spring AOP 日誌切面升級版

Spring AOP 日誌切面升級版

上一篇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容器中管理)