Java Springboot@retryable不重试
以下代码未重试。我错过了什么Java Springboot@retryable不重试,java,spring,maven,spring-boot,spring-retry,Java,Spring,Maven,Spring Boot,Spring Retry,以下代码未重试。我错过了什么 @EnableRetry @SpringBootApplication public class App implements CommandLineRunner { ......... ......... @Retryable() ResponseEntity<String> authenticate(RestTemplate restTemplate, HttpEntity<MultiValueMap<
@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);
}
谢谢。对于要查找的方法上的
@Retryable
注释,需要从初始化的上下文中正确调用它。该方法是从spring上下文的bean调用的还是通过其他方式调用的
如果使用
SpringJunit4ClassRunner
?测试这是您的跑步者,我解决了它。我发现,如果从您试图重试的方法返回某些内容,那么@Retryable()就不起作用
pom.xml中的maven依赖关系
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
在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);
}
}
输出:它尝试了9次,然后抛出异常
它也适用于返回类型
@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";
}
}
@服务
公共类检索服务{
私有整数计数=0;
//尝试该方法9次,延迟2秒。
@可重试(maxtures=9,value=Exception.class,backoff=@backoff(delay=2000))
公共字符串springReTryTest()引发异常{
计数++;
System.out.println(“try!”);
如果(计数<4)
抛出新异常();
其他的
返回“bla”;
}
}
在spring boot 2.0.2版本中,我观察到,如果在同一个类中有Retryable并调用了方法,则@Retryable
不起作用。调试时发现切入点未正确构建。目前,这个问题的解决方法是,我们需要在不同的类中编写该方法并调用它
可以找到工作示例。另一种方法是
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(新的RetryCallback(){
@凌驾
公共无效doWithRetry(RetryContext arg0){
myService.templateRetryService();
...
}
});
为我锻炼
我的问题与原问题中描述的完全相同 在我的例子中,
springbootstarteraop
依赖项被意外地忽略了。将它添加到我的pom.xml
之后,我的@Retryable
方法按预期工作
从
@Retryable
方法返回值对我来说很好。即使是我也面临同样的问题,后来经过一些调查和研究,我知道除了方法上方的@Retryable注释之外,我们还需要在类上方提供@enablerery。这个@EnableRetry注释可以在您提供了要重试的方法的同一个类的上面提供,也可以在主spring引导应用程序类的上面提供。例如:
@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
}
}
@RequiredArgsConstructor
**@启用重试**
@服务
公共类服务{
**@可重试(值={HttpServerErrorException.class,BadRequestException.class},
maxAttempts=maxRetry,backoff=@backoff(random=true,delay=1000,
maxDelay=8000,乘数=2)**
public T get()抛出HttpServerErrorException、BadRequestException{
//在此处编写要重试的代码
}
}
我希望这将有助于解决您的问题。对于那些想在课堂上调用
@Retryable
block的人,可以这样做
这里的关键是不要直接通过自注入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";
}
}
可以详细阅读有关使用重试的更多信息谢谢,我还没有机会看这个,我会回来的。这应该是公认的答案,当你说“我发现如果从尝试重试的方法返回某个内容,那么@Retryable()不起作用。”如果是错误的,你实际上可以在重试方法中返回一个对象,关键是需要从bean调用该方法。我面临着同样的问题。我对spring boot 1.5.x有过同样的体验。spring boot 2.0.0到2.0.5也有同样的体验。检查mvn回购:2017年后没有spring retry版本,而spring boot 2于2018年推出。有没有一个救世主能够让SpringRetry在任何版本的SpringBoot2.x上工作?同时回滚到spring boot 1.5.15,它运行良好这是一个通用的spring东西,您可以使用@Autowired self-reference?这就是所有spring注释的工作方式。您需要一个单独的代理对象来进行排序,以便能够应用其他逻辑。这是因为Spring创建了一个代理对象来处理重试,而它无法创建自己的代理对象。使用其他注释作为
@Transactional
@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";
}
}
@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();
...
}
});
@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
}
}
@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";
}
}