2009-02-10 8 views

Répondre

7

Je ne vous recommanderais pas de le faire. Qu'attendez-vous des haricots singleton que leur configuration a modifié? Pensez-vous que tous les singletons se rechargeront? mais certains objets peuvent contenir des références à ces singletons.

Voir ce poste et Automatic configuration reinitialization in Spring

10

Eh bien, il peut être utile d'effectuer un tel contexte reload tout en testant votre application.

Vous pouvez essayer la méthode refresh de l'une des classes AbstractRefreshableApplicationContext: elle n'actualisera pas vos beans précédemment instanciés, mais l'appel suivant sur le contexte retournera des beans rafraîchis.

import java.io.File; 
import java.io.IOException; 

import org.apache.commons.io.FileUtils; 
import org.springframework.context.support.FileSystemXmlApplicationContext; 

public class ReloadSpringContext { 

    final static String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
     "<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\"\n" + 
     " \t\"http://www.springframework.org/dtd/spring-beans.dtd\">\n"; 

    final static String contextA = 
     "<beans><bean id=\"test\" class=\"java.lang.String\">\n" + 
      "\t\t<constructor-arg value=\"fromContextA\"/>\n" + 
     "</bean></beans>"; 

    final static String contextB = 
     "<beans><bean id=\"test\" class=\"java.lang.String\">\n" + 
      "\t\t<constructor-arg value=\"fromContextB\"/>\n" + 
     "</bean></beans>"; 

    public static void main(String[] args) throws IOException { 
     //create a single context file 
     final File contextFile = File.createTempFile("testSpringContext", ".xml"); 

     //write the first context into it 
     FileUtils.writeStringToFile(contextFile, header + contextA); 

     //create a spring context 
     FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
      new String[]{contextFile.getPath()} 
     ); 

     //echo the bean 'test' on stdout 
     System.out.println(context.getBean("test")); 

     //write the second context into it 
     FileUtils.writeStringToFile(contextFile, header + contextB); 

     //refresh the context 
     context.refresh(); 

     //echo the bean 'test' on stdout 
     System.out.println(context.getBean("test")); 
    } 

} 

Et vous obtenez ce résultat

fromContextA 
fromContextB 

Une autre façon d'y parvenir (et peut-être plus simple) est d'utiliser la fonction Bean actualisables du printemps 2.5+ Avec un langage dynamique (groovy, etc) et le printemps, vous pouvez même changer le comportement de votre haricot. Jetez un coup d'œil au spring reference for dynamic language:

24.3.1.2. haricots actualisables

L'un des (sinon la) plus valeur irrésistible ajoute du soutien linguistique dynamique au printemps est la fonction 'haricot actualisable.

Un haricot actualisable est un haricot soutenu langue dynamique qui avec une petite quantité de configuration, un haricot langage soutenu dynamique peut de surveiller les changements dans la ressource de fichier source sous-jacente, puis recharger lui-même lorsque le fichier source de langue dynamique est modifié (par exemple lorsqu'un développeur modifie et enregistre les modifications apportées au fichier sur le système de fichiers ).

2

Vous pouvez jeter un oeil à ce http://www.wuenschenswert.net/wunschdenken/archives/138 où une fois que vous changez quelque chose dans le fichier de propriétés et l'enregistrez, les beans seront rechargés avec les nouvelles valeurs.

+0

Ceci a été adapté sur https://github.com/Unicon/springframework-addons/wiki/Auto-reloading-properties-files – Vadzim

+0

Liens mis à jour: http://maven-repository.com/artifact/net.unicon. springframework/springframework-addons/0.1, https://github.com/UniconLabs/springframework-addons/blob/master/src/main/java/net/unicon/springframework/addons/properties/ReloadingPropertyPlaceholderConfigurer.java, https: // github.com/knightliao/disconf/blob/master/disconf-client/src/main/java/com/baidu/disconf/client/addons/properties/ReloadingPropertyPlaceholderConfigurer.java – Vadzim

1

Pour ceux qui sont tombés sur cela plus récemment - la façon actuelle et moderne de résoudre ce problème est d'utiliser Spring Boot's Cloud Config.

Ajoutez simplement l'annotation @RefreshScope sur vos grains actualisables et @EnableConfigServer sur votre configuration principale.

Ainsi, par exemple, cette classe de contrôleur:

@RefreshScope 
@RestController 
class MessageRestController { 

    @Value("${message}") 
    private String message; 

    @RequestMapping("/message") 
    String getMessage() { 
     return this.message; 
    } 
} 

renverra la nouvelle valeur de votre propriété Chaîne message pour le point final /message chaque fois que votre configuration est mis à jour.

Voir l'exemple Spring Guide for Centralized Configuration officiel pour plus de détails de mise en œuvre.

Questions connexes