MicroProfile Fault Tolerance的@Timeout注解失效,未抛出超时异常
问题解决:MicroProfile @Timeout注解未触发超时异常
核心原因及解决方案
1. 缺少MicroProfile Fault Tolerance的具体实现依赖
你只引入了MicroProfile Fault Tolerance的API依赖,但API仅定义规范,不包含实际执行逻辑,必须搭配规范的实现库(如SmallRye Fault Tolerance)才能让注解生效。
添加Spring Boot Starter依赖到pom.xml:
<dependency> <groupId>io.smallrye</groupId> <artifactId>smallrye-fault-tolerance-spring-boot-starter</artifactId> <version>6.0.0</version> <!-- 与MicroProfile Fault Tolerance 4.0.2版本兼容 --> </dependency>
2. 内部方法调用导致拦截器失效
你的hello()方法直接调用同一类中的hello2(),属于内部方法调用,会绕过Spring或MicroProfile的代理机制,导致@Timeout注解的拦截逻辑无法触发。
解决方法二选一:
方案A:拆分业务逻辑到独立Bean
将带@Timeout的方法抽离到单独的Spring Bean中,通过依赖注入调用:
// 业务服务类 @Service public class HelloService { @Timeout(unit = ChronoUnit.MILLIS, value = 100) public String hello2() { waitingMethod(); return "no_timeout"; } private void waitingMethod() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } // 控制器类 @RestController public class HelloController { private final HelloService helloService; // 构造注入 public HelloController(HelloService helloService) { this.helloService = helloService; } @GetMapping("/hello") public String hello() { return helloService.hello2(); } }
方案B:使用自身代理对象调用方法
在当前Bean中注入自身的代理实例,通过代理调用目标方法:
@RestController public class HelloController { @Autowired private HelloController selfProxy; @GetMapping("/hello") public String hello() { return selfProxy.hello2(); } @Timeout(unit = ChronoUnit.MILLIS, value = 100) public String hello2() { waitingMethod(); return "no_timeout"; } private void waitingMethod() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
验证
完成上述修改后,重启服务调用/hello接口,100ms后会触发org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException,符合超时预期。
内容的提问来源于stack exchange,提问作者VIVEK MISHRA
相关产品推荐
相关产品推荐

