Field in required a bean of type that could not be found

The spring boot exception Field in required a bean of type that could not be found occurs when a field in the class is auto-wired as a bean type that could not be found in the spring boot context. The auto-wired class will be injected in the spring boot when the application starts. If the bean class could not be auto-wired in another class, the exception Field in required a bean of type that could not be found will be thrown.

The spring boot bean could not be found because the bean is not loaded or available in the spring boot context. You can use an annotation such as @Component, @Service, @Repository, @Controller to load in the spring boot context. If the java class is not annotated with any of the above annotations, the exception Field in required a bean of type that could not be found will be thrown.

If the java class is loaded as a bean class, it should be annotated by @Bean in the @Configuration class. The @Bean annotated method will be used to create and load the bean in the spring boot context.

The spring boot application auto-wire a bean based on either the class type or the variable name with java naming convention. If none of them matches, the exception will be thrown.



Exception

The exception Field in required a bean of type that could not be found stack trace would be similar to the one seen below.

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

Description:

Field lion in com.yawintutor.Zoo required a bean of type 'com.yawintutor.Lion' 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 'com.yawintutor.Lion' in your configuration.


Root Cause

When the spring boot application is starting, the Spring boot application loads the beans into the ApplicationContext. Subsequently, the dependent beans are added to produce other types of beans. When no bean is available or cannot be injected into another bean, an exception will be thrown. Depency injections can be made using the @AutoWired annotation.



Solution 1

If the spring boot bean class is attempting to inject another bean class and the injection bean class is not available at the spring boot ApplicationContext, the exception will be thrown. The Zoo class, in the case below is attempting to insert the Lion class into it. The Lion class is not available as a spring boot bean, the exception “Field lion in com.yawintutor.Zoo required a bean of type ‘com.yawintutor.Lion’ that could not be found.” has been thrown.

package com.yawintutor;

public class Lion {
	// .....
}
package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Zoo {
	@Autowired
	Lion lion;
}

Output

2020-12-09 07:01:32.358  WARN 90767 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'zoo': Unsatisfied dependency expressed through field 'lion'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.yawintutor.Lion' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2020-12-09 07:01:32.365  INFO 90767 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-09 07:01:32.390 ERROR 90767 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Field lion in com.yawintutor.Zoo required a bean of type 'com.yawintutor.Lion' 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 'com.yawintutor.Lion' in your configuration.

Solution

package com.yawintutor;

import org.springframework.stereotype.Component;

@Component
public class Lion {
	// .....
}


Solution 2

The spring boot bean class with annotation @Component etc cannot be loaded in the spring boot context. It is also not available in the auto-wired fields. The bean class could be created in a different package that is not part of a component scan. In the example below the Zoo class is attempting to insert bean into the Lion class. The Lion class has a @Component annotation, but the exception has occurred.

package com.yawin;

import org.springframework.stereotype.Component;

@Component
public class Lion {
	// .....
}
package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Zoo {
	@Autowired
	Lion lion;
}

Output

s.c.a.AnnotationConfigApplicationContext : 
Exception encountered during context initialization - cancelling refresh attempt: 
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'zoo': 
Unsatisfied dependency expressed through field 'lion'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'com.yawin.Lion' available: 
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

Solution

In the example below the Lion class is created with the com.yawin package. The Zoo class is created in the com.yawintutor package. The spring boot application starts and loads classes from its root com.yawintutor package. Although the com.yawin package is different, the Lion class is not loaded in the context of the spring boot application. The @ComponentScan annotation is used in the spring boot application to load the com.yawin package classes.

package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

@Component
@ComponentScan("com.yawin")
public class Zoo {
	@Autowired
	Lion lion;
}


Solution 3

If an interface is created without an implementation class, and the spring boot attempts to inject the implemented class into the interface, the spring boot fails to auto-wire the interface. The example below shows the interface that throws an exception Field required a bean of type that could not be found.

package com.yawintutor;

public interface Animal {
	public String getName();
}
package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Zoo {
	@Autowired
	public Animal animal;
}

Output

s.c.a.AnnotationConfigApplicationContext : 
Exception encountered during context initialization - cancelling refresh attempt: 
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'zoo': 
Unsatisfied dependency expressed through field 'animal'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'com.yawintutor.Animal' available: 
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

Solution

The implementation class is not available in the spring boot context. Create an implementation class for the interface and make sure that it is available in the ApplicationContext as a spring boot bean. The example below shows the implementation class for the interface Animal class.

package com.yawintutor;

import org.springframework.stereotype.Component;

@Component
public class Lion implements Animal{

	@Override
	public String getName() {
		return "Lion";
	}
}


Solution 4

If an interface is created with multiple implementation classes, and the spring boot attempts to inject the implemented class into the interface, the spring boot fails to auto-wire the interface. The example below shows the interface that throws an exception “Field in required a bean of type that could not be found”.

package com.yawintutor;

public interface Animal {
	public String getName();
}
package com.yawintutor;

import org.springframework.stereotype.Component;

@Component
public class Lion implements Animal{
	@Override
	public String getName() {
		return "Lion";
	}
}
package com.yawintutor;

import org.springframework.stereotype.Component;

@Component
public class Tiger implements Animal{
	@Override
	public String getName() {
		return "Tiger";
	}
}
package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Zoo {
	@Autowired
	public Animal animal;
}

Solution

If two or more implementation classes are created for an interface, spring boot can not inject for the interface. The annotation @Qualifier is used to inform to the spring boot to inject the implemented class into the interface. The example below shows how to use annotation @Qualifier to inject an implemented class into an interface.

package com.yawintutor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Zoo {
	@Autowired
	@Qualifier("lion")
	public Animal animal;
}


Solution 5

If the bean is loaded manually from the Spring boot ApplicationContext, the bean name should be configured as per the Java naming convention. If the bean name is different, the exception “Field required a bean of type that could not be found” will be thrown.

package com.yawintutor;

import org.springframework.stereotype.Component;

@Component
public class Lion {
	// .....
}
package com.yawintutor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class SpringBootNoBeanApplication {

	public static void main(String[] args) {
		ApplicationContext ctx = SpringApplication.run(SpringBootNoBeanApplication.class, args);
		ctx.getBean("lion1", Lion.class);
	}
}

Output

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'lion1' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:808)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1279)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1114)
	at com.yawintutor.SpringBootNoBeanApplication.main(SpringBootNoBeanApplication.java:12)

Solution

In the above example, the bean name lion1 is not as per the java convention. Spring throws exception as “Field required a bean of type that could not be found”. Change the bean name as per the java convention will resolve this issue.

package com.yawintutor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class SpringBootNoBeanApplication {

	public static void main(String[] args) {
		ApplicationContext ctx = SpringApplication.run(SpringBootNoBeanApplication.class, args);
		ctx.getBean("lion", Lion.class);
	}
}



Related Articles

Leave a Reply

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