Spring_Autowiring collaborators
在Spring3.2.2中自動裝配類型,分別為:no(default)(不采用自動裝配)、 byName,byType,constructor下面來分別介紹一下這些是如何自動裝配的
<bean id="foo" class="...Foo" autowire="autowire type">
Mode Explanation
no: (Default) No autowiring. Bean references must be defined via a ref element.
Changing the default setting is not recommended for larger deployments,
because specifying collaborators explicitly gives greater control and clarity.
To some extent, it documents the structure of a system.
byName: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.
byType:Allows a property to be autowired if exactly one bean of the property type exists in the container.
If more than one exists, a fatal exception is thrown,
which indicates that you may not use byType autowiring for that bean.
If there are no matching beans, nothing happens; the property is not set.
constructor:Analogous to byType, but applies to constructor arguments.
If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised
案例分析:
1、創建CumputerBean類
package www.csdn.spring.autowire.bean; public class CumputerBean { // 電腦名稱 private String name; public void setName(String name) { this.name = name; } }
package www.csdn.spring.autowire.bean; public class CumputerBean { // 電腦名稱 private String name; public void setName(String name) { this.name = name; } }
2、創建DeptBean 類
package www.csdn.spring.autowire.bean; public class DeptBean { //部門名稱 private String name; public void setName(String name) { this.name = name; } }
package www.csdn.spring.autowire.bean; public class DeptBean { //部門名稱 private String name; public void setName(String name) { this.name = name; } }
3、創建EmployeeBean
package www.csdn.spring.autowire.bean; public class EmployeeBean { private DeptBean deptBean; private CumputerBean cumputerBean; public void setDeptBean(DeptBean deptBean) { this.deptBean = deptBean; } public void setCumputerBean(CumputerBean cumputerBean) { this.cumputerBean = cumputerBean; } @Override public String toString() { return "EmployeeBean [deptBean=" + deptBean + ", cumputerBean=" + cumputerBean + "]"; } }
package www.csdn.spring.autowire.bean; public class EmployeeBean { private DeptBean deptBean; private CumputerBean cumputerBean; public void setDeptBean(DeptBean deptBean) { this.deptBean = deptBean; } public void setCumputerBean(CumputerBean cumputerBean) { this.cumputerBean = cumputerBean; } @Override public String toString() { return "EmployeeBean [deptBean=" + deptBean + ", cumputerBean=" + cumputerBean + "]"; } }
首先分析no、byName、byType的配置都是采用setter方法依賴注入實現的案例
1、no配置(通過ref=”” 引用需要的bean)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 去匹配--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean"> <property name="cumputerBean" ref="cumputerBean" /> <property name="deptBean" ref="deptBean" /> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 去匹配--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean"> <property name="cumputerBean" ref="cumputerBean" /> <property name="deptBean" ref="deptBean" /> </bean> </beans>
2、byName配置(分析:會根據EmployeeBean中屬性的名稱 自動裝配)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="byName" /> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="byName" /> </beans>
3、byType配置(分析:會根據EmployeeBean中屬性的類型 自動裝配)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 去匹配--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="byType" /> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 去匹配--> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="byType" /> </beans>
注意:當根據byType類型裝配時,當在容器內找到多個匹配的類型時會出現如下 bug
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'employeeBean' defined in class path resource [spring-byType.xml]: Unsatisfied dependency expressed through bean property 'deptBean': :
No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined: expected single matching bean but found 2: deptBean,deptBean1;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined: expected single matching bean but found 2: deptBean,deptBean1
4、Constructor(構造器參數根據byType類型匹配,自動裝配)
首先修改EmployeeBean類 修改後代碼如下:
package www.csdn.spring.autowire.bean; public class EmployeeBean { private DeptBean deptBean; private CumputerBean cumputerBean; public EmployeeBean(DeptBean deptBean, CumputerBean cumputerBean) { super(); this.deptBean = deptBean; this.cumputerBean = cumputerBean; } @Override public String toString() { return "EmployeeBean [deptBean=" + deptBean + ", cumputerBean=" + cumputerBean + "]"; } }
package www.csdn.spring.autowire.bean; public class EmployeeBean { private DeptBean deptBean; private CumputerBean cumputerBean; public EmployeeBean(DeptBean deptBean, CumputerBean cumputerBean) { super(); this.deptBean = deptBean; this.cumputerBean = cumputerBean; } @Override public String toString() { return "EmployeeBean [deptBean=" + deptBean + ", cumputerBean=" + cumputerBean + "]"; } }
配置文件操作:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
說明:
1、當構造器的參數類型在容器中找不全時。
比如:
配置文件中只 配置了CumpterBean時
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
會出現如下bug:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'employeeBean' defined in class path resource [spring-constructors.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [www.csdn.spring.autowire.bean.DeptBean]: :
No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] 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 qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
2、 當配置文件找到構造器參數的類型有多個的時候比如配置文件如下:
<?xml version="1.0" encoding="UTF- 8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 部門bean --> <bean id="deptBean1" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 部門bean --> <bean id="deptBean1" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
說明:上面配置有兩個同樣類型的DeptBean但是不會出現bug,原因是在EmployeeBean中構造器接 受的參數名稱與deptBean一致。
3、當配置文件找到構造器參數的類型有多個的時候比如配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean1" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 部門bean --> <bean id="deptBean2" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 電腦bean --> <bean id="cumputerBean" class="www.csdn.spring.autowire.bean.CumputerBean"> <property name="name" value="HP6325筆記本" /> </bean> <!-- 部門bean --> <bean id="deptBean1" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 部門bean --> <bean id="deptBean2" class="www.csdn.spring.autowire.bean.DeptBean"> <property name="name" value="CSDN教育事業部" /> </bean> <!-- 員工bean 根據EmployeeBean中的 屬性名稱 bytype 去匹配 --> <bean id="employeeBean" class="www.csdn.spring.autowire.bean.EmployeeBean" autowire="constructor"> </bean> </beans>
會出現如下bug(與byType的bug一 致):
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'employeeBean' defined in class path resource [spring- constructors.xml]:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'employeeBean' defined in class path resource [spring- constructors.xml]:
Unsatisfied dependency expressed through constructor argument with index 0 of type [www.csdn.spring.autowire.bean.DeptBean]: : No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined: expected single matching bean but found 2: deptBean1,deptBean2; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined:
Unsatisfied dependency expressed through constructor argument with index 0 of type [www.csdn.spring.autowire.bean.DeptBean]: : No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined: expected single matching bean but found 2: deptBean1,deptBean2; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [www.csdn.spring.autowire.bean.DeptBean] is defined:
expected single matching bean but found 2: deptBean1,deptBean2