The spring boot exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type available and org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type defined occurs when the bean is not available or defined while auto-wired in another class. If the bean is not available when the spring boot bean is annotated by @Autowired from the spring boot ApplicationContext, this exception will be thrown from the application.
The spring boot application can insert the bean either by class type or by Java naming convention. If none of them matches, the exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type will be thrown.
If the Java class is not loaded in the context of the spring boot, the exception will be thrown. The java class should be configured with annotations like @Component, @Service, @Repository, @Controller. Or the bean class can be annotated by @Bean in the @Configuration class.
In spring boot, BeanFactory loads all the java beans in the spring boot application context. If BeanFactory unable to load any java bean, this exception “org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type available” is thrown in the console log at the start of the spring boot application.
Exception
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)}
Root Cause
Dependency injection is one of the features of the spring boot. Spring boot loads all the beans into the ApplicationContext and dependent beans are injected. If any bean is not available or unable to inject a bean, The exception NoSuchBeanDefinitionException is thrown. The reason could be either that the bean is not available or that it is not possible to locate the bean or that an error occurred while injecting the bean.
Solution 1 – Bean Not Available in ApplicationContext
If the java class is trying to inject another class and the injection class is not available at the spring boot ApplicationContext, the NoSuchBeanDefinitionException exception will be thrown. In the example below, the Zoo class is trying to inject the Lion class into it. The Lion class is not available as spring boot bean, the NoSuchBeanDefinitionException has occurred.
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
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)}
Solution
The error is “expected at least 1 bean which qualifies as autowire candidate.” The solution is to add the injection class in the ApplicationContext using annotation @Component. The exception “NoSuchBeanDefinitionException: No qualifying bean of type” is resolved if the annotation @Component is added in the Lion class. The example below shows an exception fix using @Component annotation.
package com.yawintutor;
import org.springframework.stereotype.Component;
@Component
public class Lion {
// .....
}
Solution 2 – Bean Not Loaded in ApplicationContext
The injected bean is added with annotation @Component, still the exception NoSuchBeanDefinitionException is thrown in the spring boot application. This is due to the java bean is not loaded in the ApplicationContext. In the example below, the Zoo class is trying to inject the Lion class bean into it. The Lion class has annotation @Component, still, the NoSuchBeanDefinitionException 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
The error is “expected at least 1 bean which qualifies as autowire candidate.” The solution is to add the injection class in the ApplicationContext using annotation @ComponentScan. The spring boot main class should be as root package.
In this example, there are two packages called “com.yawintutor” and “com.yawin.” The Lion class is not created under the “com.yawintutor” root package. The Lion class that is not created under the root package will not be loaded by the spring boot. The @ComponentScan annotation will include packages that are explicitly required to load the bean in the spring boot context.
The exception “NoSuchBeanDefinitionException: No qualifying bean of type” is resolved if the annotation @ComponentScan is added to the Zoo class. The example below shows an exception fix using @ComponentScan annotation.
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 – Implementation class not available for Interface
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 NoSuchBeanDefinitionException.
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 – Found Multiple Implemented Class for Interface
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 NoSuchBeanDefinitionException.
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 – No bean named available
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 is NoSuchBeanDefinitionException.
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 “NoSuchBeanDefinitionException: No bean named available”. 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);
}
}