Lascio questo riferimento, ma la risposta aggiornato è al di sotto del divisore:
Bene l'interfaccia ConfigurableApplicationContext
contiene un metodo refresh(), che dovrebbe essere ciò che si vuole, ma la domanda è: come accedere quel metodo. In qualunque modo lo si fa, si inizia con un fagiolo che ha una dipendenza di tipo ConfigurableApplicationContext
:
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
Ora le due opzioni di base io suggerirei sarebbe a uno
- utilizzare il Task Execution Framework e lascia che il tuo bean controlli regolarmente le risorse della proprietà, aggiornando ApplicationContext quando trova le modifiche o
- expose the bean to JMX, consentendo di attivare manualmente l'aggiornamento.
riferisco a commenti: poiché sembra impossibile aggiornare l'intero contesto, una strategia alternativa potrebbe essere quella di creare un chicco di proprietà fabbrica e iniettare che in tutte le altre fagioli.
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;
}
}
Si potrebbe iniettare gli annunci di questo fagiolo in tutti gli altri fagioli, tuttavia, si dovrà fare attenzione ad usare sempre prototipo ambito. Questo è particolarmente difficile all'interno dei fagioli singleton, a solution can be found here.
Se non si vuole iniettare metodi di ricerca in tutto il luogo, si potrebbe anche iniettare un PropertyProvider
fagioli come questo:
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);
}
}
fonte
2010-11-03 08:05:22
Non sarebbe questo carico l'intero contesto di applicazione? Potete per favore condividere qualche campione? Sono abbastanza nuovo per Spring, quindi potrei sbagliarmi. Ho anche pensato di ricaricare l'intero contesto applicativo di primavera, ma ciò significherebbe che altri processi attualmente in esecuzione potrebbero essere interrotti. O forse sto pensando male! – SJoe
No, hai ragione, il contesto completo sarebbe stato aggiornato. –
In tal caso, il mio processo in corso non verrà interrotto. Il mio è un'applicazione batch e potrebbe richiedere ore per completare un processo. Inoltre, ho un SchedularFactoryBean configurato tramite Spring. La mia domanda è, se ricarico completamente il contesto dell'applicazione, lo scheduler non dovrebbe essere ripristinato? – SJoe