Spring 自 2004 年首版釋出以來,憑藉低侵入設計、容器管理 Bean、AOP 切面解耦、事務整合等特性,成為 Java 企業級開發事實標準。本文系統梳理 Spring 核心架構、IoC 容器運作、依賴注入(DI)模式、Bean 作用域、自動裝配策略與實戰配置技巧,並附上原始碼級範例,助你建立完整心智模型。

ApplicationContext 為最常用容器介面,兩大實現:
ClassPathXmlApplicationContext:從類路徑載入 XML 配置(如 classpath:beans.xml)。FileSystemXmlApplicationContext:從檔案系統絕對/相對路徑載入。public class BeanTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
Person p = ctx.getBean("person", Person.class);
p.say();
}
}
建議建立 User Library 管理 Spring JAR,專案發布時勾選「Export」將 JAR 複製至 WEB-INF/lib。或直接放入 WEB-INF/lib,配合 Maven/Gradle 依賴管理更佳。
Spring 容器扮演「超級工廠」角色,負責:
傳統模式:呼叫者 主動 new 被依賴物件,或透過工廠取得 → 硬編碼耦合。
Spring 模式:呼叫者 被動 接受容器注入 → 依賴關係外置配置,實現解耦。
| 維度 | 設值注入 | 構造注入 |
|---|---|---|
| 方式 | Setter 方法 | 建構子參數 |
| 優點 | 符合 JavaBean 慣例、可選依賴友善、避免建構子膨脹、循環依賴易處理 | 依賴順序可控、不可變性強、依賴關係封裝於建構子、符合高內聚 |
| 缺點 | 不可變性弱、需預防 null 注入 | 參數多時閱讀性差、所有依賴必須就緒才能實例化 |
| 建議場景 | 選用依賴、多數業務 Bean、框架整合點 | 核心領域物件、不可變值物件、必須依賴 |
最佳實踐:以設值注入為主、構造注入為輔。@Required 或 @NonNull 輔助檢查必要依賴。
| 作用域 | 生命週期 | 適用場景 |
|---|---|---|
| singleton(預設) | 容器內單一實例,全域共享 | 無狀態服務、DAO、Controller、工具類 |
| prototype | 每次 getBean() 建立新實例 | 有狀態物件、命令模式、每次請求需獨立實例 |
| request | 單一 HTTP 請求內共享 | Web 請求級資料、表單綁定物件 |
| session | 單一 HTTP Session 共享 | 購物車、使用者偏好設定 |
| global session | Portlet 全域 Session 共享 | Portlet 環境跨應用共享資料 |
效能提醒:prototype 建立/銷毀成本高,非必要勿用。singleton Bean 需確保執行緒安全(無可變狀態或使用 ThreadLocal)。
在 <beans> 或 <bean> 上設定 autowire/default-autowire:
no(預設):手動 ref 指定,依賴關係最清晰,大型專案推薦。byName:依 setter 名稱(去 set 首字母小寫)匹配 Bean id。byType:依 setter 參數型別匹配,若多於一個拋出異常。constructor:依建構子參數型別匹配。autodetect:嘗試 constructor 失敗則 fallback byType。排除自動裝配:
<bean id="dataSource" autowire-candidate="false" />
<beans default-autowire-candidates="*Dao" />
<bean id="..." class="..."> 呼叫無參/有參建構子。<bean id="..." class="FactoryClass" factory-method="createInstance"/>。<bean id="factory" class="FactoryClass"/> <bean id="..." factory-bean="factory" factory-method="createInstance"/>。@ComponentScan、@EnableTransactionManagement、@EnableAsync 等啟用註解替代 XML 命名空間。@Profile("dev|prod|test") 區分環境差異。