如何在Spring Boot中使用@Bean创建或配置Rest模板

时间:2016-07-22 01:02:41

标签: spring-boot

我想在Spring启动应用程序的配置类中使用RestTemplate注释将@Bean定义为应用程序bean。

我在应用程序流程中的不同位置调用了4个休息服务。目前我每次请求都会创建RestTemplate。有没有办法可以使用@Bean将其定义为应用程序bean并使用@Autowired注入?

这个问题的主要原因是我可以使用RestTemplate定义@Bean但是当我用@Autowired注入它时,我将丢失所有已定义的拦截器(拦截器未被调用。)

配置类

@Bean(name = "appRestClient")
public RestTemplate getRestClient() {

    RestTemplate  restClient = new RestTemplate(
        new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));

    List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
    interceptors.add(new RestServiceLoggingInterceptor());
    restClient.setInterceptors(interceptors);

    return restClient;
}

服务类

public class MyServiceClass {

    @Autowired
    private RestTemplate appRestClient;

    public String callRestService() {
        // create uri, method response objects
        String restResp = appRestClient.getForObject(uri, method, response);
        // do something with the restResp
        // return String
    }
}

看来我的Interceptors根本没有被这个配置调用。但RestTemplate能够调用REST服务并获得响应。

3 个答案:

答案 0 :(得分:4)

判断拦截器的名称,我猜你在做一些登录?您可能错过了日志记录级别配置。我使用package com.example; // imports... @SpringBootApplication public class TestApplication { private static final Logger LOGGER = LoggerFactory.getLogger(TestApplication.class); public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @Bean(name = "appRestClient") public RestTemplate getRestClient() { RestTemplate restClient = new RestTemplate( new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())); // Add one interceptor like in your example, except using anonymous class. restClient.setInterceptors(Collections.singletonList((request, body, execution) -> { LOGGER.debug("Intercepting..."); return execution.execute(request, body); })); return restClient; } } 版本创建了一个小应用程序来检查配置的工作天气。

在这个类中,我定义了application.properties bean和带有日志记录的拦截器。

logging.level.com.example=DEBUG

为了记录工作,我还必须在RestTemplate中设置正确的调试级别。

@Service
public class SomeService {

    private final RestTemplate appRestClient;

    @Autowired
    public SomeService(@Qualifier("appRestClient") RestTemplate appRestClient) {
        this.appRestClient = appRestClient;
    }

    public String callRestService() {
        return appRestClient.getForObject("http://localhost:8080", String.class);
    }
}

然后我创建了一个服务,我注入了这个@RestController public class SomeController { private final SomeService service; @Autowired public SomeController(SomeService service) { this.service = service; } @RequestMapping(value = "/", method = RequestMethod.GET) public String testEndpoint() { return "hello!"; } @RequestMapping(value = "/test", method = RequestMethod.GET) public String test() { return service.callRestService(); } }

GET

还有一个端点来测试它。

http://localhost:8080/test

通过向hello!执行http://localhost:8080请求,我应该会打印字符串hello!(该服务会调用Intercepting...并返回{{1}}并把它发回给我)。带记录器的拦截器也会在控制台中打印出{{1}}。

答案 1 :(得分:1)

如果您使用的是Spring Boot 1.4.0或更高版本,那么Edd的解决方案将无法运行。您将不得不使用RestTemplateBuilder来实现这一点。这是示例

@Bean(name="simpleRestTemplate")
@Primary
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){

    RestTemplate template = restTemplateBuilder.requestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
                                                .interceptors(logRestRequestInterceptor) //This is your custom interceptor bean
                                                .messageConverters(new MappingJackson2HttpMessageConverter())
                                                .build();
    return template;


}

现在您可以将bean自动装入服务类

@Autowired
@Qualifier("simpleRestTemplate")
private RestTemplate simpleRestTemplate;

希望这有帮助

答案 2 :(得分:1)

Spring boot 2。*。*版本的答案。

我正在使用 Spring boot 2.1.2RELEASE ,并且还在项目中存在邮件方法的类中添加了 RestTemplate

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {

    return builder.setConnectTimeout(Duration.ofMillis(300000))
     .setReadTimeout(Duration.ofMillis(300000)).build();
}

并在我的服务或其他课程中使用

@Autowired
RestTemplate res;

方法

 HttpEntity<String> entity = new HttpEntity<>(str, headers);
            return res.exchange(url, HttpMethod.POST, entity, Object.class);