以下代码未重试。我错过了什么?
@EnableRetry
@SpringBootApplication
public class App implements CommandLineRunner
{
.........
.........
@Retryable()
ResponseEntity<String> authenticate(RestTemplate restTemplate, HttpEntity<MultiValueMap<String, String>> entity) throws Exception
{
System.out.println("try!");
throw new Exception();
//return restTemplate.exchange(auth_endpoint, HttpMethod.POST, entity, String.class);
}
我已将以下内容添加到pom.xml中。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
我也试过为@Retryable提供不同的参数组合。
@Retryable(maxAttempts=10,value=Exception.class,backoff=@Backoff(delay = 2000,multiplier=2))
感谢。
答案 0 :(得分:9)
对于要发现的方法的@Retryable
注释,需要从初始化的上下文中正确调用它。方法是从spring上下文中调用bean还是通过其他方式调用?
如果使用SpringJunit4ClassRunner
测试这是你的跑步者?
答案 1 :(得分:7)
在Spring Boot 2.0.2发行版中,我观察到@Retryable在同一个类中具有可重试和调用的方法时不起作用。在调试时发现切入点没有正确构建。现在,解决此问题的方法是,我们需要在其他类中编写该方法并调用它。
可以找到工作示例here。
答案 2 :(得分:3)
我解决了。我发现如果从你试图重试的方法返回一些东西,那么@Retryable()就不起作用了。
pom.xml中的maven依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
Spring boot Application.java
@SpringBootApplication
@EnableTransactionManagement
@EnableRetry
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
在controller.java中
@RestController
public class JavaAllDataTypeController {
@Autowired
JavaAllDataTypeService JavaAllDataTypeService;
@RequestMapping(
value = "/springReTryTest",
method = RequestMethod.GET
)
public ResponseEntity<String> springReTryTest() {
System.out.println("springReTryTest controller");
try {
JavaAllDataTypeService.springReTryTest();
} catch (Exception e) {
e.printStackTrace();
}
return new ResponseEntity<String>("abcd", HttpStatus.OK);
}
}
@Service
@Transactional
public class JavaAllDataTypeService {
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts=9,value=Exception.class,backoff=@Backoff(delay = 2000))
public void springReTryTest() throws Exception {
System.out.println("try!");
throw new Exception();
}
}
输出:它&#39;尝试9次然后抛出异常。
答案 3 :(得分:2)
它也适用于返回类型
@Service
public class RetryService {
private int count = 0;
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts = 9, value = Exception.class, backoff = @Backoff(delay = 2000))
public String springReTryTest() throws Exception {
count++;
System.out.println("try!");
if (count < 4)
throw new Exception();
else
return "bla";
}
}
答案 4 :(得分:0)
另一个选择可以是RetryTemplate
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000l);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}
和
retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
@Override
public Void doWithRetry(RetryContext arg0) {
myService.templateRetryService();
...
}
});
为我锻炼
答案 5 :(得分:0)
我遇到的问题与原始问题完全相同。
在我的情况下,事实证明偶然不包括spring-boot-starter-aop
依赖项。将其添加到我的pom.xml
后,我的@Retryable
方法可以正常工作。
从@Retryable
方法返回值对我来说很好。
答案 6 :(得分:0)
即使我遇到了同样的问题,后来经过一些调查和研究才知道,除了方法上面的@Retryable注解,我们还需要在类上面提供@EnableRetry。这个@EnableRetry 注释可以提供在您提供了要重试的方法的同一类之上,也可以提供在主 Spring Boot 应用程序类之上。例如像这样:
@RequiredArgsConstructor
**@EnableRetry**
@Service
public class SomeService {
**@Retryable(value = { HttpServerErrorException.class, BadRequestException.class},
maxAttempts = maxRetry, backoff = @Backoff(random = true, delay = 1000,
maxDelay = 8000, multiplier = 2))**
public <T> T get( ) throws HttpServerErrorException, BadRequestException {
//write code here which you want to retry
}
}
我希望这能帮助您解决问题。
答案 7 :(得分:0)
对于那些想在来类中调用 @Retryable
块的人可以通过这种方式。
这里的关键不是直接调用方法,而是通过自注入bean
@Slf4j
@Service
public class RetryService {
@Resource(name = "retryService")
private RetryService self;
public String getValue(String appender) {
return self.getData(appender);
}
@Retryable(value = NumberFormatException.class, maxAttempts = 4, backoff = @Backoff(500))
public String getData(String appender) {
log.info("Calling getData");
Integer value = Integer.parseInt(appender);
value++;
return value.toString();
}
@Recover
public String recoverData(String appender) {
log.info("Calling recoverData");
return "DEFAULT";
}
}
可以阅读更多关于使用重试的详细信息here