The Spring Boot exception “org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type available” occurs when attempting to auto-wire a bean in another class, but the bean is either not available or not defined in the Spring application context. This exception is thrown when the @Autowired annotation is used, and Spring Boot fails to find a qualifying bean of the specified type within the ApplicationContext. The NoSuchBeanDefinitionException is raised if the required bean is not present or not correctly defined when attempting to use @Autowired to inject the bean into another component in a Spring Boot application. It is crucial to ensure that the bean is properly declared and available in the application context to prevent this exception.

In a Spring Boot application, beans can be injected using either the class type or Java naming conventions. If neither of these methods matches a qualifying bean within the application context, the exception “org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type” will be thrown. This exception indicates that Spring Boot could not find a bean that matches the specified criteria during the auto-wiring process.

If a Java class is not loaded into the context of the Spring Boot application, an exception will be thrown. To ensure that a Java class is recognized as a bean and available for injection, it should be appropriately configured with annotations such as @Component, @Service, @Repository, or @Controller. Alternatively, the bean class can be annotated with @Bean within a @Configuration class. These annotations inform Spring Boot about the intended use of the class as a bean and its specific role within the application context, allowing for proper bean initialization and injection. Failure to apply these annotations may result in the mentioned exception when attempting to use the class as a bean.

In Spring Boot, the BeanFactory is responsible for loading all the Java beans into the application context. If the BeanFactory encounters a situation where it cannot find or load a particular Java bean, it throws the exception “org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type available.” This exception is typically logged in the console output at the startup 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 a key feature of Spring Boot, where all beans are loaded into the ApplicationContext, and dependent beans are injected automatically. If Spring Boot encounters a situation where it cannot find or inject a particular bean, it throws the exception NoSuchBeanDefinitionException. The reasons behind this exception could be that the bean is not available in the ApplicationContext, it cannot be located, or an error occurred during the injection process. It is essential to ensure that the required beans are properly configured, annotated, and available in the application context to prevent such exceptions and ensure smooth dependency injection in Spring Boot applications.



Solution 1 – Bean Not Available in ApplicationContext

When a Java class attempts to inject another class, and the injection class is not present in the Spring Boot ApplicationContext, a NoSuchBeanDefinitionException is raised. In the following illustration, the Zoo class endeavors to inject the Lion class, which, in this case, is not configured as a Spring Boot bean. Consequently, the occurrence of the NoSuchBeanDefinitionException signals that the required bean, specifically the Lion class in this context, is not available in the Spring Boot application context. To rectify this issue, it is imperative to ensure proper bean configuration for all classes involved in dependency injection.

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 encountered is “expected at least 1 bean which qualifies as autowire candidate.” To resolve this issue, it is necessary to include the injection class in the ApplicationContext by using the @Component annotation. By adding the @Component annotation to the Lion class, the exception “NoSuchBeanDefinitionException: No qualifying bean of type” can be effectively addressed. The example below illustrates the solution by incorporating the @Component annotation to resolve the mentioned exception.

package com.yawintutor;

import org.springframework.stereotype.Component;

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

 



Solution 2 – Bean Not Loaded in ApplicationContext

Even with the injected bean annotated with @Component, the Spring Boot application continues to throw the NoSuchBeanDefinitionException exception. This issue persists because the Java bean is not loaded into the ApplicationContext. In the provided example, the Zoo class attempts to inject the Lion class bean, which is annotated with @Component. Despite this annotation, the NoSuchBeanDefinitionException still arises, indicating that the Lion class bean is not successfully loaded into the ApplicationContext.

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 encountered error is “expected at least 1 bean which qualifies as autowire candidate.” To address this issue, the solution involves adding the injection class to the ApplicationContext using the @ComponentScan annotation. It is crucial to ensure that the Spring Boot main class serves as the root package.

In the provided example, there exist two packages, namely “com.yawintutor” and “com.yawin.” Notably, the Lion class is not situated under the “com.yawintutor” root package. When a class is not created under the root package, it may not be loaded by Spring Boot. The @ComponentScan annotation becomes instrumental in explicitly specifying the packages required to load the bean into the Spring Boot context.

To resolve the NoSuchBeanDefinitionException: No qualifying bean of type exception, the @ComponentScan annotation should be applied to the Zoo class. The subsequent example demonstrates the resolution of the exception by incorporating the @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

When an interface is created without an implementation class, and Spring Boot attempts to inject the interface, it fails to auto-wire the interface, resulting in a NoSuchBeanDefinitionException exception. The absence of an implemented class for the interface makes it impossible for Spring Boot to fulfill the auto-wiring request. The following example illustrates the scenario where an interface triggers the NoSuchBeanDefinitionException exception:

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

To resolve the issue where the implementation class for the interface is not available in the Spring Boot context, it is necessary to create an implementation class for the interface and ensure that it is registered as a Spring Boot bean in the ApplicationContext. The following example demonstrates the creation of an implementation class Lion for the Animal interface:

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

When an interface is associated with multiple implementation classes, Spring Boot encounters challenges in auto-wiring the interface when attempting to inject one of the implemented classes. In such instances, the absence of clear resolution criteria may result in Spring Boot’s failure to perform the auto-wiring process. The example provided below exemplifies this scenario, where the interface triggers a NoSuchBeanDefinitionException exception:

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

When an interface has two or more implementation classes, Spring Boot may face challenges in injecting the interface. To resolve this ambiguity and specify which implementation class should be injected, the @Qualifier annotation is employed. The @Qualifier annotation provides explicit information to Spring Boot, guiding the injection process. The example below illustrates the usage of @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

When manually loading a bean from the Spring Boot ApplicationContext, it is essential to configure the bean name following Java naming conventions. If the bean name deviates from the expected convention, it may result in a NoSuchBeanDefinitionException exception.

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 given example, the bean name “lion1” does not adhere to Java naming conventions, leading to a thrown exception: “NoSuchBeanDefinitionException: No bean named available.” To resolve this issue, changing the bean name to align with Java conventions will address the exception.

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


Leave a Reply