2016-03-22 13 views
54

Tôi nhận được dưới đây là ngoại lệ khi chạy ứng dụng khởi động mùa xuân trong khởi động:Không thể autowire lĩnh vực: RestTemplate trong ứng dụng khởi động mùa xuân

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)} 

Tôi autowiring RestTemplate trong TestController tôi. Tôi đang sử dụng Maven để quản lý sự phụ thuộc.

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

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

<?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> 
+0

upvoting câu hỏi của bạn vì nó không phải là rõ ràng rằng khi mọi thứ được liên kết một cách kỳ diệu thì 'RestTemplate' sẽ không được tạo tự động cho bạn. –

+0

Upvoted - hướng dẫn trên trang riêng của Spring Boot không nói gì về việc tạo một Bean RestTemplate !! – Matt

Trả lời

77

Đó chính xác là những gì lỗi nói. Bạn không tạo bất kỳ hạt nào có kích thước RestTemplate, do đó, nó không thể tự động nén bất kỳ loại nào. Nếu bạn cần số RestTemplate, bạn sẽ phải cung cấp một tài khoản. Ví dụ, thêm dòng sau vào TestMicroServiceApplication.java:

@Bean 
public RestTemplate restTemplate() { 
    return new RestTemplate(); 
} 

Lưu ý, trong các phiên bản trước đây của khởi động mùa xuân đám mây cho Eureka, một bean RestTemplate đã được tạo ra cho bạn, nhưng điều này không còn đúng nữa.

+0

Cảm ơn bạn rất nhiều vì đã trả lời. Điều này đã giúp! – Khuzi

+6

Đã bỏ phiếu cho câu hỏi và câu trả lời của bạn Nguyên nhân không rõ ràng là bạn phải tự tạo một 'RestTemplate' khi mọi thứ khác được tạo và liên kết một cách kỳ diệu cho bạn. Đặc biệt nếu một người dùng đám mây mùa xuân trước đó cung cấp một 'RestTemplate' được tự động định cấu hình. ;-) –

+2

Thành thật mà nói, đó là lý do tôi đặt vấn đề này ở đây trong diễn đàn. Tôi đã mong đợi RestTemplate được liên kết với tôi. :-) Điều này đã làm việc tốt khi tôi đã bao gồm sự phụ thuộc Eureka trong POM.xml. Nó hoạt động tốt mà không cần định nghĩa bean RestTemplate. Một trong những lớp học của Eureka có thể đã định nghĩa loại đậu này. – Khuzi

1

Các điểm lỗi trực tiếp rằng RestTemplate đậu không được xác định trong ngữ cảnh và nó không thể nạp hạt.

  1. Xác định một bean cho RestTemplate và sau đó sử dụng nó
  2. Sử dụng một trường hợp mới của RestTemplate

Nếu bạn chắc chắn rằng các hạt được xác định cho các RestTemplate sau đó sử dụng sau đây để in đậu có sẵn trong bối cảnh được tải bởi ứng dụng khởi động mùa xuân

ApplicationContext ctx = SpringApplication.run(Application.class, args); 
String[] beanNames = ctx.getBeanDefinitionNames(); 
Arrays.sort(beanNames); 
for (String beanName : beanNames) { 
    System.out.println(beanName); 
} 

Nếu điều này chứa đậu theo tên/loại đã cho, thì tất cả đều tốt. Hoặc định nghĩa một bean mới và sau đó sử dụng nó.

3

Nếu một TestRestTemplate là một lựa chọn hợp lệ trong bài kiểm tra đơn vị của bạn, tài liệu này có thể liên quan

http://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/reference/htmlsingle/#boot-features-rest-templates-test-utility

Câu trả lời ngắn: nếu sử dụng

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 

sau đó @Autowired sẽ làm việc. Nếu sử dụng

@SpringBootTest(webEnvironment=WebEnvironment.MOCK) 

sau đó tạo ra một TestRestTemplate như thế này

private TestRestTemplate template = new TestRestTemplate(); 
0

Kể từ trường hợp RestTemplate thường cần phải được tùy chỉnh trước khi được sử dụng, Spring Boot không cung cấp bất kỳ tính năng tự động cấu hình đậu RestTemplate duy nhất.

RestTemplateBuilder cung cấp cách thích hợp để định cấu hình và khởi tạo mẫu khuôn mẫu còn lại, ví dụ như cho auth hoặc interceptor cơ bản.

@Bean 
public RestTemplate restTemplate(RestTemplateBuilder builder) { 
    return builder 
       .basicAuthorization("user", "name") // Optional Basic auth example 
       .interceptors(new MyCustomInterceptor()) // Optional Custom interceptors, etc.. 
       .build(); 
} 
1

Tùy thuộc vào những gì công nghệ bạn đang sử dụng và những gì các phiên bản sẽ ảnh hưởng như thế nào bạn định nghĩa một RestTemplate trong lớp @Configuration của bạn.

Xuân> = 4 mà không có mùa xuân Boot

Đơn giản chỉ cần xác định một @Bean:

@Bean 
public RestTemplate restTemplate() { 
    return new RestTemplate(); 
} 

Xuân Boot < = 1,3

Không cần phải xác định một, Spring Boot tự động xác định một cho bạn.

Xuân Boot> = 1.4

Xuân Boot không còn tự động định nghĩa một RestTemplate nhưng thay vì định nghĩa một RestTemplateBuilder cho phép bạn kiểm soát nhiều hơn các RestTemplate đó được tạo ra. Bạn có thể tiêm các RestTemplateBuilder như một tham số trong phương pháp @Bean của bạn để tạo ra một RestTemplate:

@Bean 
public RestTemplate restTemplate(RestTemplateBuilder builder) { 
    // Do any additional configuration here 
    return builder.build(); 
} 

Sử dụng nó trong lớp học của bạn

@Autowired 
private RestTemplate restTemplate; 

Reference

Các vấn đề liên quan