我希望在通过XML配置刷新上下文之前将PropertySource
添加到Spring Environment
。
执行此操作的Java配置方法是:
@Configuration
@PropertySource("classpath:....")
public ConfigStuff {
// config
}
在上下文刷新/初始化之前,我会以某种方式猜测@PropertySource
。
但是,我想做一些更动态的东西,而不仅仅是从类路径加载。
在刷新上下文之前,我知道如何配置Environment
的唯一方法是实现ApplicationContextInitializer<ConfigurableApplicationContext>
和注册。
我强调注册部分,因为这需要通过servlet上下文告诉你的环境关于上下文初始化器和/或在单元测试的情况下为每个单元测试添加@ContextConfiguration(value="this I don't mind", initializers="this I don't want to specify")
。
我更喜欢我的自定义初始化程序,或者在我的情况下,自定义PropertySource在适当的时间通过应用程序上下文xml文件加载,就像@PropertySource
看起来如何工作一样。
答案 0 :(得分:0)
在查看如何加载@PropertySource之后,我想出了我需要实现哪个接口,这样我就可以在其他beanPostProcessors运行之前配置环境。诀窍是实施BeanDefinitionRegistryPostProcessor
。
public class ConfigResourcesEnvironment extends AbstractConfigResourcesFactoryBean implements ServletContextAware,
ResourceLoaderAware, EnvironmentAware, BeanDefinitionRegistryPostProcessor {
private Environment environment;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (environment instanceof ConfigurableEnvironment) {
ConfigurableEnvironment env = ((ConfigurableEnvironment) this.environment);
List<ResourcePropertySource> propertyFiles;
try {
propertyFiles = getResourcePropertySources();
} catch (IOException e) {
throw new RuntimeException(e);
}
//Spring prefers primacy ordering so we reverse the order of the files.
reverse(propertyFiles);
for (ResourcePropertySource rp : propertyFiles) {
env.getPropertySources().addLast(rp);
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//NOOP
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
我的getResourcePropertySources()
是自定义的,所以我没有费心去展示它。另请注意,此方法可能无法用于调整环境配置文件。为此,您仍然需要使用初始化程序。