The required a bean of type ‘org.springframework.web.client.RestTemplate’ that could not be located. spring boot occurs when the RestTemplate is auto-wired without bean creation. The RestTemplate cannot be auto-wired unless the bean creation configuration is specified. Spring boot cannot locate the RestTemplate because it is not in the loaded bean. 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. RestTemplate Bean can be created in a variety of ways. Create a configuration to create a RestTemplate bean, then autowire RestTemplate using annotations. This error will not happen.



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 and destroyed when the rest call is finished. The RestTemplate object will not be managed by Spring Boot.

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



Leave a Reply