फ़ील्ड को स्वतः-लोड नहीं किया जा सका: स्प्रिंग बूट एप्लिकेशन में रिस्टेमप्लेट


109

स्टार्ट अप के दौरान स्प्रिंग बूट एप्लिकेशन चलाने के दौरान मुझे नीचे अपवाद मिल रहा है:

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

मैं अपने टेस्टकंट्रोलर में RestTemplate को स्वत: प्राप्त कर रहा हूं। मैं मावेन का उपयोग निर्भरता प्रबंधन के लिए कर रहा हूं।

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>

1
आपके प्रश्न के कारण को देखते हुए यह स्पष्ट नहीं है कि जब सब कुछ जादुई रूप से जुड़ा हुआ RestTemplateहै तो स्वचालित रूप से आपके लिए नहीं बनाया जाता है।
daniel.eichten

Upvoted - स्प्रिंग बूट के अपने पेज पर ट्यूटोरियल एक RestTemplate बीन बनाने के बारे में कुछ नहीं कहता है !!
मैट

जवाबों:


174

यह वही है जो त्रुटि कहता है। आपने कोई RestTemplateबीन नहीं बनाई , इसलिए यह किसी को भी रोक नहीं सकता है। यदि आपको जरूरत है RestTemplateतो आपको एक प्रदान करना होगा। उदाहरण के लिए, TestMicroServiceApplication.java के लिए निम्नलिखित जोड़ें :

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

ध्यान दें, यूरेका के लिए स्प्रिंग क्लाउड स्टार्टर के पुराने संस्करणों में, आपके लिए एक RestTemplateसेम बनाया गया था, लेकिन यह अब सच नहीं है।


उत्तर के लिए आपका बहुत - बहुत धन्यवाद। इससे मदद मिली!
ख़ुजी

19
प्रश्न और आपके उत्तर का कारण बना है यह स्पष्ट नहीं है कि आपको मैन्युअल रूप से बनाना होगा RestTemplateजब बाकी सब कुछ जादुई तरीके से बनाया गया हो और आपके लिए जुड़ा हो। खासतौर पर अगर कोई स्प्रिंग-क्लाउड का इस्तेमाल करता है, जो ऑटोकैफिगर करता है RestTemplate। ;-)
daniel.eichten

2
ईमानदारी से, यही कारण था कि मैंने इस मुद्दे को यहाँ मंच पर रखा। मैं उम्मीद कर रहा था कि रेस्टेमप्लेट मेरे लिए लिंक किया जाएगा। :-) यह ठीक काम कर रहा था जब मैंने यूरेका निर्भरता को POM.xml में शामिल किया था। रेस्टेमप्लेट बीन को परिभाषित किए बिना यह ठीक काम कर रहा था। यूरेका की एक कक्षा ने इस बीन को परिभाषित किया होगा।
ख़ुजी

4
बस एक अद्यतन। स्प्रिंग बूट से 1.4.0 RestTemplateBuilderका उपयोग RestTemplateइंस्टेंस के प्रबंधन के लिए किया जा सकता है । उदाहरण यहाँ spring.io/guides/gs/consuming-rest
Mensur

मैं अभी तक एसबी 1.4.0 में अपग्रेड नहीं कर सकता। मैं 1.3.8 के साथ यह करना चाहता हूं। कृपया लेकिन @ g00glen00b समाधान मेरे लिए काम नहीं किया। मैं spring-cloud-netflixसंस्करण के साथ कलाकृतियों का भी उपयोग कर रहा हूं 1.1.5.RELEASE। My RestTemplate को @RestControllerjava क्लास से बुलाया जा रहा है जो इसके लिए उपयोग करता @Autowiredहै RestTemplate। क्या कोई मदद कर सकता है?
जीरोग्रिटी

33

इस बात पर निर्भर करता है कि आप किन तकनीकों का उपयोग कर रहे हैं और कौन से संस्करण प्रभावित करेंगे कि आप RestTemplateअपनी @Configurationकक्षा में कैसे परिभाषित करते हैं ।

