无法自动装配字段:Spring 启动应用程序中的 RestTemplate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36151421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Could not autowire field:RestTemplate in Spring boot application
提问by Khuzi
I am getting below exception while running spring boot application during start up:
我在启动期间运行 spring boot 应用程序时遇到异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.client.RestTemplate com.micro.test.controller.TestController.restTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.client.RestTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
I am autowiring RestTemplate in my TestController. I am using Maven for dependency managagement.
我在我的 TestController 中自动装配 RestTemplate。我正在使用 Maven 进行依赖管理。
TestMicroServiceApplication.java
测试微服务应用程序
package com.micro.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestMicroServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TestMicroServiceApplication.class, args);
}
}
TestController.java
测试控制器.java
package com.micro.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/micro/order/{id}",
method=RequestMethod.GET,
produces=MediaType.ALL_VALUE)
public String placeOrder(@PathVariable("id") int customerId){
System.out.println("Hit ===> PlaceOrder");
Object[] customerJson = restTemplate.getForObject("http://localhost:8080/micro/customers", Object[].class);
System.out.println(customerJson.toString());
return "false";
}
}
POM.xml
POM文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.micro.test</groupId>
<artifactId>Test-MicroService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test-MicroService</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
回答by g00glen00b
It's exactly what the error says. You didn't create any RestTemplate
bean, so it can't autowire any. If you need a RestTemplate
you'll have to provide one. For example, add the following to TestMicroServiceApplication.java:
这正是错误所说的。您没有创建任何RestTemplate
bean,因此它无法自动装配任何 bean。如果你需要一个,RestTemplate
你必须提供一个。例如,将以下内容添加到TestMicroServiceApplication.java:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
Note, in earlier versions of the Spring cloud starter for Eureka, a RestTemplate
bean was created for you, but this is no longer true.
请注意,在 Eureka 的 Spring cloud starter 的早期版本中,RestTemplate
为您创建了一个bean,但现在不再如此。
回答by Sahil Chhabra
Depending on what technologies you're using and what versions will influence how you define a RestTemplate
in your @Configuration
class.
取决于您使用的技术和版本将影响您RestTemplate
在@Configuration
类中定义 a的方式。
Spring >= 4 without Spring Boot
Spring >= 4 没有 Spring Boot
Simply define an @Bean
:
简单地定义一个@Bean
:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
Spring Boot <= 1.3
弹簧靴 <= 1.3
No need to define one, Spring Boot automatically defines one for you.
不需要定义一个,Spring Boot 会自动为你定义一个。
Spring Boot >= 1.4
弹簧靴 >= 1.4
Spring Boot no longer automatically defines a RestTemplate
but instead defines a RestTemplateBuilder
allowing you more control over the RestTemplate that gets created. You can inject the RestTemplateBuilder
as an argument in your @Bean
method to create a RestTemplate
:
Spring Boot 不再自动定义 aRestTemplate
而是定义 aRestTemplateBuilder
允许您更好地控制创建的 RestTemplate 。你可以RestTemplateBuilder
在你的@Bean
方法中作为参数注入来创建一个RestTemplate
:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
// Do any additional configuration here
return builder.build();
}
Using it in your class
在你的课堂上使用它
@Autowired
private RestTemplate restTemplate;
回答by Mark K.
If a TestRestTemplate is a valid option in your unit test, this documentation might be relevant
如果 TestRestTemplate 是单元测试中的有效选项,则此文档可能是相关的
Short answer: if using
简短回答:如果使用
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
then @Autowired
will work. If using
然后@Autowired
会工作。如果使用
@SpringBootTest(webEnvironment=WebEnvironment.MOCK)
then create a TestRestTemplate like this
然后像这样创建一个 TestRestTemplate
private TestRestTemplate template = new TestRestTemplate();
回答by Pierrick HYMBERT
Since RestTemplate instances often need to be customized before being used, Spring Boot does not provide any single auto-configured RestTemplate bean.
由于 RestTemplate 实例在使用前经常需要自定义,因此 Spring Boot 不提供任何单个自动配置的 RestTemplate bean。
RestTemplateBuilderoffers proper way to configure and instantiate the rest template bean, for example for basic auth or interceptors.
RestTemplateBuilder提供了正确的方法来配置和实例化 rest 模板 bean,例如用于基本身份验证或拦截器。
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.basicAuthorization("user", "name") // Optional Basic auth example
.interceptors(new MyCustomInterceptor()) // Optional Custom interceptors, etc..
.build();
}
回答by VinayVeluri
Error points directly that RestTemplate
bean is not defined in context and it cannot load the beans.
错误直接指出RestTemplate
bean 未在上下文中定义并且无法加载 bean。
- Define a bean for RestTemplate and then use it
- Use a new instance of the RestTemplate
- 为 RestTemplate 定义一个 bean 然后使用它
- 使用 RestTemplate 的新实例
If you are sure that the bean is defined for the RestTemplate then use the following to print the beans that are available in the context loaded by spring boot application
如果您确定为 RestTemplate 定义了 bean,则使用以下命令打印 spring boot 应用程序加载的上下文中可用的 bean
ApplicationContext ctx = SpringApplication.run(Application.class, args);
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
If this contains the bean by the name/type given, then all good. Or else define a new bean and then use it.
如果这包含给定名称/类型的 bean,那么一切都很好。或者定义一个新的bean然后使用它。
回答by vineet
Please make sure two things:
请确保两件事:
1- Use @Bean
annotation with the method.
1-@Bean
在方法中使用注释。
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
2- Scope of this method should be publicnot private.
2- 此方法的范围应该是public而不是private。
Complete Example -
完整示例 -
@Service
public class MakeHttpsCallImpl implements MakeHttpsCall {
@Autowired
private RestTemplate restTemplate;
@Override
public String makeHttpsCall() {
return restTemplate.getForObject("https://localhost:8085/onewayssl/v1/test",String.class);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}
回答by Padi kodwo
The simplest way I was able to achieve a similar feat to use the code below (reference), but I would suggest not to make API calls in controllers(SOLID principles). Also autowiring this way is better optimsed than the traditional way of doing it.
我能够实现类似壮举的最简单方法是使用下面的代码(参考),但我建议不要在控制器中进行 API 调用(SOLID 原则)。此外,以这种方式自动装配比传统的方式更好。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
private final RestTemplate restTemplate;
@Autowired
public TestController(RestTemplateBuilder builder) {
this.restTemplate = builder.build();
}
@RequestMapping(value="/micro/order/{id}", method= RequestMethod.GET, produces= MediaType.ALL_VALUE)
public String placeOrder(@PathVariable("id") int customerId){
System.out.println("Hit ===> PlaceOrder");
Object[] customerJson = restTemplate.getForObject("http://localhost:8080/micro/customers", Object[].class);
System.out.println(customerJson.toString());
return "false";
}
}
回答by Ranushka Lakmal Sankalpa
- You must add
@Bean public RestTemplate restTemplate(RestTemplateBuilder builder){ return builder.build(); }
- 你必须添加
@Bean public RestTemplate restTemplate(RestTemplateBuilder builder){ return builder.build(); }
回答by Fazle Subhan
you are trying to inject the restTemplate but you need to create configuration class . then there you need to create bean that return you new RestTemplate see the below example.
您正在尝试注入 restTemplate 但您需要创建配置类。然后你需要创建bean来返回你新的RestTemplate,见下面的例子。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class YourConfigClass {
@Bean
public RestTemplate restTesmplate() {
return new RestTemplate();
}
}