Spring - Sostituzione dei valori delle proprietà di fagioli con i valori di file nuova proprietà

StackOverflow https://stackoverflow.com/questions/4084890

Domanda

Ho un file di proprietà e l'utilizzo di proprietà posto titolare Primavera, ho impostato i valori ai fagioli di primavera. Ora, questo file proprietà può essere modificato durante la fase di esecuzione. C'è un modo per aggiornare le proprietà dei bean Spring con questo valore di proprietà appena modificato? In particolare, ho molti fagioli Singleton? Come posso aggiornare con i nuovi valori? C'è già una soluzione a questo o dovrebbe essere codificato personalizzato? Se non esiste già, qualcuno può dare l'approccio migliore per raggiungere questo obiettivo? Grazie!

PS: La mia applicazione è un'applicazione batch. Io uso la configurazione quarzo basato primavera per pianificare le partite.

È stato utile?

Soluzione

Lascio questo riferimento, ma la risposta è al di sotto aggiornato il divisore:

Bene l'interfaccia ConfigurableApplicationContext contiene un refresh () il metodo , che dovrebbe essere ciò che si vuole, ma la domanda è: come accedere a tale 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

  1. Task Execution quadro e lasciate che il vostro fagioli guardare le risorse di proprietà regolarmente, aggiornare l'ApplicationContext quando trova modifiche o
  2. esporre il fagioli a JMX , che consente di attivare manualmente l'aggiornamento.

Facendo riferimento a commenti:. In quanto 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 Singleton fagioli, una soluzione può essere trovata qui .

Se non si vuole iniettare ricerca metodi di tutto il luogo, si potrebbe anche iniettare un fagiolo PropertyProvider in questo modo:

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);
    }

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top