NoSuchBeanDefinitionException: No qualifying bean of type

In this article, we discuss about the spring boot exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type available. and “org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named available” If any bean creation failed in spring boot application context, the exception “NoSuchBeanDefinitionException: No qualifying bean of type available” is thrown by spring boot BeanFactory.

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



Related Articles

Leave a Reply

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