The spring boot exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named available and org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named is defined happens when you try to access a bean that is not available or is not defined in the spring boot context. If the bean is not available when injecting the spring boot bean programmatically 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 bean named available 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.

If two or more implementation available for an interface, injecting the interface is not possible. The annotation @Qualifier is required to specify the implementation class. In this article, we see about how to get bean with class and qualifier programmatically using Application context.



Exception

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:15)


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 from the ApplicationContext, The exception NoSuchBeanDefinitionException: No bean named available is thrown. 



Solution 1

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:15)

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


Solution 2

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.

package com.yawintutor;

import org.springframework.stereotype.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("lion", Lion.class);
	}
}

Output

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'lion' 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:15)

Solution

The class Lion is annotated with @Component. The spring boot will load Lion class using the annotation @Component.

package com.yawintutor;

import org.springframework.stereotype.Component;

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


Solution 3

If a spring boot bean is loaded programmatically using ApplicationContext in the @Component class and the injecting bean is not available or unable to load from ApplicationContext, the exception “NoSuchBeanDefinitionException: No bean named available” is thrown.

The example below shows how to inject the spring boot bean using ApplicationContext. The Lion class is injected in the Zoo class. The exception is thrown as the bean name of the Lion class is wrong.

package com.yawintutor;

import org.springframework.stereotype.Component;

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

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

@Component
public class Zoo implements InitializingBean {
	@Autowired
	private ApplicationContext applicationContext;
	
	@Override
	public void afterPropertiesSet() {
		applicationContext.getBean("lion1");
	}
}

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.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class Zoo implements InitializingBean {
	@Autowired
	private ApplicationContext applicationContext;
	
	@Override
	public void afterPropertiesSet() {
		applicationContext.getBean("lion");
	}
}


Solution 4

If the above of two solution is not fixing the NoSuchBeanDefinitionException exception, then follow the below url. This link shows solutions for beans that are not loaded in the application context. The link is

NoSuchBeanDefinitionException: No qualifying bean of type available

The NoSuchBeanDefinitionException is thrown due to other reasons such as No qualifying bean of type. The above link contains solutions for other reasons.



Solution 4 – Load bean with class and qualifier programmatically

If two or more implemented class is available for an interface and the interface is injected using ApplicationContext, the interface will not be injected. In the @Component class, the annotation @Qualifier is used to specify the implemented class to load in the interface. When loading the interface programmatically using the ApplicationContext, it is not possible to specify the @Qualifier annotation.

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.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class Zoo implements InitializingBean {
	@Autowired
	private ApplicationContext applicationContext;
	
	@Override
	public void afterPropertiesSet() {
		applicationContext.getBean("animal");
	}
}

The application context class provides api to get bean using qualifier. This has to be done in two steps as shown below. The first api is getBeansOfType() and next call is get(). The example below shows how to get bean with class and qualifier programmatically.

package com.yawintutor;

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

@Component
public class Zoo implements InitializingBean {
	@Autowired
	private ApplicationContext applicationContext;
	
	@Override
	public void afterPropertiesSet() {
		applicationContext.getBeansOfType(Animal.class).get("lion");
	}
}



Leave a Reply