@Timed 注解需依赖 Spring AOP 切面与 MeterRegistry 才能生效,必须启用自动配置、确保 Bean 被 Spring 管理并正确暴露 /actuator/prometheus 端点,且方法调用须经代理(避免同类内调用),指标才可上报至 Prometheus。

Java 中 Micrometer 的 @Timed 注解本身不会自动上报指标,它只是标记方法需要计时,真正上报依赖于 Spring AOP 切面 + MeterRegistry 的注册机制。要让 @Timed 生效并自动暴露给 Prometheus,关键在于启用自动配置、确保切面生效、以及正确暴露 /actuator/prometheus 端点。
确保 Spring Boot 自动配置已启用
Spring Boot 2.0+ 默认集成 Micrometer,只要引入了 spring-boot-starter-actuator 和 micrometer-registry-prometheus,且配置开启即可:
- 添加 Maven 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
- 在
application.yml中启用 actuator 端点和 Prometheus 暴露:
management:
endpoints:
web:
exposure:
include: prometheus,health,info
endpoint:
prometheus:
show-details: when_authorized
这样 /actuator/prometheus 就能返回文本格式的指标数据。
@Timed 注解需配合 @EnableAspectJAutoProxy 或自动代理机制
@Timed 是基于 AOP 实现的,Spring 默认对带 @Timed 的 Bean 方法织入计时逻辑,但前提是目标 Bean 必须是 Spring 管理的代理对象(即通过 IOC 容器获取,而非 new 实例)。
立即学习“Java免费学习笔记(深入)”;
- 确保类被 Spring 托管(如加
@Service、@Component) - 避免在同一个类中调用本类的
@Timed方法(内部调用绕过代理,不触发切面) - 若使用 JDK 动态代理(接口实现),方法必须定义在 public 接口中;若用 CGLIB(类代理),方法不能是 private/final/static
自定义 Timed 切面(可选,用于增强控制)
默认情况下 Spring Boot 已提供 TimedAspect(由 TimedAdvisor 驱动),一般无需手动写。但若需自定义行为(比如统一添加 tag、忽略某些异常等),可显式定义:
- 声明一个
@Aspect类,注入MeterRegistry - 拦截
@Timed方法,手动创建 Timer 并记录耗时 - 注意:不要重复注册同名 metric,否则会报错(Micrometer 要求 metric name 唯一)
示例片段(非必须,仅作参考):
@Aspect
@Component
public class CustomTimedAspect {
private final MeterRegistry registry;
public CustomTimedAspect(MeterRegistry registry) {
this.registry = registry;
}
@Around("@annotation(timed)")
public Object timedMethod(ProceedingJoinPoint joinPoint, Timed timed) throws Throwable {
String name = timed.value().isEmpty() ? joinPoint.getSignature().toShortString() : timed.value();
Timer timer = Timer.builder(name)
.tags(timed.extraTags())
.description(timed.description())
.register(registry);
return timer.recordCallable(() -> joinPoint.proceed());
}
}
验证指标是否上报成功
启动应用后,访问 http://localhost:8080/actuator/prometheus,搜索类似 method_timer_seconds_count{class="YourService",method="yourMethod",...} 的指标。
- 若没看到对应指标,先确认方法是否被 Spring 正确代理(打印日志或断点看是否进入切面)
- 检查是否因异常未被捕获导致计时中断(
@Timed默认统计所有执行,包括抛异常的情况) - 确认
Timed注解在方法上(不是类上),且方法是 public


















