从Spring调用具有Oauth2的API时,我们需要添加重试。
我们还没有想出一种简单的方法。我们甚至尝试使用拦截器,但没有运气。
这是我们的代码:
Application.java
@EnableRetry
@SpringBootApplication
public class Application {
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
@Bean
public OAuth2RestTemplate oAuth2RestTemplate(ClientHttpRequestInterceptor interceptor) {
List<String> scopes = new ArrayList<>();
scopes.add("some-scope");
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setAccessTokenUri("tokenUrl");
resourceDetails.setClientId("client-id");
resourceDetails.setClientSecret("client-secret");
resourceDetails.setScope(scopes);
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails);
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(interceptor);
oAuth2RestTemplate.setInterceptors(interceptors);
return oAuth2RestTemplate;
}
@Bean
public CommandLineRunner run(OAuth2RestTemplate oAuth2RestTemplate) throws Exception {
return args -> {
oAuth2RestTemplate.getForObject(
"some-url-that-returns-error.com", Quote.class);
};
}
}
MyInterceptor.java
@Component
public class MyInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
return interceptWithRetry(httpRequest, bytes, execution);
}
@Retryable
private ClientHttpResponse interceptWithRetry(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
System.out.println("====================================");
return execution.execute(httpRequest, bytes);
}
}
以及我们pom.xml中的依赖项
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
运行此命令时出现错误,我们看不到调用beign重试,无论我们传递给@Retryable
的参数如何,拦截器仅被调用一次。
有人可以为此提供一些指导吗?
谢谢
答案 0 :(得分:0)
我们仍然不知道Retryable
在拦截器中不起作用的原因。我们最终将注释移至Service中的方法,并完全摆脱了拦截器。
SomeService.java
@Service
public class SomeService {
private OAuth2RestTemplate restTemplate;
public SomeService(OAuth2RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Retryable
public Quote getSomething() {
System.out.println("============= THIS WILL THROW AN EXCEPTION =================");
return restTemplate.getForObject(
"some-url-that-returns-error.com", Quote.class);
}
}
这有效。但是,最好避免在每种服务的每种方法上重复@Retryable(params)
。
现在,我会将问题标记为已回答。