स्प्रिंग बूट के बिना स्प्रिंग> = 4

बस एक परिभाषित करें @Bean:

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

स्प्रिंग बूट <= 1.3

एक को परिभाषित करने की आवश्यकता नहीं है, स्प्रिंग बूट स्वचालित रूप से आपके लिए परिभाषित करता है।

स्प्रिंग बूट> = 1.4

स्प्रिंग बूट अब स्वचालित रूप से परिभाषित नहीं करता है, RestTemplateबल्कि RestTemplateBuilderआपको बनाए गए रेस्टेमप्लेट पर अधिक नियंत्रण की अनुमति देता है। आप RestTemplateBuilderअपनी @Beanविधि में तर्क के रूप में इंजेक्ट कर सकते हैं RestTemplate:

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

अपनी कक्षा में इसका उपयोग करना

@Autowired
private RestTemplate restTemplate;

संदर्भ


8

यदि आपके यूनिट परीक्षण में TestRestTemplate एक वैध विकल्प है, तो यह प्रलेखन प्रासंगिक हो सकता है

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

संक्षिप्त उत्तर: यदि उपयोग कर रहे हैं

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

तब @Autowiredकाम करेगा। अगर उपयोग कर रहे हैं

@SpringBootTest(webEnvironment=WebEnvironment.MOCK)

फिर इस तरह TestRestTemplate बनाएं

private TestRestTemplate template = new TestRestTemplate();

1

त्रुटि सीधे इंगित करती है कि RestTemplateबीन को संदर्भ में परिभाषित नहीं किया गया है और यह सेम को लोड नहीं कर सकता है।

  1. RestTemplate के लिए एक बीन को परिभाषित करें और फिर इसका उपयोग करें
  2. RestTemplate के एक नए उदाहरण का उपयोग करें

यदि आप सुनिश्चित हैं कि सेम को रेन्स्टेमप्लेट के लिए परिभाषित किया गया है, तो स्प्रिंग बूट एप्लिकेशन द्वारा लोड किए गए संदर्भ में उपलब्ध फलियों को प्रिंट करने के लिए निम्नलिखित का उपयोग करें

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

यदि इसमें दिए गए नाम / प्रकार से बीन शामिल है, तो सभी अच्छे हैं। या फिर एक नई बीन को परिभाषित करें और फिर इसका उपयोग करें।


1

चूंकि RestTemplate उदाहरणों को अक्सर उपयोग किए जाने से पहले अनुकूलित करने की आवश्यकता होती है, स्प्रिंग बूट किसी भी ऑटो-कॉन्फ़िगर RestTemplate बीन प्रदान नहीं करता है।

RestTemplateBuilder बुनियादी टेम्पलेट या इंटरसेप्टर के लिए उदाहरण के लिए, बाकी टेम्पलेट बीन को कॉन्फ़िगर और त्वरित करने का उचित तरीका प्रदान करता है।

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


0

कृपया दो चीजें सुनिश्चित करें:

1- @Beanविधि के साथ एनोटेशन का उपयोग करें ।

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
    return builder.build();
}

2- इस पद्धति का दायरा सार्वजनिक होना चाहिए न कि निजी

पूरा उदाहरण -

@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();
}
}

0

सबसे सरल तरीका मैं नीचे दिए गए कोड ( संदर्भ ) का उपयोग करने के लिए एक समान उपलब्धि हासिल करने में सक्षम था , लेकिन मैं नियंत्रकों ( ठोस सिद्धांतों ) में एपीआई कॉल नहीं करने का सुझाव दूंगा । साथ ही इस तरह से ऑटो करना, पारंपरिक तरीके से करने की तुलना में बेहतर है।

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";
    }
}

0

आप restTemplate को इंजेक्ट करने का प्रयास कर रहे हैं, लेकिन आपको कॉन्फ़िगरेशन वर्ग बनाने की आवश्यकता है। तब आपको बीन बनाने की आवश्यकता होती है जो आपको वापस लौटाता है नया रेस्टेमप्लेट नीचे का उदाहरण देखें।

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class YourConfigClass {


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

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.