我正在尝试编写一种跨领域的功能注释,以在执行方法之前在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。