Spring Boot 3中@NewSpan与@ContinueSpan注解支持情况确认
关于Spring Boot 3链路追踪注解问题的解答
对三个假设的验证
1. Spring Boot 3未官方支持这些旧注解
正确。虽然io.micrometer.tracing.annotation包下仍保留@NewSpan、@ContinueSpan等注解类,但Spring Boot 3的默认自动配置中,不再注册处理这些注解的AOP切面。这直接导致添加注解后,不会触发Span的创建/延续逻辑,所以看不到Span变化。
2. 可手动实现AOP切面使旧注解生效
正确。你可以自行编写AOP切面,通过@Around等切点拦截带有这些注解的方法,结合Micrometer Tracing提供的Tracer API手动创建Span、处理@SpanTag的标签注入。示例代码如下:
@Aspect @Component public class LegacyTracingAspect { private final Tracer tracer; public LegacyTracingAspect(Tracer tracer) { this.tracer = tracer; } @Around("@annotation(newSpan)") public Object handleNewSpan(ProceedingJoinPoint joinPoint, NewSpan newSpan) throws Throwable { String spanName = StringUtils.hasText(newSpan.value()) ? newSpan.value() : joinPoint.getSignature().getName(); Tracer.Span span = tracer.nextSpan().name(spanName).start(); try (Tracer.SpanInScope scope = tracer.withSpan(span)) { // 处理@SpanTag标签 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Object[] args = joinPoint.getArgs(); for (int i = 0; i < parameterAnnotations.length; i++) { for (Annotation annotation : parameterAnnotations[i]) { if (annotation instanceof SpanTag spanTag) { String key = StringUtils.hasText(spanTag.value()) ? spanTag.value() : spanTag.name(); span.tag(key, args[i].toString()); } } } return joinPoint.proceed(); } finally { span.end(); } } }
实现类似逻辑后,旧注解就能正常触发Span操作。
3. Micrometer Observation API是未来推荐方案
正确。Spring官方已明确将Micrometer Observation API作为链路追踪、指标监控的统一标准方案,它整合了原有的Micrometer指标和Tracing能力,提供更一致的编程模型。替代旧注解的方案是使用@Observed注解,或手动通过ObservationRegistry创建观测,既能生成追踪Span,也能收集业务指标,这是Spring Boot 3及后续版本的长期推荐方向。
补充建议
如果是新项目或迁移项目,优先采用Observation API而非维护自定义切面,避免后续版本兼容风险。例如用@Observed替代@NewSpan的示例:
@Service @RequiredArgsConstructor public class UserCreationService { private final ObservationRegistry observationRegistry; @Transactional @Observed(name = "create.new.user.and.group", contextualName = "user-creation") public UserGroup create(UserCreationRequest creationRequest) { // 业务逻辑 return userGroup; } }
内容的提问来源于stack exchange,提问作者Compile-Time
相关产品推荐
相关产品推荐

