首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring Bean 裝配全解析:Set/構造器/自動裝配/屬性佔位符/集合注入/繼承配置實戰

     編輯:Java 綜合教學

Bean 裝配基礎

<beans>
    <bean id="foo" class="com.xidian.Foo" /> <!-- 最簡配置:id + 全限定類名 -->
</beans>

Scope 作用域

Scope含義適用場景
singleton (默認)容器內單例,全局共享無狀態 Service、DAO、工具類
prototype每次獲取創建新實例有狀態對象、命令模式、請求級 Bean
request每個 HTTP 請求一個實例Web 環境,表單對象
session每個 HTTP Session 一個實例用戶購物車、偏好設置
globalSessionPortlet 全局 SessionPortlet 環境

最佳實踐:優先 singleton,prototype 慎用(性能、GC 壓力)。

一、Setter 注入

1. 引用其他 Bean

<bean id="car" class="com.example.Car">
    <property name="engine" ref="engine" /> <!-- ref 引用另一 bean -->
</bean>
<bean id="engine" class="com.example.Engine" />

2. 內部 Bean(僅用於單一引用)

<bean id="car" class="com.example.Car">
    <property name="engine">
        <bean class="com.example.Engine" /> <!-- 無 id,外部不可引用 -->
    </property>
</bean>

3. 繼承配置

<bean id="student" class="com.example.Student">
    <property name="name" value="順平" />
    <property name="age" value="30" />
</bean>

<bean id="graduate" parent="student" class="com.example.Graduate">
    <property name="degree" value="碩士" /> <!-- 覆蓋或新增 -->
</bean>

parent 屬性值為父 Bean 的 id,而非類名。

4. 簡單屬性注入

<property name="name">
    <value>tom</value> <!-- 或 value="tom" 簡寫 -->
</property>

5. 集合類型注入

<bean id="dept" class="com.example.Department">
    <!-- 數組 -->
    <property name="empNames">
        <list><value>小明</value><value>小紅</value></list>
    </property>

    <!-- List (可重復) -->
    <property name="empList">
        <list>
            <ref bean="emp1" />
            <ref bean="emp2" />
            <ref bean="emp1" /> <!-- 允許重復 -->
        </list>
    </property>

    <!-- Set (不可重復) -->
    <property name="empSet">
        <set>
            <ref bean="emp1" />
            <ref bean="emp2" />
        </set>
    </property>

    <!-- Map -->
    <property name="empMap">
        <map>
            <entry key="11" value-ref="emp1" />
            <entry key="22" value-ref="emp2" />
        </map>
    </property>

    <!-- Properties -->
    <property name="props">
        <props>
            <prop key="k1">v1</prop>
            <prop key="k2">v2</prop>
        </props>
    </property>
</bean>

二、構造器注入

public class Employee {
    private String name;
    private Integer age;
    public Employee(String name, Integer age) { this.name = name; this.age = age; }
}

<bean id="employee" class="com.example.Employee">
    <constructor-arg index="0" type="java.lang.String" value="大明" />
    <constructor-arg index="1" type="java.lang.Integer" value="22" />
</bean>

類型嚴格性(關鍵)

  • 包裝類:type="java.lang.Integer"(不可寫 int 或 Integer)。
  • 基本類型:type="int"(不可寫 java.lang.Integer)。
  • Spring 反射不支持自動裝箱/拆箱匹配,類型必須精確一致。

Setter vs 構造器注入對比

維度Setter 注入構造器注入
必選依賴表達無法強制(可選屬性易混淆)構造器參數天然表達強依賴
不可變對象不支持(需 setter)支持(final 字段 + 構造器)
循環依賴支持(Set 後再注入)不支持(需 @Lazy 或 Setter 輔助)
可讀性屬性名清晰參數順序易誤
主流建議✅ 通用首選✅ 必選依賴/不可變對象首選

三、自動裝配

<bean id="master" class="com.example.Master" autowire="byName" />
<bean id="dog" class="com.example.Dog" /> <!-- id=dog 匹配 master 的 dog 屬性 -->

四種模式

模式匹配規則風險
byName屬性名 = Bean id重命名屬性/Bean 易斷裂
byType屬性類型 = Bean 類型(唯一)多實現拋異常
constructor構造器參數類型匹配同 byType
autodetect優先 constructor,失敗回退 byType不可控

默認自動裝配

<beans default-autowire="byName"> <!-- 全局默認 -->
    <bean id="foo" class="..." autowire="default" /> <!-- 繼承全局 -->
</beans>

建議:生產環境禁用自動裝配,顯式 <property>/<constructor-arg> 更清晰、可追蹤、重構安全。

四、屬性佔位符:外部化配置

1. 引入屬性文件

<context:property-placeholder location="classpath:db.properties,classpath:db2.properties" />

2. 屬性文件

# db.properties
name=scott
drivername=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:hsp
pwd=tiger

# db2.properties
db2.name=sys
db2.drivername=...
db2.url=...
db2.pwd=...

3. Bean 中使用 ${key}

<bean id="dbutil" class="com.example.DBUtil">
    <property name="name" value="${name}" />
    <property name="drivername" value="${drivername}" />
    <property name="url" value="${url}" />
    <property name="pwd" value="${pwd}" />
</bean>

<bean id="dbutil2" class="com.example.DBUtil">
    <property name="name" value="${db2.name}" />
    <property name="drivername" value="${db2.drivername}" />
    <property name="url" value="${db2.url}" />
    <property name="pwd" value="${db2.pwd}" />
</bean>

五、總結:裝配方式選型決策樹

需要裝配 Bean
    │
    ├─ 強依賴 / 不可變對象 / final 字段 ──→ 構造器注入 (constructor-arg)
    │
    ├─ 可選依賴 / 可變對象 / 多屬性 ──→ Setter 注入 (property)
    │
    ├─ 大量相似 Bean / 快速原型 ──→ 自動裝配 (autowire) ⚠️ 僅開發期
    │
    ├─ 多環境配置 / 敏感信息外部化 ──→ 屬性佔位符 (${}) + PropertyPlaceholder
    │
    └─ 集合/Map/Props 注入 ──→ property + list/set/map/props 標籤

掌握 Spring Bean 裝配的各種方式、適用邊界與避坑指南,能構建清晰、可維護、環境友好的 IoC 容器配置。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved