Spring 容器可自動解析 Bean 依賴關係,減少 XML 中 <constructor-arg>、<property> 手工配置。在 <bean> 元素上指定 autowire 屬性啟用。
容器查找 Bean id 與屬性名相同 的 Bean 注入。
<bean id="textEditor" class="com.example.TextEditor" autowire="byName">
<property name="name" value="Generic Editor"/> <!-- 簡單值仍需手工 -->
</bean>
<bean id="spellChecker" class="com.example.SpellChecker"/> <!-- id = spellChecker,匹配屬性名 -->
容器查找 類型兼容 的 Bean (僅有一個匹配時)。
<bean id="textEditor" class="com.example.TextEditor" autowire="byType">
<property name="name" value="Generic Editor"/>
</bean>
<bean id="mySpellChecker" class="com.example.SpellChecker"/> <!-- 類型匹配,id 可任意 -->
primary 或 qualifier類似 byType,但作用於 建構子參數。
public class TextEditor {
private SpellChecker spellChecker;
private String name;
public TextEditor(SpellChecker spellChecker, String name) { ... }
}
<bean id="textEditor" class="com.example.TextEditor" autowire="constructor">
<constructor-arg value="Generic Editor"/> <!-- 簡單值仍需手工 -->
</bean>
<bean id="spellChecker" class="com.example.SpellChecker"/>
嘗試 constructor 失敗則回退 byType。Spring 3.0+ 不推薦使用。
無自動裝配,需顯式配置。繼承自父 <beans default-autowire="...">。
public class TextEditor {
private SpellChecker spellChecker;
private String name;
// 建構子 (constructor 模式用)
public TextEditor(SpellChecker spellChecker, String name) { ... }
// Setter (byName/byType 用)
public void setSpellChecker(SpellChecker sc) { this.spellChecker = sc; }
public void setName(String name) { this.name = name; }
public void spellCheck() { spellChecker.checkSpelling(); }
}
| 模式 | autowire 值 | SpellChecker Bean id | 手工配置項 |
|---|---|---|---|
| byName | byName | spellChecker (必須同名) | name (簡單值) |
| byType | byType | 任意 (如 myChecker) | name |
| constructor | constructor | 任意 | name (建構子參數) |
| 無 | default/無 | 任意 | spellChecker + name |
byType 多候選時拋異常;byName 重命名屬性即失效<property>/<constructor-arg> 會覆蓋自動裝配結果valueXML autowire 已被 @Autowired / @Inject / @Resource 取代,功能更強、類型安全、IDE 友善。
@Component
public class TextEditor {
@Autowired // byType,可配合 @Qualifier 指定名稱
private SpellChecker spellChecker;
@Value("${editor.name}") // 簡單值注入
private String name;
}
@Resource(name = "mySpellChecker") // 指定 Bean 名稱
private SpellChecker spellChecker;
@Component
public class TextEditor {
private final SpellChecker spellChecker;
private final String name;
public TextEditor(SpellChecker spellChecker, @Value("${editor.name}") String name) {
this.spellChecker = spellChecker;
this.name = name;
}
}
| 場景 | 推薦方式 |
|---|---|
| 新專案 / 現代化重構 | 建構子注入 + @Autowired + @Value |
| 舊版 XML 維護 | 顯式 <property>/<constructor-arg>,避免 autowire |
| 第三方庫整合無法加註解 | XML 顯式配置或 @Bean 方法 |
| 原型 Bean / 複雜初始化 | @Bean 方法手工控制 |
核心原則:顯式優於隱式。自動裝配雖省力,但犧牲了可讀性與可維護性,現代 Spring 開發應以註解驅動的顯式依賴聲明為主。