Ad

Saturday 7 March 2015

No matching bean of type [] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency

In this post we will see how to resolve this exception-"NoSuchBeanDefinitionException:No matching bean of type [] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency" in spring.Click this  link to know about the autowire feature in spring and the various types.Coming back to our topic, this exception is thrown in the below scenario:
  1. When we  autowire the bean collaborators by constructor type,so that the spring container will resolve the bean dependencies automatically
  2. And there was  no bean declared or exist in the application context which is same as type of the constructor argument of the bean to be autowired.
Below code sample will explain this scenario.
  • Car- bean class for which the dependencies has to be resolved automatically by their constructor arguments type.
  • Engine - bean class which is set as the property of the Car object .
  • CarDemo -main class which will load the spring container and get the car bean from the container.
  • carcontext.xml - metadata configuration details for the spring container.
Car.java

package test;

public class Car {

private Engine engine=null;

public Car(Engine engine) {
super();
this.engine = engine;
}

public Engine getEngine() {
return engine;
}

@Override
public String toString() {
return "Car [engine=" + engine + "]";
}
}

Engine.java

package test;

public class Engine {

private int engineNumber;

private int engineCost;

public int getEngineNumber() {
return engineNumber;
}

public void setEngineNumber(int engineNumber) {
this.engineNumber = engineNumber;
}

public int getEngineCost() {
return engineCost;
}

public void setEngineCost(int engineCost) {
this.engineCost = engineCost;
}

@Override
public String toString() {
return "Engine [engineNumber=" + engineNumber + ", engineCost="
+ engineCost + "]";
}
}

carcontext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<bean id="car" class="test.Car" autowire="constructor">
</bean>

</beans>

As we can see in the application context file,we used the attribute autowire="constructor" to make the container to automatically inject and resolve the dependencies for the car bean.Since the Car bean has the constructor of argument type test.Engine,container will look for the bean of type "test.Engine" and inject the same.

CarDemo.java

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CarDemo {

public static void main(String[] args) {
ApplicationContext bf= new ClassPathXmlApplicationContext(new String[]{"carcontext.xml"});
Car car= bf.getBean("car",Car.class);
   System.out.println(car);
}

}


OUTPUT:

When we run the main program - CarDemo,we will get the below exception

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'car' defined in class path resource [carcontext.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [test.Engine]: : No matching bean of type [test.Engine] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [test.Engine] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray
(ConstructorResolver.java:730)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor
(ConstructorResolver.java:196)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance
(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean
(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject
(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton
(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons
(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization
(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh
(AbstractApplicationContext.java:464)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at test.CarDemo.main(CarDemo.java:9)

While autowiring the dependencies for the car bean by constructor arguments, container could not found a bean of type test.Engine and hence this exception was thrown.

To resolve this,make sure we declare a bean of type test.Engine in the application context file so that the container will inject the same to Car bean by autowiring.

<bean id="engine" class="test.Engine">
<property name="engineNumber" value="2301"/>
<property name="engineCost" value="120000"/>
</bean>

Now if we run the CarDemo with the above change in the carcontext.xml,we will get the expected output

Car [engine=Engine [engineNumber=2301, engineCost=120000]]

No comments:

Post a Comment