2016-03-22 29 views
54

io sono sempre al di sotto di eccezione durante l'esecuzione di un'applicazione di avvio di primavera durante l'avvio:Impossibile autowire campo: RestTemplate in applicazione di avvio primavera

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

sto autowiring RestTemplate nel mio TestController. Sto usando Maven per la gestione delle dipendenze.

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 tua domanda causa non è ovvio che quando tutto è magicamente collegato un 'RestTemplate' non viene automaticamente creato per te. –

+0

Upvoted: il tutorial sulla pagina di avvio di Spring non dice nulla sulla creazione di un bean RestTemplate !! – Matt

risposta

77

È esattamente quello che dice l'errore. Non hai creato alcun bean RestTemplate, quindi non può autowire nessuno. Se hai bisogno di un RestTemplate dovrai fornirne uno. Ad esempio, aggiungere il seguente al TestMicroServiceApplication.java:

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

nota, nelle versioni precedenti del motorino di avviamento primavera nuvola per Eureka, un fagiolo RestTemplate è stato creato per voi, ma questo non è più vero.

+0

Grazie mille per la risposta. Questo ha aiutato! – Khuzi

+6

Hai svalutato la domanda e la tua risposta causa Non è ovvio che devi creare manualmente un 'RestTemplate' quando tutto il resto è magicamente creato e collegato per te. Soprattutto se si è utilizzato un cloud primaverile prima del quale viene fornito un 'RestTemplate' autoconfigurato. ;-) –

+2

Onestamente, questo è il motivo per cui ho messo questo problema qui nel forum. Mi aspettavo che RestTemplate fosse collegato per me. :-) Funzionava bene quando avevo incluso la dipendenza Eureka in POM.xml. Funzionava bene senza definire il bean RestTemplate. Una delle classi di Eureka potrebbe aver definito questo fagiolo o così. – Khuzi

1

Punti di errore direttamente che il bean RestTemplate non è definito nel contesto e non può caricare i bean.

  1. Definire un fagiolo per RestTemplate e quindi utilizzarlo
  2. Utilizzare una nuova istanza della RestTemplate

Se si è certi che il fagiolo è definito per il RestTemplate quindi utilizzare il seguente per stampare il fagioli che sono disponibili nel contesto caricato da molla applicazione di avvio

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

Se questo contiene il fagiolo di nome/tipo specificato, quindi tutto buono. Oppure definire un nuovo bean e quindi utilizzarlo.

3

Se un TestRestTemplate è un'opzione valida nel test di unità, questa documentazione potrebbe essere rilevante

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

Risposta breve: se si utilizza

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 

poi @Autowired funzionerà. Se si utilizza

@SpringBootTest(webEnvironment=WebEnvironment.MOCK) 

quindi creare un TestRestTemplate come questo

private TestRestTemplate template = new TestRestTemplate(); 
0

Dal momento che le istanze RestTemplate spesso bisogno di essere personalizzato prima di essere utilizzato, Primavera di avvio non fornisce alcun singolo chicco RestTemplate auto-configurato.

RestTemplateBuilder offre un modo corretto di configurare e creare un'istanza del bean del modello di rest, ad esempio per l'autenticazione di base o gli intercettori.

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

a seconda di ciò che si sta utilizzando tecnologie e quali versioni influenzeranno come si definisce un RestTemplate nella classe @Configuration.

Primavera> = 4, senza molla di avvio

sufficiente definire un @Bean:

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

Primavera Boot < = 1,3

Non c'è bisogno di definire uno, Primavera di avvio definisce automaticamente uno per te.

Primavera Boot> = 1.4

Primavera di avvio non è più definisce automaticamente un RestTemplate ma invece definisce un RestTemplateBuilder che consente un maggiore controllo sul RestTemplate che viene creato. È possibile iniettare il RestTemplateBuilder come un argomento nel metodo @Bean per creare un RestTemplate:

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

di utilizzare con la classe

@Autowired 
private RestTemplate restTemplate; 

Reference