从相同/不同类中的另一个方法内部调用该方法时,注释不起作用

时间:2019-04-12 08:12:57

标签: java annotations aop aspectj spring-annotations

我正在尝试编写一种跨领域的功能注释,以在执行方法之前在MDC中添加值。但是,当我从另一个方法调用该方法并给出NPE时,我无法这样做。我该怎么办?

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MDCAnnotated {
    MDCValue[] value() default {};
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface MDCValue {
    String key();
    String content() default "";
}
@Order(1)
@Service
@Aspect
public class MdcContextInitializer {

    private final String REQUEST_ID = "requestId";

    @Around("@annotation(com.example.test.annotation.MDCAnnotated)")
    public Object aroundAnnotatedMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        MDCAnnotated annotation = method.getAnnotation(MDCAnnotated.class);
        setMdcContextForMethod(annotation);
        setMdcContextForMethodWithParameterDefinedValues(method.getParameters(), joinPoint.getArgs());
        return joinPoint.proceed();
    }

    private void setMdcContextForMethod(MDCAnnotated annotation) {
        boolean isRequestIdSpecificallyAdded = false;
        //Gives NPE in the following line
        for (MDCParam value : annotation.value()) {
            if (REQUEST_ID.equals(value.key())) {
                isRequestIdSpecificallyAdded = true;
            }
            MDC.put(value.key(), value.content());
        }
        if (!isRequestIdSpecificallyAdded) {
            MDC.put(REQUEST_ID, UUID.randomUUID().toString());
        }
    }

    private void setMdcContextForMethodWithParameterDefinedValues(Parameter[] parameters, Object[] args) {
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            MDCValue value = parameter.getAnnotation(MDCValue.class);
            if (value != null) {
                MDC.put(value.key(), String.valueOf(args[i]));
            }
        }
    }
}

现在,当我尝试使用批注时,它可以在此处用于Spring Scheduler:

@Scheduled(cron = "${scheduling.example.cron}")
@ExtendMDC({
        @MDCValue(key = "Name 1", content = "Fixed Value 1"),
        @MDCValue(key = "Name 2", content = "Fixed Value 2")
})
public void test() {
    log.info(MDC.get("Name 1"));
    log.info(MDC.get("Name 2"));
    log.info(MDC.get("requestId"));
    myServiceFactory.getService(1).build();
    testService.test("rjw");
}

但是,我也注释了上述方法的最后一行中调用的测试服务方法。

@Service
@Slf4j
public class TestServiceImpl implements TestService {

    @Override
    @ExtendMDC
    public void test(@MDCValue(key = "hj") String hj) {
        log.info("HJ:{}", MDC.get(hj));
    }
}

在此方法方面处理中,它在行中提供了用于注释的NPE(在方面类中进行了注释以供参考)。

这怎么可能?如果没有注释,那么它将不会仅出现在Aspect中。不是吗?

我该如何解决?

P.S .:我已经用@EnableAspectJAutoProxy标记了我的SpringBootApplication。

0 个答案:

没有答案