Springブートアプリケーションでフィールド:RestTemplateを自動配線できませんでした


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

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

    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 2016年

賛成-Spring Boot独自のページのチュートリアルでは、RestTemplate Beanの作成について何も言われていません。
マット

回答:


174

それはまさにエラーが言うことです。RestTemplateBeanを作成しなかったため、自動配線できません。必要なRestTemplate場合は、提供する必要があります。たとえば、以下をTestMicroServiceApplication.javaに追加します。

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

EurekaのSpringクラウドスターターの以前のバージョンでは、RestTemplateBeanが作成されていましたが、これは当てはまりません。


お返事ありがとうございます。これは役に立ちました!
Khuzi 2016年

19
質問と回答の原因を賛成しましたRestTemplate他のすべてが魔法のように作成されてリンクされているときに手動でを作成する必要があることは明らかではありません。特に、以前に自動設定されたを提供するspring-cloudを使用した場合RestTemplate。;-)
daniel.eichten 2016年

2
正直なところ、それが私がこの問題をフォーラムに投稿した理由です。RestTemplateがリンクされることを期待していました。:-) POM.xmlにEurekaの依存関係を含めた場合、これは正常に機能していました。RestTemplate Beanを定義しなくても問題なく動作しました。ユーレカのクラスの1つがこのBeanを定義した可能性があります。
Khuzi 2016年

4
ただのアップデート。Spring Boot 1.4.0以降 RestTemplateBuilderは、RestTemplateインスタンスの管理に使用できます。ここの例spring.io/guides/gs/sumption-rest
Mensur

SB 1.4.0にアップグレードできません。1.3.8.RELEASEでこれを実行したいのですが、@ g00glen00bソリューションではうまくいきませんでした。私はspring-cloud-netflixversionでArtifactid も使用しています1.1.5.RELEASE。RestTemplateは、@RestControllerを使用するJavaクラスから呼び出され@AutowiredていRestTemplateます。誰か助けてもらえますか?
ZeroGraviti 2016年

33

使用しているテクノロジーとバージョンによってRestTemplate@Configurationクラスでのの定義方法に影響します。

Spring> = 4、Spring Bootなし

単に定義する@Bean

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

スプリングブーツ<= 1.3

定義する必要はありません。SpringBootが自動的に定義します。

スプリングブート> = 1.4

Spring Bootは自動的に定義するのでRestTemplateはなく、RestTemplateBuilder作成されるRestTemplateをより詳細に制御できるように定義します。メソッドの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は、Beanがコンテキストで定義されておらず、Beanをロードできないことを直接示しています。

  1. RestTemplateのBeanを定義して使用する
  2. RestTemplateの新しいインスタンスを使用する

BeanがRestTemplateに対して定義されていることが確実な場合は、以下を使用して、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);
}

これに指定された名前/タイプのBeanが含まれている場合は、すべて問題ありません。または、新しいBeanを定義して使用します。


1

RestTemplateインスタンスは使用する前にカスタマイズする必要があることが多いため、Spring Bootは自動構成された単一のRestTemplate Beanを提供していません。

RestTemplateBuilderは、たとえば基本的な認証やインターセプターなど、残りのテンプレートBeanを適切に設定およびインスタンス化する方法を提供します。

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


0

次の2つを確認してください。

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

以下のコードを使用して同様の偉業を達成することができた最も簡単な方法(参照)ですが、コントローラー(SOLID原則)でAPI呼び出しを行わないことをお勧めします。また、この方法での自動配線は、従来の方法よりも最適化されています。

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を注入しようとしていますが、構成クラスを作成する必要があります。次に、新しいRestTemplateを返すBeanを作成する必要があります。以下の例を参照してください。

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


@Configuration
public class YourConfigClass {


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

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.