Spring Bean 定義是 IoC 容器配置的核心。本文系統梳理 <bean> 元素 14 個核心屬性的含義、取值範圍、相互影響與最佳實踐,作為 Spring XML 配置速查手冊。
| 屬性 | 必填 | 默認值 | 核心作用 |
|---|---|---|---|
| id | 否 (但強烈建議) | - | Bean 唯一標識,符合 XML ID 約束 (字母開頭、無特殊字符) |
| name | 否 | - | 別名,支援特殊字符,多個用逗號/分號/空格分隔 |
| class | 是 (非子 Bean) | - | 全限定類名,容器實例化目標類型 |
| parent | 否 | - | 父 Bean 引用,繼承配置,子 Bean 可覆蓋屬性 |
| abstract | 否 | false | true=模板 Bean,不實例化,供子 Bean 繼承 |
| scope | 否 | singleton | singleton/prototype/request/session/application/websocket |
| lazy-init | 否 | default | true=延遲初始化 (僅 singleton);default=繼承容器級默認 |
| autowire | 否 | default | no/byName/byType/constructor/autodetect/default |
| dependency-check | 否 | default | none/objects/simple/all/default (配合 autowire 校驗依賴完整性) |
| depends-on | 否 | - | 強制前置初始化的 Bean 名稱,控制啟動順序 |
| init-method | 否 | - | 初始化回調方法 (無參),屬性注入後調用 |
| destroy-method | 否 | - | 銷毀回調方法 (無參),僅 singleton,容器關閉時調用 |
| factory-method | 否 | - | 工廠方法名,配合 factory-bean 使用,class 屬性失效 |
| factory-bean | 否 | - | 工廠 Bean 名稱,調用其 factory-method 創建實例 |
id:XML ID 類型,唯一,不含特殊字符,推薦作為主鍵name:CDATA 類型,可含 *、#、@ 等特殊字符,適合別名/兼容舊名稱<bean id="userDao" name="userDao*,userDaoV2" class="..."/>| 作用域 | 生命週期 | 適用場景 | 備註 |
|---|---|---|---|
| singleton | 容器啟動~關閉,單實例 | 無狀態服務、DAO、工具類 | 默認,線程安全由開發者保證 |
| prototype | 每次 getBean 新實例 | 有狀態對象、命令模式、請求級 | 容器不管銷毀,需自行管理 |
| request | 單次 HTTP 請求 | Web 請求上下文數據 | 僅 Web 環境 |
| session | HTTP Session 週期 | 用戶購物車、偏好設置 | 僅 Web 環境 |
| application | ServletContext 週期 | 全局配置、緩存 | 僅 Web 環境 |
| websocket | WebSocket Session 週期 | 長連接狀態 | Spring 4+ |
setUserDao() 找 userDao建議:生產環境顯式 <property>/<constructor-arg>,自動裝配降低可讀性、難調試、易誤裝配。
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
init-method="init" destroy-method="close">
<property name="jdbcUrl" value="jdbc:mysql://..."/>
</bean>
InitializingBean/DisposableBean 接口 (強耦合 Spring)@PostConstruct / @PreDestroy (JSR-250,需 <context:annotation-config/>)
<bean id="baseDao" abstract="true" class="com.dao.BaseJdbcDao">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" parent="baseDao" class="com.dao.UserDaoImpl">
<property name="tableName" value="t_user"/>
</bean>
abstract="true" 避免實例化
<bean id="client" class="com.service.HttpClientFactory" factory-method="createClient"/>
<bean id="factory" class="com.service.HttpClientFactory"/>
<bean id="client" factory-bean="factory" factory-method="createClient"/>
| 錯誤現象 | 根因 | 修正 |
|---|---|---|
| Bean 重複定義 | 同 id 多次定義 | 檢查導入配置文件去重;使用 allow-bean-definition-overriding |
| 原型 Bean 內存洩漏 | 容器不管理銷毀 | 手動調用 destroy-method;或改用 singleton + 線程局部變量 |
| 循環依賴 | 雙向引用無構造器注入 | 改用 setter 注入;或 @Lazy 延遲注入;或重構設計 |
| autowire 失效 | 多候選 Bean | 標記 @Primary / 顯式指定 / 限定符 @Qualifier |
Spring Bean 定義屬性看似繁多,核心邏輯只有三條線:標識 (id/name) → 創建 (class/factory/scope) → 裝配與生命周期 (autowire/depends-on/init/destroy)。掌握這 14 個屬性的語義邊界與組合規則,即可駕馭 95% 的 XML 配置場景。現代項目建議註解配置 (@Component/@Bean) 為主,XML 處理基礎設施與跨模塊整合。