Spring 提供多種方式加載 .properties 配置並注入 Bean。本文對比 PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer、@PropertySource、@Value、Environment、@ConfigurationProperties 等方案,給出生產環境推薦配置模式。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=secret123
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list><value>classpath:jdbc.properties</value></list>
</property>
<property name="fileEncoding" value="UTF-8"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
</bean>
用法:${jdbc.url} 占位符注入 XML Bean 屬性或 @Value("${jdbc.url}") 注入字段。
@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
@Autowired Environment env;
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setDriverClassName(env.getProperty("jdbc.driver"));
ds.setJdbcUrl(env.getProperty("jdbc.url"));
ds.setUsername(env.getProperty("jdbc.username"));
ds.setPassword(env.getProperty("jdbc.password"));
return ds;
}
}
@Component
@ConfigurationProperties(prefix = "jdbc")
@PropertySource("classpath:jdbc.properties") // Spring Boot 自動加載 application.properties 可省略
public class JdbcProperties {
private String driver;
private String url;
private String username;
private String password;
// getter/setter
}
啟用:@EnableConfigurationProperties(JdbcProperties.class) 或掃描 @Component。
優點:類型安全、IDE 提示、鬆散綁定 (driver-class-name ↔ driverClassName)、驗證 (JSR-303)。
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list><value>classpath:jdbc.properties</value></list>
</property>
<property name="fileEncoding" value="UTF-8"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertySourcesPlaceholderConfigurer">
<property name="properties" ref="configProperties"/>
</bean>
注入用法:
@Value("#{configProperties['jdbc.url']}")
private String url;
@Value("#{configProperties['jdbc.username']}")
private String username;
注意:PropertySourcesPlaceholderConfigurer 是 4.3+ 推薦替代 PropertyPlaceholderConfigurer,支援 Spring Environment 抽象與 Profile。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class) // 或 locations
public class PropertiesTest {
@Autowired JdbcProperties jdbcProperties; // 方案三
@Value("${jdbc.url}") String url; // 方案一/二
@Test
public void test() {
assertEquals("jdbc:mysql://...", jdbcProperties.getUrl());
assertEquals("jdbc:mysql://...", url);
}
}
| 類 | 用途 | 備註 |
|---|---|---|
| PropertyPlaceholderConfigurer | 解析 ${...} 占位符 | 舊版,不支援 Environment/Profile |
| PropertySourcesPlaceholderConfigurer | 解析 ${...},整合 Environment | 推薦 XML 方式 |
| PropertiesFactoryBean | 加載 .properties 為 Properties 對象 | 配合 SpEL #{...} 讀取 |
| @PropertySource | Java Config 聲明配置源 | 可多註解、支援 encoding |
| @ConfigurationProperties | 綁定到 POJO | 類型安全、鬆散綁定、驗證 |
application.yml/properties + @ConfigurationProperties,零配置。PropertySourcesPlaceholderConfigurer + @Value("${key}")。@PropertySource + Environment 或 @ConfigurationProperties。jasypt-spring-boot 加密或外部配置中心 (Nacos/Apollo/Consul)。jdbc-dev.properties, jdbc-prod.properties + @Profile 或 Spring Boot application-{profile}.yml。配置管理是應用可維護性的關鍵。統一用 @ConfigurationProperties 綁定強類型配置對象,配合 @PropertySource 聲明源,PropertySourcesPlaceholderConfigurer 解析占位符,構建清晰、安全、可測試的配置體系。