PropertyPlaceholderConfigurer must be overridden to reload new properties
You need to rewrite the processProperties method to make a StringValueResolver that contains properties that have become loadable. This is my code.
import java.io.IOException; import java.util.Properties; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; import org.springframework.util.StringValueResolver; public class ReloadablePropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { private ReloadablePlaceholderResolvingStringValueResolver reloadableValueResolver; public void reloadProperties() throws IOException { Properties props = mergeProperties(); this.reloadableValueResolver.refreshProperties(props); } @Override protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { this.reloadableValueResolver = new ReloadablePlaceholderResolvingStringValueResolver(props); StringValueResolver valueResolver = this.reloadableValueResolver; this.doProcessProperties(beanFactoryToProcess, valueResolver); } private class ReloadablePlaceholderResolvingStringValueResolver implements StringValueResolver { private final PropertyPlaceholderHelper helper; private final ReloadablePropertyPlaceholderConfigurerResolver resolver; public ReloadablePlaceholderResolvingStringValueResolver(Properties props) { this.helper = new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders); this.resolver = new ReloadablePropertyPlaceholderConfigurerResolver(props); } @Override public String resolveStringValue(String strVal) throws BeansException { String value = this.helper.replacePlaceholders(strVal, this.resolver); return (value.equals(nullValue) ? null : value); } private void refreshProperties(Properties props){ this.resolver.setProps(props); } } private class ReloadablePropertyPlaceholderConfigurerResolver implements PlaceholderResolver { private Properties props; private ReloadablePropertyPlaceholderConfigurerResolver(Properties props) { this.props = props; } @Override public String resolvePlaceholder(String placeholderName) { return ReloadablePropertyPlaceholderConfigurer.this.resolvePlaceholder(placeholderName, props, SYSTEM_PROPERTIES_MODE_FALLBACK); } public void setProps(Properties props) { this.props = props; } } }
here is the configuration for properties-config.xml . All of these properties can be reloaded at run time as a prototype bean.
<bean id="propertyConfigurer" class="com.cn21.mail189.analysis.commons.expand.ReloadablePropertyPlaceholderConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:spring/dbconfig.properties</value> <value>classpath:spring/app.properties</value> <value>classpath:xxxx.properties</value> </list> </property> </bean>`
source share