How to autowire RestTemplate using annotations

Spring boot error required a bean of type ‘org.springframework.web.client.RestTemplate’ that could not be located. occurs when the RestTemplate is auto-wired without bean creation. The RestTemplate cannot be auto-wired without specifying the bean creation configuration. Spring boot can not find the RestTemplate as it could not be found in the loaded bean. If you autowire RestTemplate using annotations without the bean creation configuration, the error required a bean of type ‘org.springframework.web.client.RestTemplate’ that could not be located. will be thrown.

The RestTemplate bean must be loaded before the autowire RestTemplate using annotations. There are a number of ways to build RestTemplate Bean. Create a configuration to create a RestTemplate bean, then autowire RestTemplate use annotations . This error is not going to occur.



Exception

The exception below will occur at the start of the spring boot application. The stack trace of the exception will be shown as like below

2020-10-07 07:15:11.703  WARN 44038 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testController': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2020-10-07 07:15:11.705  INFO 44038 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2020-10-07 07:15:11.715  INFO 44038 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-10-07 07:15:11.780 ERROR 44038 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field restTemplate in com.yawintutor.TestController required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.


How to recreate this exception

If you autowire RestTemplate using annotations without bean definition configuration of the RestTemplate bean, spring boot application could not found the RestTemplate Bean. Hence, the exception will be thrown at the start of the spring boot application.

package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {
	
	@Autowired
	RestTemplate restTemplate;
	
	@GetMapping(value = "/student")
	public Student getStudent() {
		return new Student(1, "name1");
	}

	@GetMapping(value = "/getstudent")
	private Student getStudentObject()
	{
		String uri = "http://localhost:8080/student";
	    Student result = restTemplate.getForObject(uri, Student.class);
	    return result; 
	}
}

Output

***************************
APPLICATION FAILED TO START
***************************

Description:

Field restTemplate in com.yawintutor.TestController required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.


Solution 1

The simple solution for creating the RestTemplate is to create the RestTemplate object before calling the restTemplate. The RestTemplate object is created before the rest call is called and destroyed after the rest call is completed. Spring boot will not manage the RestTemplate object.

package com.yawintutor;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {
	
	@GetMapping(value = "/student")
	public Student getStudent() {
		return new Student(1, "name1");
	}

	@GetMapping(value = "/getstudent")
	private Student getStudentObject()
	{
	    String uri = "http://localhost:8080/student";
	    RestTemplate restTemplate = new RestTemplate();
	    Student result = restTemplate.getForObject(uri, Student.class);
	    return result; 
	}
}	


Solution 2

The RestTemplate will be created by using the @Bean annotation. If the rest template is used in a single class, this method would be sufficient. Create a RestTemplate using the @Bean annotation and load the bean in the class using the autowire annotation.

package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {
	
	@Autowired
	RestTemplate restTemplate;
	
	@GetMapping(value = "/student")
	public Student getStudent() {
		return new Student(1, "name1");
	}

	@GetMapping(value = "/getstudent")
	private Student getStudentObject()
	{
		String uri = "http://localhost:8080/student";
	    Student result = restTemplate.getForObject(uri, Student.class);
	    return result; 
	}
	
	@Bean
	public RestTemplate restTemplate() {
	    return new RestTemplate();
	}
}


Solution 3

If the RestTemplate is used in several places in the application, the RestTemplate bean should be created in the @Configuration class. The bean will be created to start the spring boot application. The RestTemplate bean will be reused in the application.

RestTemplateConfiguration.java

package com.yawintutor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

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

TestController.java

package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {
	
	@Autowired
	RestTemplate restTemplate;
	
	@GetMapping(value = "/student")
	public Student getStudent() {
		return new Student(1, "name1");
	}

	@GetMapping(value = "/getstudent")
	private Student getStudentObject()
	{
	    String uri = "http://localhost:8080/student";
	    Student result = restTemplate.getForObject(uri, Student.class);
	    return result; 
	}
}



Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *