是否有可能使Spring @Import或@Configuration参数化?

Pio*_*ler 17 java spring annotations spring-mvc spring-boot

我创建了许多常见的小bean定义容器(@Configuration),我用它来快速开发Spring Boot应用程序,如:

@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 ...
Run Code Online (Sandbox Code Playgroud)

例如,其中一个@Configuration可以通过Web控制器为区域设置cookie设置会话存储,以切换到所选语言等.

使用和重用它们非常有趣,但是将它设置为参数化会非常棒,这可以允许更多的重用.我的意思是:

伪代码:

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

所以,我的意思是"可配置@Configurations".以这种方式进行配置的最佳方法是什么?

也许更像这样的东西(再次,伪代码):

@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}");
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*ipp 10

让我引用Spring Boot参考指南 - 外化配置:

"Spring Boot允许您外部化您的配置,以便您可以在不同的环境中使用相同的应用程序代码."

在我看来,定制不是在导入时通过注释参数完成的,例如在第二个伪代码块中,而是定制在运行时发生,例如在配置类中.让我调整你的第三个代码块(只有一个函数):

@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() {
        String defaultLocale = env.getProperty("my.app.config.defaultlocale", "en");
        String switchLocale = env.getProperty("my.app.config.switchlocale", "/switchlocale/{loc}");

        return LocaleResolverConfigurator.trackedInCookie().withDefaultLocale(defaultLocale).withSwitchUrl(switchLocale);
    }
Run Code Online (Sandbox Code Playgroud)

为了LocaleResolverConfigurator从环境中读取配置,定义了有意义的默认值.通过以任何支持的方式(在第一个链接中记录)为配置参数提供不同的值 - 通过命令行或yaml文件,可以轻松更改默认值.注释参数的优点是您可以在运行时而不是编译时更改行为.

您也可以注入的配置参数(如果您愿意让他们作为实例变量),或使用了大量的其他条件,例如@ConditionalOnMissingBean,@ConditionalOnClass,@ConditionalOnExpression.例如,@ConditionalOnClass您可以检查特定类是否在类路径上,并为此类标识的库提供设置.有了@ConditionalOnMissingClass你可以提供一个可选的实现.在上面的例子中,我曾经ConditionalOnMissingBean为它提供了一个默认的实现FreeMarkerConfigurer.此实现仅在没有FreeMarkerConfigurerbean可用时使用,因此可以轻松覆盖.

看看Spring Boot或社区提供的初学者.这篇博客文章也很好读.我从spring-boot-starter-batch-web中学到了很多东西,他们在德国Java杂志上有一篇文章系列,但部分也在线,请参阅启动你自己的基础设施 - 分五步扩展Spring Boot(必读),特别是段落"通过使用属性使您的起始器可配置".