参照用にこれを残しますが、更新された回答は仕切りの下にあります:
ConfigurableApplicationContext
インターフェースにはrefresh ()メソッドが含まれていますが、これは必要なはずですが、問題は、そのメソッドにアクセスする方法です。どちらの方法でも、 type の依存関係を持つ Bean から開始しますConfigurableApplicationContext
。
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
ここで、私が提案する2つの基本的なオプションは、次のいずれかです
- タスク実行フレームワークを使用して、Bean にプロパティ リソースを定期的に監視させ、変更が見つかったときに ApplicationContext を更新するか、
- Bean を JMXに公開して、更新を手動でトリガーできるようにします。
コメントを参照してください: コンテキスト全体を更新することは不可能に思われるため、代わりの戦略は、プロパティ ファクトリ Bean を作成し、それを他のすべての Bean に注入することです。
public class PropertiesFactoryBean implements FactoryBean<Properties>{
public void setPropertiesResource(Resource propertiesResource){
this.propertiesResource = propertiesResource;
}
private Properties value=null;
long lastChange = -1L;
private Resource propertiesResource;
@Override
public Properties getObject() throws Exception{
synchronized(this){
long resourceModification = propertiesResource.lastModified();
if(resourceModification != lastChange){
Properties newProps = new Properties();
InputStream is = propertiesResource.getInputStream();
try{
newProps.load(is);
} catch(IOException e){
throw e;
} finally{
IOUtils.closeQuietly(is);
}
value=newProps;
lastChange= resourceModification;
}
}
// you might want to return a defensive copy here
return value;
}
@Override
public Class<?> getObjectType(){
return Properties.class;
}
@Override
public boolean isSingleton(){
return false;
}
}
このプロパティ Bean を他のすべての Bean に注入することもできますが、常にプロトタイプ スコープを使用するように注意する必要があります。これはシングルトン Bean 内では特に注意が必要です。解決策はここにあります。
あちこちにルックアップ メソッドを注入したくない場合は、次のPropertyProvider
ように Bean を注入することもできます。
public class PropertiesProvider implements ApplicationContextAware{
private String propertyBeanName;
private ApplicationContext applicationContext;
public void setPropertyBeanName(final String propertyBeanName){
this.propertyBeanName = propertyBeanName;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException{
this.applicationContext = applicationContext;
}
public String getProperty(final String propertyName){
return ((Properties) applicationContext.getBean(propertyBeanName)).getProperty(propertyName);
}
}