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

Spring 依賴注入方式全解析:XML 配置下的 7 種注入姿勢

     編輯:Java 相關知識

前言

Spring 核心是 IoC 容器管理 Bean 生命周期與依賴關係。在 XML 配置元數據模式下(雖然現代項目多用註解,但維護老項目、理解原理仍需掌握),除常見的 <constructor-arg>、<property> 外,Spring 還提供 **FactoryBean 機制** 實現「方法返回值注入」「字段值注入」「任意靜態方法調用」等高級注入。本文系統梳理 7 種姿勢。

基礎注入(最常用)

方式XML 元素底層調用適用場景
構造器注入<constructor-arg>有參構造器強依賴、不可變對象
Setter 注入<property>setXxx()可選依賴、可變對象

進階注入:FactoryBean 系列

Spring 內建三個 FactoryBean,讓 XML 能表達「調用方法/讀取字段/調用靜態方法」並將結果作為 Bean 注入:

1. MethodInvokingFactoryBean —— 調用實例/靜態方法返回值注入

<!-- 調用實例方法 -->
<bean id="valueGenerator" class="com.example.ValueGenerator"/>
<bean id="dynamicValue" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="valueGenerator"/>
    <property name="targetMethod" value="generate"/>
    <property name="arguments">
        <list><value>param1</value></list>
    </property>
</bean>

<!-- 調用靜態方法(簡寫) -->
<bean id="systemProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod" value="java.lang.System.getProperty"/>
    <property name="arguments">
        <list><value>java.version</value></list>
    </property>
</bean>

<!-- 將方法返回值直接注入其他 Bean -->
<bean id="consumer" class="com.example.Consumer">
    <property name="config" ref="dynamicValue"/>
</bean>

2. FieldRetrievingFactoryBean —— 讀取實例/靜態字段值注入

<!-- 讀取靜態常量 -->
<bean id="serializableLevel" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>

<!-- 讀取實例字段(需先有目標 Bean) -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" .../>
<bean id="poolSize" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <property name="targetObject" ref="dataSource"/>
    <property name="targetField" value="maximumPoolSize"/>
</bean>

3. PropertyPathFactoryBean —— 通過屬性路徑鏈式獲取值

<bean id="orderService" class="com.example.OrderService">
    <property name="userService" ref="userService"/>
</bean>

<!-- 獲取 orderService.userService.userDao.dataSource.url -->
<bean id="dbUrl" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
    <property name="targetBeanName" value="orderService"/>
    <property name="propertyPath" value="userService.userDao.dataSource.url"/>
</bean>

<!-- 簡寫:Bean id 即屬性路徑 -->
<bean id="orderService.userService.userDao.dataSource.url" 
      class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>

完整對比表

FactoryBean核心屬性典型用例是否支持參數
MethodInvokingFactoryBeantargetObject/targetClass, targetMethod, arguments, staticMethod調用工具類靜態方法、實例方法獲取配置值是
FieldRetrievingFactoryBeanstaticField / (targetObject + targetField)讀取常量、單例對象的公共字段否
PropertyPathFactoryBeantargetBeanName, propertyPath深層屬性鏈導航、將內部對象暴露為獨立 Bean否

實戰場景:將系統屬性注入 DataSource 配置

<bean id="dbProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod" value="java.lang.System.getProperties"/>
</bean>

<bean id="jdbcUrl" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="dbProps"/>
    <property name="targetMethod" value="getProperty"/>
    <property name="arguments">
        <list><value>jdbc.url</value></list>
    </property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="url" ref="jdbcUrl"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.pass}"/>
</bean>

避坑提醒

  1. 循環依賴:FactoryBean 返回的對象若又依賴原 Bean,會導致循環引用,需用 <property name="lazy-init" value="true"/> 或重構。
  2. 類型轉換:方法返回 Object,注入目標若為基本類型/String,Spring 自動轉換;複雜類型需確保返回類型匹配。
  3. 單例 vs 原型:FactoryBean 默認單例,若需每次調用獲取新值,設置 <property name="singleton" value="false"/>(僅 MethodInvokingFactoryBean 支持)。
  4. 現代替代:Spring 3.0+ 推薦使用 @Value("#{systemProperties['jdbc.url']}")、@Autowired + @Qualifier、@Bean 方法體內直接調用,XML FactoryBean 僅用於維護舊系統。

總結

Spring XML 配置通過 **三大 FactoryBean** 將「方法調用、字段讀取、屬性路徑導航」納入依賴注入體系,極大擴展了聲明式裝配能力。理解這 7 種注入姿勢(2 基礎 + 3 FactoryBean + 2 組合變體),能靈活應對老項目中各種非標準裝配需求,也是深入理解 Spring 容器擴展機制的關鍵一課。

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