Comment gérer deux ensembles de propriétés au moment de l’exécution?

Je construis un service Web qui doit basculer entre deux ensembles de propriétés en fonction de l’URL de requête entrant. Je ne sais pas quelle est la meilleure méthode pour gérer cela.

J’ai une application Spring Boot qui a un fichier de propriétés yaml. Dans le fichier de propriétés, la structure ressemble à ceci:

optionA: foo: urls: - a - b bar: something: hello optionB: foo: urls: - x - y bar: something: bye 

optionA et optionB ont à peu près toutes les mêmes propriétés, juste des valeurs différentes.

Donc, une demande arrive, je vérifie la demande et décide si j’ai besoin d’optionA ou d’optionB.

J’ai essayé d’obtenir que @ConfigurationProperties en charge cette opération, mais les propriétés sont initialisées au démarrage, ce qui ne peut pas être dynamic. Une autre possibilité est que je dispose de deux classes de configuration, une pour chaque option, mais ensuite mon code se remplit de vérifications permettant de basculer entre les deux classes et les classes sont pratiquement identiques, ce qui n’est pas très agréable non plus.

Toutes les meilleures pratiques ou recommandations sur la meilleure façon de gérer cela seraient appréciées, bravo!

Si vous n’avez pas trop d’options, j’irais de cette façon: (Exemple juste avec une configuration plus petite)

options.yml:

 optionA: name: optionA optionB: name: optionB 

J’ai créé une classe d’option pour l’extension:

 public class Option { private Ssortingng name; public Ssortingng getName() { return name; } public void setName(Ssortingng name) { this.name = name; } } 

Et deux classes Option où les @ConfigurationProperties sont définies: (Pour l’instant, ces classes sont vides, mais vous avez la possibilité d’être plus spécifiques sur chaque option.)

 @Component @ConfigurationProperties(prefix ="optionA", locations = "classpath:options.yml") public class OptionA extends Option{ } @Component @ConfigurationProperties(prefix ="optionB", locations = "classpath:options.yml") public class OptionB extends Option{ } 

Pour la décision des différentes options, j’ai créé une interface :

 public interface OptionService { Option findOption(boolean businessLogic); } 

Et dans l’implémentation, j’injecte les deux options et l’implémentation de la logique métier: (de manière simple)

 @Service public class OptionServiceImpl implements OptionService { private OptionA optionA; private OptionB optionB; @Override public Option findOption(boolean businessLogic) { if(businessLogic){ return getOptionA(); } else { return getOptionB(); } } public OptionA getOptionA() { return optionA; } @Autowired public void setOptionA(OptionA optionA) { this.optionA = optionA; } public OptionB getOptionB() { return optionB; } @Autowired public void setOptionB(OptionB optionB) { this.optionB = optionB; } } 

Et à la fin, votre contrôleur appelle simplement la classe OptionServiceImpl et détermine quelle option doit être utilisée:

 @Controller public class YourController { private OptionService optionServiceImpl; @RequestMapping("/") public Ssortingng getIndex(){ Option option = getOptionServiceImpl().findOption(true); System.out.println(option.getName()); option = getOptionServiceImpl().findOption(false); System.out.println(option.getName()); return "Hello World"; } public OptionService getOptionServiceImpl() { return optionServiceImpl; } @Autowired public void setOptionServiceImpl(OptionService optionServiceImpl) { this.optionServiceImpl = optionServiceImpl; } } 

Sortie de System.out.println:

 optionA optionB 

Par conséquent, la logique de votre entreprise pour décider de l’option à utiliser n’est pas une construction if-else. Vous pouvez créer les règles pour la décision dans l’interface et son implémentation. Je pense que vous êtes capable de créer plus de règles pour plus de contrôleurs.

Vous pouvez définir des paires clé-valeur dans application.properties.

où clé est le nom du service Web et la valeur est l’option (liste des propriétés)

Utiliser @ConfigurationProperties

 @ConfigurationProperties class Configuration { Map options; // getters and setters } @Component class ChooseServiceBasedConfiguration { @Autowired Configuration configuration; public void serviceMethod(Ssortingng key ){ //get appropriate properties of the web service configuration.getOptions().get(key); } } 

basé sur le service Web, obtenez les valeurs requirejses à l’aide de la clé.

Changez votre yml en:

 options: - name: optionA foo: urls: - a - b bar: something: hello - name: optionB foo: urls: - x - y bar: something: bye 

Ajouter une classe de configuration:

 @Data @ConfigurationProperties @Configuration public class MyConfig { private List 

Utilise le:

 @Component public class UseConfig { @Autowired public UseConfig(final MyConfig config) { System.out.println(config.getOptions()); } } 

Résultat:

 [Option(name=optionA, foo=Foo(urls=[a, b]), bar=Bar(something=hello)), Option(name=optionB, foo=Foo(urls=[x, y]), bar=Bar(something=bye))]