一、property-placeholderhelp
Property-placeholder是Spring框架提供的一种用于替换XML中属性占位符的机制。它可以读取Properties文件,并且在XML文件中取出相应的属性值,并将其替换为占位符,该机制对于模块化配置、测试、灵活性以及重用方面都具有很大的优势。
在Spring的应用上下文中,通过PropertyPlaceholderConfigurer可以很方便的读取Properties文件,并用${}的语法来引用读取的属性值,当然在引用值为空的时候,可以设置默认值。例如:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
在上述的代码中,${jdbc.driverClassName}、${jdbc.url}、${jdbc.username} 和 ${jdbc.password} 都是PropertyPlaceholderConfigurer读取Properties文件中所定义的属性名。
二、property-placeholderhelper
除了通过PropertyPlaceholderConfigurer来读取Properties文件之外,Spring 4.3版本以后,还提供了一个更加强大的属性加载机制 -- PropertySourcesPlaceholderConfigurer。PropertySourcesPlaceholderConfigurer继承自PropertyPlaceholderConfigurer,并且更加灵活,支持从多个地方读取属性文件,包括系统属性、Java配置类、环境变量等等。实际上,它也是Spring @PropertySources注解使用的核心类。
在Java配置类中配置示例:
@Configuration @ComponentScan @PropertySources(value = { @PropertySource("classpath:application.properties"), @PropertySource("file:/opt/config/application.properties") }) public class AppConfig { @Autowired Environment env; @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); dataSource.setUrl(env.getProperty("jdbc.url")); dataSource.setUsername(env.getProperty("jdbc.username")); dataSource.setPassword(env.getProperty("jdbc.password")); return dataSource; } }
使用PropertySourcesPlaceholderConfigurer可以在Java配置类中从多个地方加载属性,并且与其他的Spring组件无缝集成。
三、property-placeholder热加载
在大多数情况下,我们不会在运行时更改属性文件中的值,但是,在一些特殊的情况下,我们可能需要热修改Properties文件的值,并且更新Spring容器中的Bean。Spring框架自身并没有提供热修改属性文件的功能,但是我们可以自己实现一个热加载的机制。
我们可以在程序中监控Properties文件的修改,并且在文件发生变更时,重新读取Properties文件,并且更新Spring中的Bean。示例代码如下:
@Configuration @PropertySources(value = {@PropertySource("classpath:config.properties")}) public class AppConfig { @Autowired Environment env; @Bean public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setLocation(new ClassPathResource("config.properties")); configurer.setIgnoreResourceNotFound(false); configurer.setIgnoreUnresolvablePlaceholders(false); configurer.setProperties(CommonUtils.loadProperties(configurer.getLocation())); return configurer; } /** * 监听文件修改 */ @PostConstruct public void init() { String location = env.getProperty("spring.config.location"); if (location != null) { File file = new File(location); if (!file.exists()) { throw new FileNotFoundException("The config file does not exist: " + file.toString()); } if (location.endsWith(".properties")) { new PropertiesFileListener(file, this::reloadProperties).watch(); } } } /** * 重新加载Properties文件 * @param properties Properties */ public void reloadProperties(Properties properties) { PropertySourcesPlaceholderConfigurer configurer = propertySourcesPlaceholderConfigurer(); configurer.setProperties(properties); } .......... }
四、PropertyPlaceholderConfigurer
PropertyPlaceholderConfigurer是Spring框架中的一个核心组件,它是Properties文件中的属性值占位符解析器。它提供了多种方式来解析Properties文件中的占位符,例如,可以使用系统环境变量、标准JRE属性、命令行参数、JNDI等等方式。通过PropertyPlaceholderConfigurer,我们可以轻松地将XML配置文件和Properties文件进行解耦合,从而实现灵活性和可维护性。例如:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config.properties</value> </list> </property> </bean>
在上述代码中,我们将Properties文件的配置放置到了Spring的Application Context对象中,并且可以通过占位符来引用Properties文件中的参数。
五、结合注解使用
除了XML配置之外,Property-placeholder在注解中也得到了广泛的应用,Spring提供了@Value注解来读取Properties文件中的配置参数,用法如下:
@Value("${jdbc.driverClassName}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password;
使用@Value注解读取Properties文件中的配置参数,可以避免在Java代码中硬编码参数值,也可以让配置从不同的环境中进行分离。
总结
Property-placeholder机制在Spring框架中得到了广泛地应用,在不同的开发场景中起到了不可替代的作用。通过本文的介绍,我们知道,Spring提供了多种加载Properties文件的方式,从XML配置、Java配置到注解方式,我们可以根据实际的开发情况来选择使用哪种方式。同时,在热加载方面,我们需要根据实际需求进行调整,以达到最佳的实践效果。