NoSuchBeanDefinitionException: No bean named available

In this article, we are discussing about the spring boot exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named available and org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named is defined. If any error occurred while injecting the spring boot bean programmatically from the spring boot ApplicationContext, This exception will be thrown from the application.

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 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 3

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

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



Related Articles

Leave a Reply

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