自動裝配Bean屬性
3種類型的自動裝配
Spring提供幾種技巧用于減少XML的配置數量:
- 自動裝配(autowiring)有助于減少甚至消除配置<property>元素和<constructor-arg>元素,讓Spring自動識别如何裝配Bean的依賴關系。
- 自動檢測(autodiscovery)比自動裝配更進一步,讓Spring能自動識别哪些類需要被自動裝配成Spring Bean,進而減少<Bean>元素的使用。
Spring的三種自動裝配政策:
- byName:把與Bean屬性具有相同名字或者ID的其他Bean自動裝配到對應的屬性中,如果沒有,該屬性不被裝配。
- 通過設定autowire屬性為byName,為屬性自動裝配ID與該屬性名字相同的Bean。
- byType:把與Bean的屬性具有相同類型的其他Bean自動裝配的Bean對應的屬性當中去,若沒有,該屬性不被裝配。
- 通過設定autowire屬性為byType,為屬性自動裝配類型與該屬性類型相同的Bean。
- 限制:應用隻允許存在一個Bean與自動裝配的的屬性類型相比對。
- 使用<bean>元素的primary屬性屬性為自動裝配辨別一個首選Bean;為了使用primary屬性,要将所有非首選Bean的primary屬性設定為false。
- 通過設定<bean>元素的autowire-candidate屬性為false,可以在自動裝配時排除某些Bean。
- constructor:把與Bean的構造器入參具有相同類型的其他Bean自動裝配到Bean構造器的對應入參中。
- 通過設定autowire屬性為constructor,在構造器注入配置Bean時,可以移除<constructor-arg>元素,由Spring在應用上下文自動選擇Bean注入到構造器入參中。
- 和byType自動裝配有相同的限制,應用隻允許存在一個Bean與自動裝配的的屬性類型相比對。
預設自動裝配
如果需要為Spring應用上下文中的多數Bean配置相同的autowire屬性,可以讓Spring為它所建立的所有Bean應用相同的自動裝配政策來簡化配置。
在配置檔案的根元素<beans>上增加default-autowire屬性,可以将default-autowire屬性設定為任意一種有效的自動裝配政策,将其應用與Spring配置檔案中的所有Bean。
可以在一個Spring應用上下文中定義多個配置檔案,每個配置檔案都可以有自己預設的自動裝配政策。
<bean>元素的autowire屬性可以覆寫<benas>所配置的預設自動裝配政策。
混合使用自動裝配和自動裝配
對某個Bean設定了自動裝配政策後,仍然可以為任意一個屬性配置<property>元素進行顯示裝配。
混合使用自動裝配和自動裝配,可以解決使用byType自動裝配政策可能産生的裝配不确定性問題。
使用示例
先給出一個飛彈接口(IMissile),接口中隻有一個發射的方法
package com.li.autowire;
/*飛彈接口*/
public interface IMissile {
void fire();
}
在給出一個飛彈類,該類實作了飛彈接口
package com.li.autowire;
/*飛彈類,實作飛彈接口*/
public class Missile implements IMissile {
@Override
public void fire() {
System.out.println("The missile is fired...");
}
}
随後是一個無人機類,無人機可以裝載飛彈,我們直接在該類中進行測試
package com.li.autowire;
import java.io.File;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*無人機類*/
public class Uav {
/*無人機裝配有飛彈*/
private IMissile missile;
public IMissile getMissile() {
return missile;
}
public void setMissile(IMissile missile) {
this.missile = missile;
}
public Uav(IMissile missile) {
super();
this.missile = missile;
}
public Uav() {
super();
}
public void attack() {
missile.fire();
}
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("com"+File.separator+"li"+File.separator+"autowire"+File.separator+"uav.xml");
Uav uav1=(Uav)ctx.getBean("uav");
uav1.attack();
Uav uav2=(Uav)ctx.getBean("uav1");
uav2.attack();
}
}
Spring XML配置檔案(不使用自動裝配)
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引用Spring的多個Schema空間的格式定義檔案 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="missile" class="com.li.autowire.Missile"></bean>
<bean id="uav" class="com.li.autowire.Uav">
<property name="missile" ref="missile"></property>
</bean>
<!-- 對同一個類配置不同的Bean -->
<bean id="uav1" class="com.li.autowire.Uav">
<constructor-arg ref="missile"></constructor-arg>
</bean>
</beans>
Spring XML配置檔案(使用自動裝配)
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引用Spring的多個Schema空間的格式定義檔案 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="missile" class="com.li.autowire.Missile"></bean>
<bean id="uav" class="com.li.autowire.Uav" autowire="byName">
</bean>
<!-- 對同一個類配置不同的Bean -->
<bean id="uav1" class="com.li.autowire.Uav" autowire="constructor">
</bean>
</beans>