自定义注解

203 阅读1分钟

自定义注解

定义使用在方法上的注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";

    String converseMark() default "defaultConverseMark";

    /**
     * 是否启用
     *
     * @return
     */
    boolean enable() default true;


    LogActionType type() default LogActionType.SELECT;
}

配置切面,只要添加了日志注解的接口都会被切到

/**
 * @author lyp
 */

@Component
@Aspect
@Slf4j
public class LogAspectMongo {
    private final LogServiceImpl logService;

    ThreadLocal<Long> currentTime = new ThreadLocal<>();

    public LogAspectMongo(LogServiceImpl logService) {
        this.logService = logService;
    }

    /**
     * 配置切入点
     */
    @Pointcut("@annotation(com.ebaiyihui.log.annotation.Log)")
    public void logPointcut() {
        // 该方法无方法体,主要为了让同类中其他方法使用此切入点
    }

    /**
     * 配置环绕通知,使用在方法logPointcut()上注册的切入点
     *
     * @param joinPoint join point for advice
     */
    @Around("logPointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result;
        currentTime.set(System.currentTimeMillis());
        result = joinPoint.proceed();
        String resParam = postHandle(result);
        Log log = new Log("INFO",System.currentTimeMillis() - currentTime.get());
        currentTime.remove();
        HttpServletRequest httpServletRequest = RequestHolder.getHttpServletRequest();
        logService.saveMongo(httpServletRequest,resParam,joinPoint,log);
        return result;
    }

    /**
     * 配置异常通知
     *
     * @param joinPoint join point for advice
     * @param e exception
     */
    @AfterThrowing(pointcut = "logPointcut()", throwing = "e")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
        log.info("========错误信息======>{}", ThrowableUtil.getStackTrace(e));
        Log log = new Log("ERROR",System.currentTimeMillis() - currentTime.get());
        currentTime.remove();
        log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes());
        HttpServletRequest request = RequestHolder.getHttpServletRequest();
        String userViewId=request.getHeader("userId");
        String appCode = request.getHeader("appCode");
        String resParam = "接口异常";
        logService.save(appCode,resParam,userViewId, StringUtil.getBrowser(request), IpAddressUtil.getIpAddr(request), (ProceedingJoinPoint)joinPoint, log);
    }

    private String postHandle(Object retVal) {
        if(null == retVal){
            return "";
        }
        return JSON.toJSONString(retVal);
    }

}
/**
 * @ClassName LogService
 * @description: 记录操作日志
 * @author: liyp
 * @create: 2020-08-0711:54
 **/
@Service
@Slf4j
public class LogServiceImpl  {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private Map<String, ResolveParameter>   resolveParameterMap;

   
  //异步线程池
   public void saveMongo(HttpServletRequest httpServletRequest,String resParam, ProceedingJoinPoint joinPoint, Log adminLog) {
            simpleExecutorService.execute(() -> {
                try {
                    log.info("进入纪录日志service");
                    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                    Method method = signature.getMethod();
                    com.ebaiyihui.log.annotation.Log aopLog = method.getAnnotation(com.ebaiyihui.log.annotation.Log.class);

                    String logActionType = aopLog.type().getDisplay();

                    // 方法路径
                    String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";

                    StringBuilder params = new StringBuilder("{");
                    //参数值
                    List<Object> argValues = new ArrayList<>(Arrays.asList(joinPoint.getArgs()));

                    String reqParam = JSON.toJSONString(joinPoint.getArgs());

                    log.info("reqParam = {}",reqParam);

                    //参数名称
                    for (Object argValue : argValues) {
                        params.append(argValue).append(" ");
                    }

                    log.info(" params = {}",params);
                    String converseMark = aopLog.converseMark();

                    // 描述
                    if (adminLog != null) {
                        adminLog.setDescription(aopLog.value());
                    }
                    adminLog.setAppCode(httpServletRequest.getHeader("appCode"));
                    adminLog.setRequestIp(IpAddressUtil.getIpAddr(httpServletRequest));
                    adminLog.setMethod(methodName);
                    adminLog.setUserId(httpServletRequest.getHeader("userId"));
//                adminLog.setReqParams(params.toString() + " }");
                    adminLog.setReqParams(reqParam);
                    adminLog.setResParams(resParam);
                    adminLog.setBrowser(StringUtil.getBrowser(httpServletRequest));
                    adminLog.setLogActionType(logActionType);
                    adminLog.setResParams(resParam);
                    adminLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    log.info("接口解析方法入参:{}",JSON.toJSONString(adminLog));

                    LogReqVo logReqVo = new LogReqVo();
                    logReqVo.setReqParam(reqParam);
                    logReqVo.setResParam(resParam);

                    LogResVo logResVo = new LogResVo();
                    ResolveParameter resolveParameter = resolveParameterMap.get(converseMark);
                    if (Objects.isNull(resolveParameter)){
                        DefaultResolveParameter defaultResolveParameter = new DefaultResolveParameter();
                        logResVo = defaultResolveParameter.resolveParas(logReqVo);
                        adminLog.setOperationDescription(logResVo.getOperationDescription());
                        log.info("默认接口解析返回值:{}",JSON.toJSONString(logResVo));
                    }else{
                        logResVo = resolveParameter.resolveParas(logReqVo);
                        adminLog.setOperationDescription(logResVo.getOperationDescription());
                        log.info("接口解析后返回值:{}",JSON.toJSONString(logResVo));
                    }
                    log.info("存入mongo参数:{}",JSON.toJSONString(adminLog));
                    mongoTemplate.save(adminLog);
                }catch (Exception e){
                    e.printStackTrace();
                }
            });
    }
}

给方法上添加注解:

@Log(value = "就诊卡-绑定就诊卡",converseMark = "hybindListCard",type = LogActionType.UPDATE)
public BaseResponse<List<CardDetailsInfoRespVO>> hybindListCard(@RequestBody RegisterCardReqVO reqVO) {
    MdcUtil.setCallerUserMethod(reqVO.getChannelCode(), reqVO.getCredNo(), "航天中心医院绑定卡集合");
    return cardService.hybindListCard(reqVO);
}
/**
 * @ClassName RegisterOrBindCardParse
 * @description: 注册或绑定就诊卡解析
 * @author: liyp
 * @create: 2020-10-2016:32
 **/
@Component("registerOrBindCard")
@Slf4j
public class RegisterOrBindCardParse implements ResolveParameter {
    @Override
    public LogResVo resolveParas(LogReqVo logReqVo) {
        String reqParam = "";
        if(null != logReqVo){
            reqParam = logReqVo.getReqParam();
            StringBuilder stringBuilder = new StringBuilder(reqParam);
            reqParam = stringBuilder.substring(1, stringBuilder.length() - 1).toString();
        }
        log.info("绑定就诊卡参数解析入参:{}",reqParam);
        RegisterCardReqVO registerCardReqVO = JSON.parseObject(reqParam, RegisterCardReqVO.class);
        LogResVo logResVo = new LogResVo();
        logResVo.setOperationDescription("新增就诊卡:".concat(registerCardReqVO.getPatientName()));
        log.info("logResVo = {}",JSON.toJSONString(logResVo));
        return logResVo;
    }