【问题标题】:RestTemplateBuilder beanRestTemplateBuilder 豆
【发布时间】:2018-12-05 11:10:59
【问题描述】:

我的应用程序与不同的休息端点接口,每个都需要一个专门的 RestTemplate 对象。我正在使用 RestTemplateBuilder 创建每个 RestTemplate 对象。是否可以克隆spring boot提供的RestTemplateBuilder对象并进行更改?

@Configuration
public class Config {
@Bean
public RestTemplate googleRestTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.basicAuthorization("user", "pwd123").build();
}

@Bean
public RestTemplate twitterRestTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.setConnectTimeout(5000).build();
}
}

在这里,我将单例构建器 bean 注入到两个 bean 方法中。我试图克服的问题是同一个构建器对象的变异。在我的示例中,我的第二个休息模板不需要基本授权,但我无意中得到了它。

【问题讨论】:

    标签: spring-mvc spring-boot resttemplate


    【解决方案1】:

    您可以使用@Qualifier 注释来区分您的 RestTemplates,如下所示。

    @Configuration
    public class Config {
    
      @Bean
      @Qualifier("googleRestTemplate")
      public RestTemplate googleRestTemplate(RestTemplateBuilder restTemplateBuilder) {
        return restTemplateBuilder.basicAuthorization("user", "pwd123").build();
      }
    
      @Bean
      @Qualifier("twitterRestTemplate")
      public RestTemplate twitterRestTemplate(RestTemplateBuilder restTemplateBuilder) {
        return restTemplateBuilder.setConnectTimeout(5000).build();
      }
    }
    

    然后,您可以将控制器中的任何 RestTemplate bean 与这些 @Qualifiers 一起使用。

    @Autowired
    @Qualifier("googleRestTemplate")
    private RestTemplate restTemplate;
    

    【讨论】:

    • 谢谢。我知道区分不同休息模板 bean 的限定符 - 我的问题是关于休息模板构建器 bean。
    【解决方案2】:

    你为什么要这样做? 添加config 类:

    @Configuration
    class Config {
        @Bean
        @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
        RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
            return restTemplateBuilder.build();
        }
    }
    

    在您的 Controller 中,这将消耗您的端点:

    @Autowired
    RestTemplate restTempl;
    
    @RequestMapping(value = "/consume", method = RequestMethod.POST)
    public void samplePostMethod() {
    
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<String> entity = new HttpEntity<String>("Data", headers);
        RequestDetails requestDetails = new RequestDetails("http://localhost:8082/endpoint1", HttpMethod.POST);
        ResponseEntity<String> response = restTempl.exchange(requestDetails.getUrl(), requestDetails.getRequestType(),
                entity, String.class);
    
        RequestDetails requestDetailss = new RequestDetails("http://localhost:8082/endpoint2", HttpMethod.POST);
        ResponseEntity<String> responses = restTempl.exchange(requestDetailss.getUrl(), requestDetailss.getRequestType(),
                entity, String.class);
    
        logger.log("{} {}", response, responses);
        return response.getBody();
    }
    

    【讨论】:

    • 我已经添加了一个代码sn-p和问题的解释。
    • 如何将 bean 的范围从单例更改为请求。查看上面的更新
    • 但是,如果您需要对这些端点进行调用,并对您的应用程序发出相同的请求,则上述解决方案将不起作用。我在等你的回复。
    • 我的想法是在这两种 bean 方法中克隆 resttemplatebuilder 以便原始构建器保持原始状态。
    • 不,你不能那样做。如果您需要自定义,请使用 RestTemplateCustomizer 并且您不需要这样做。根据文档,每次调用 RestTemplateBuilder 的方法都会返回一个新的 RestTemplateBuilder 实例。所以这基本上意味着,你应该有一个 google 实例和一个 twitter 实例。我怀疑你甚至没有调用你的第二个 bean。你能通过添加一些记录器来检查吗?
    猜你喜欢
    • 2019-08-26
    • 1970-01-01
    • 2017-05-31
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多