Spring 4与Spring retry 1.2.1.RELEASE中@Recover注解未生效问题
让我来帮你排查下@Recover方法没触发的常见问题,结合你使用的Spring 4.3.5.RELEASE和Spring Retry 1.2.1.RELEASE版本,这些点要重点检查:
1. 重试方法的@Retryable注解配置是否完整
@Retryable是触发重试逻辑的核心前提,你需要确保:
- 注解明确指定了要捕获的异常类型,比如
@Retryable(value = Exception.class),否则Spring Retry无法识别哪些异常需要触发重试 maxAttempts参数值大于1(默认是3),如果手动设置为1,重试逻辑不会执行,自然也不会走到@Recover方法
2. @Recover方法的签名是否严格匹配要求
Spring Retry对恢复方法的签名有严格规则,不匹配的话不会触发,需要满足:
- 和
@Retryable方法在同一个类中(Spring Retry无法跨类匹配恢复方法) - 返回值和
@Retryable方法完全一致 - 第一个参数必须是触发重试的异常类型(或其父类)
- 后续参数要和
@Retryable方法的参数一一对应
举个符合要求的示例:
@Retryable(value = RuntimeException.class, maxAttempts = 2) public void process(ObjectA objA) { // 硬编码抛出异常 throw new RuntimeException("处理失败"); } @Recover public void recover(RuntimeException e, ObjectA objA) { // 用objB调用原方法 process(new ObjectB()); }
3. Spring AOP代理是否生效
Spring Retry基于AOP实现,必须满足代理生效的条件:
- 重试方法必须是
public修饰符(Spring AOP默认只代理public方法) - 不能在同一个类中直接调用重试方法(比如
this.process(objA)),这种写法会绕过代理,导致重试和恢复逻辑都失效,必须通过Spring容器注入的Bean来调用 - 你的
ClassTest必须被Spring容器正确管理,检查ConfigClass中beanA()方法返回的实例是否被成功注册到容器
4. 依赖冲突排查
虽然Spring 4.3.5和Spring Retry 1.2.1版本兼容,但要确保项目中没有混入其他版本的Spring AOP、Spring Context等依赖,你可以通过Maven/Gradle的依赖树命令排查冲突,比如mvn dependency:tree。
5. 开启日志辅助排查
开启Spring Retry的DEBUG日志,能直观看到重试逻辑的执行情况,比如是否触发了重试、是否尝试调用恢复方法:
<!-- 以Logback为例,添加日志配置 --> <logger name="org.springframework.retry" level="DEBUG"/>
完整示例参考
你可以对照这个完整的可运行示例调整你的代码:
// 配置类 @Configuration @EnableRetry public class ConfigClass { @Bean public ClassTest beanA(){ ClassTest obj = new ClassTest(); obj.setProp("test-prop"); return obj; } } // 业务类 public class ClassTest { private String prop; @Retryable(value = RuntimeException.class, maxAttempts = 2) public void process(ObjectA objA) { System.out.println("尝试处理ObjectA: " + objA); throw new RuntimeException("模拟处理失败"); } @Recover public void recover(RuntimeException e, ObjectA objA) { System.out.println("触发恢复方法,异常信息:" + e.getMessage()); // 用ObjectB调用原方法 process(new ObjectB()); } // getter/setter public String getProp() { return prop; } public void setProp(String prop) { this.prop = prop; } } // 调用示例 @Autowired private ClassTest classTest; public void testRetry() { classTest.process(new ObjectA()); }
内容的提问来源于stack exchange,提问作者user93726
相关产品推荐
相关产品推荐

