今天在Spring Boot(2.1.6.RELEASE)應用程式的Controller類別中用@Autowired
注入RestTemplate
的實例時出現下面錯誤訊息而無法啟動。
DemoController
package com.abc.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private RestTemplate restTemplate;
...
}
***************************
APPLICATION FAILED TO START
***************************
Description:
Field restTemplate in com.abc.demo.controller.DemoController required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
訊息大意是說找不到org.springframework.web.client.RestTemplate
的Bean,並提示我們在應用程式的配置中定義一個org.springframework.web.client.RestTemplate
的Bean。
所以在Spring Boot的SpringBootApplication類別中使用@Bean
定義一個RestTemplate
的Bean如下。
SpringBootDemoApplication
@SpringBootApplication
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
必須手動配置Bean是因為RestTemplate
使用前常需要自訂各種參數,所以Spring Boot不幫我們自動配置。
以下引述官方說明:
Since
RestTemplate
instances often need to be customized before being used, Spring Boot does not provide any single auto-configuredRestTemplate
bean. It does, however, auto-configure aRestTemplateBuilder
, which can be used to createRestTemplate
instances when needed.
完成以上RestTemplate
的Bean配置即可在Controller中正常以@Autowired
注入RestTemplate
的實例。
不過Spring Boot有自動配置RestTemplateBuilder
的Bean,所以在Controller或Service類別中可改用以下方式取得RestTemplate
實例。
DemoController
package com.abc.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/demo")
public class DemoController {
private final RestTemplate restTemplate;
// 建構式注入
public DemoController(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
@GetMapping(value = "/{id}", produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
public String getDemoResult(@PathVariable int id) {
return this.restTemplate.getForObject("http://localhost:8080/services/{id}", String.class);
}
...
}
參考:
沒有留言:
張貼留言