Est-il possible de paramétrer Spring @Import ou @Configuration?

J’ai créé beaucoup de petits conteneurs de définition de bean ( @Configuration ) que j’utilise pour développer rapidement des applications avec Spring Boot comme:

 @Import({ FreemarkerViewResolver.class, // registers freemarker that auto appends <#escape etc. ConfigurationFromPropertiesFile.class, // loads conf/configuration.properties UtfContentTypeResponse.class, // sets proper Content-language and Content-type LocaleResolverWithLanguageSwitchController // Locale resolver + switch controller ); class MySpringBootApp ... 

Par exemple, l’un de ces @Configuration configuration peut configurer le stockage de session pour le cookie de parameters régionaux avec le contrôleur Web pour passer à la langue sélectionnée, etc.

Ils sont très amusants à utiliser et à réutiliser, mais ce serait vraiment génial de les paramétrer , ce qui pourrait leur permettre d’être beaucoup plus réutilisés. Je veux dire quelque chose comme:

Pseudo code :

 @Imports( imports = { @FreemarkerViewResolver( escapeHtml = true, autoIncludeSpringMacros = true), @ConfigurationFromProperties( path = "conf/configuration.properties" ), @ContentTypeResponse( encoding = "UTF-8" ), @LocaleResolver( switchLocaleUrl = "/locale/{loc}", defaultLocale = "en" }) 

Donc, je veux dire fondamentalement “configuration configurable”. Quel serait le meilleur moyen de faire la configuration de cette façon?

Peut-être que quelque chose de plus semblable à ceci (encore une fois, pseudo code):

 @Configuration public class MyAppConfiguration { @Configuration public FreemarkerConfiguration freemarkerConfiguration() { return FreemarkerConfigurationBuilder.withEscpeAutoAppend(); } @Configuration public ConfigurationFromPropertiesFile conf() { return ConfigurationFromPropertiesFile.fromPath("..."); } @Configuration public LocaleResolverConfigurator loc() { return LocaleResolverConfigurator.trackedInCookie().withDefaultLocale("en").withSwitchUrl("/switchlocale/{loc}"); } 

Permettez-moi de citer le Guide de référence de Spring Boot – Configuration externalisée :

“Spring Boot vous permet d’externaliser votre configuration pour que vous puissiez travailler avec le même code d’application dans différents environnements.”

A mon avis, la personnalisation n’est pas effectuée au moment de l’importation via des parameters d’annotation comme dans votre deuxième bloc de pseudo-code, mais la personnalisation se produit au moment de l’exécution, par exemple dans les classes de configuration. Laissez-moi adapter votre 3ème bloc de code (une seule fonction):

 @Configuration public class MyAppConfiguration { @Autowired private Environment env; // Provide a default implementation for FreeMarkerConfigurer only // if the user of our config doesn't define her own configurer. @Bean @ConditionalOnMissingBean(FreeMarkerConfigurer.class) public FreeMarkerConfigurer freemarkerConfig() { FreeMarkerConfigurer result = new FreeMarkerConfigurer(); result.setTemplateLoaderPath("/WEB-INF/views/"); return result; } ... @Bean public LocaleResolverConfigurator loc() { Ssortingng defaultLocale = env.getProperty("my.app.config.defaultlocale", "en"); Ssortingng switchLocale = env.getProperty("my.app.config.switchlocale", "/switchlocale/{loc}"); return LocaleResolverConfigurator.trackedInCookie().withDefaultLocale(defaultLocale).withSwitchUrl(switchLocale); } 

Pour LocaleResolverConfigurator la configuration est lue dans l’environnement, des valeurs par défaut significatives sont définies. Il est facile de modifier la ou les valeurs par défaut en fournissant une valeur différente pour un paramètre de configuration dans n’importe laquelle des méthodes sockets en charge (documentées dans le premier lien) – via une ligne de commande ou un fichier yaml. L’avantage par rapport aux parameters d’annotation est que vous pouvez modifier le comportement au moment de l’exécution au lieu de la compilation.

Vous pouvez également injecter les parameters de configuration (si vous préférez les avoir comme variable d’instance) ou utiliser beaucoup d’autres conditions, par exemple @ConditionalOnMissingBean , @ConditionalOnClass , @ConditionalOnExpression , etc. Par exemple, avec @ConditionalOnClass vous pouvez vérifier si une classe particulière se trouve sur votre chemin de classe et définir un paramètre pour la bibliothèque identifiée par cette classe. Avec @ConditionalOnMissingClass vous pouvez fournir une implémentation alternative. Dans l’exemple ci-dessus, j’ai utilisé ConditionalOnMissingBean pour fournir une implémentation par défaut pour FreeMarkerConfigurer . Cette implémentation n’est utilisée que lorsqu’aucun bean FreeMarkerConfigurer n’est disponible et peut donc être facilement remplacé.

Jetez un coup d’oeil aux démarreurs fournis par Spring Boot ou par la communauté. Une bonne lecture est aussi cette entrée de blog . J’ai beaucoup appris de Spring-Boot-Starter-Batch-Web , ils ont publié une série d’articles dans un magazine Java allemand, mais des parties sont également en ligne. Voir Boot your own infrastructure – Extension de Spring Boot en cinq étapes ( MUST READ ) le paragraphe “Rendre votre démarreur configurable en utilisant les propriétés”.

Bien que j’aime l’idée de paramétrer les importations, je pense qu’en ce moment, l’utilisation de @Import et @Configuration ne @Configuration pas.

Je peux penser à deux façons d’utiliser des configurations dynamics, qui ne reposent pas sur la configuration de style PropertySource .

  1. Créez un @ImportConfig annotation et d’annotation @ImportConfig personnalisé qui accepte les propriétés de configuration qui sont codées en dur dans les fichiers source générés.
  2. Utilisez un BeanFactoryPostProcessor ou un BeanPostProcessor pour append ou manipuler vos beans inclus respectivement.

L’OMI n’est pas particulièrement simple, mais comme il semble que vous ayez une façon de travailler particulière. Cela pourrait donc valoir le temps investi.