Why is Spring not throwing NoSuchBeanDefinitionException
where there are ambiguous dependencies and more than one bean candidates found for autowiring using @Autowired
annotation ?
I have this simple beans.xml that has two same beans with different ids category
and category1
and for some reason Spring
picks the category
bean for autowiring. I was under the impression that @Autowired
annotation uses byType
autowiring internally
and since here there are more than one matches found here Spring will throw NoSuchBeanDefinitionException
exception.
I am using spring version 3.2.13.RELEASE
here.
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans
..... ">
<context:annotation-config />
<bean id="product" class="com.study.spring.Product">
<property name="id" value="101"/>
<property name="name" value="Apple iPhone"/>
<property name="active" value="true"/>
</bean>
<bean id="category1" class="com.study.spring.Category">
<property name="id" value="202"/>
<property name="name" value="Phone"/>
<property name="active" value="true"/>
</bean>
<bean id="category" class="com.study.spring.Category">
<property name="id" value="201"/>
<property name="name" value="Communications"/>
<property name="active" value="true"/>
</bean>
</beans>
Product.java
package com.study.spring;
import org.springframework.beans.factory.annotation.Autowired;
public class Product {
private int id;
private String name;
private boolean active;
@Autowired
private Category category;
//getters and setters here
}
It takes the Category
object with the id category
because it matches the name of the field. The old spring documentation explain this as:
"For a fallback match, the bean name is considered as a default qualifier value."
The current documentation explains this a bit clearer. You have a "byName" autowiring situation here:
Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master, and uses it to set the property.