Spring - Remplacement des valeurs de propriété de haricots avec de nouvelles valeurs de fichier de propriété

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

Question

J'ai un fichier de propriétés et à l'aide de porte-lieu de la propriété printemps, je mets des valeurs aux grains de printemps. Maintenant, ce fichier de propriété peut être modifié pendant la durée de l'exécution. Est-il un moyen de rafraîchir les propriétés des grains de printemps avec cette valeur de la propriété nouvellement modifiée? Surtout, j'ai beaucoup de haricots singleton? Comment puis-je les rafraîchir avec les nouvelles valeurs? Y at-il déjà une solution à ce ou doit-il être codé sur mesure? Si elle n'existe pas déjà, quelqu'un peut-il s'il vous plaît donner la meilleure approche pour y parvenir? Merci!

PS: Mon application est une application de traitement par lots. J'utilise la configuration à base de quartz printemps pour planifier les lots.

Était-ce utile?

La solution

Je vais laisser cela à titre de référence, mais la réponse est mis à jour en dessous du diviseur:

Eh bien l'interface ConfigurableApplicationContext contient un refresh () , qui devrait être ce que vous voulez, mais la question est: comment accéder à cette méthode. Quelle que soit la façon dont vous le faites, vous allez commencer avec un haricot qui a une dépendance de type ConfigurableApplicationContext:

private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
    this.context = ctx;
}

Maintenant, les deux options de base je proposerais seraient soit

  1. utilisez le cadre de la Tâche d'exécution et laissez votre haricots regarder les ressources de propriété régulièrement, rafraîchir la ApplicationContext quand il trouve des modifications ou
  2. exposer la haricots à JMX , ce qui vous permet de déclencher manuellement le rafraîchissement.

Faisant référence aux observations. Car il semble impossible de rafraîchir tout le contexte, une stratégie alternative serait de créer un haricot d'usine de propriétés et injectent que dans toutes les autres haricots

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

}

Vous pouvez injecter les annonces de haricots dans tous vos autres haricots, cependant, vous devez être prudent d'utiliser toujours la portée du prototype. Ceci est particulièrement délicat à l'intérieur singleton haricots, une solution peut être trouvée ici .

Si vous ne voulez pas injecter recherche des méthodes dans tous les sens, vous pouvez aussi injecter un grain de PropertyProvider comme ceci:

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top