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

Spring @Value 注解兩種注入方式差異與配置詳解

     編輯:Java 相關知識

在 Spring 開發中,@Value 是注入外部配置屬性的常用注解。本文將深入對比其兩種主要表達式形式——#{...} (SpEL) 與 ${...} (Placeholder),並通過具體 XML 配置示例,闡明底層機制差異與適用場景,幫助開發者避免常見配置陷阱。

兩種語法形式對比

語法表達式類型典型寫法依賴組件
@Value("#{configProperties['key']}")Spring Expression Language (SpEL)引用 Bean ID + Map 鍵PropertiesFactoryBean 生成的 Properties 對象
@Value("${key}")Property Placeholder直接引用鍵名PropertyPlaceholderConfigurer 或 PreferencesPlaceholderConfigurer

方式一:SpEL 表達式注入 (#{...})

此方式需顯式定義一個 PropertiesFactoryBean Bean,將屬性文件加載為 java.util.Properties 對象,再通過 SpEL 從中取值。

<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:/config/t1.properties</value>
        </list>
    </property>
</bean>

Java 代碼中:

@Value("#{configProperties['t1.msgname']}")
private String msgName;

特點:

  • 強類型引用:依賴 Bean ID (configProperties),IDE 可導航,重構安全。
  • 功能強大:支持 SpEL 完整語法(運算、方法調用、條件判斷等)。
  • 適用場景:需動態計算、引用其他 Bean 屬性、或屬性值本身包含 ${...} 占位符時。

方式二:佔位符注入 (${...})

此方式依賴 PropertyPlaceholderConfigurer (或其子類) 在 Bean 定義階段解析 ${...} 佔位符,將屬性值直接替換到 Bean 定義中。

配置方案 A:復用 PropertiesFactoryBean

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties" ref="configProperties"/>
</bean>

配置方案 B:直接指定文件路徑

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="config/t1.properties"/>
</bean>

Java 代碼中:

@Value("${t1.msgname}")
private String msgName;

特點:

  • 配置簡潔:無需在代碼中指定 Bean ID,屬性鍵直接映射。
  • 早期解析:在容器啟動階段完成替換,運行時無額外開銷。
  • 注意:PropertyPlaceholderConfigurer 僅處理 XML 中的佔位符,若需在註解屬性值中使用,需確保 <context:property-placeholder/> 或相應 Bean 已加載。

核心差異總結

  1. 解析時機:SpEL 在 Bean 初始化時運行期求值;Placeholder 在配置解析階段靜態替換。
  2. 依賴關係:SpEL 依賴具體 Properties Bean;Placeholder 依賴全局 PropertySources。
  3. 表達能力:SpEL 支持複雜邏輯運算;Placeholder 僅做鍵值查找。
  4. 推薦選型:純屬性注入首選 ${...} 配合 @PropertySource (Spring 3.1+);需動態計算或引用 Bean 時用 #{...}。

現代 Spring 實踐建議 (Spring 3.1+)

優先使用 @PropertySource + Environment 或 @ConfigurationProperties 實現類型安全綁定,減少硬編碼鍵名:

@Configuration
@PropertySource("classpath:/config/t1.properties")
public class AppConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

// 注入單個值
@Value("${t1.msgname}") String msgName;

// 或綁定到 POJO (推薦)
@Component
@ConfigurationProperties(prefix = "t1")
public class T1Properties {
    private String msgname;
    // getter/setter
}

這樣既保持了配置集中管理,又獲得了編譯期類型檢查與 IDE 支持,是當前企業級項目的主流做法。

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