Java 是否可以将Spring@Import或@Configuration参数化?

Java 是否可以将Spring@Import或@Configuration参数化?,java,spring,spring-mvc,annotations,spring-boot,Java,Spring,Spring Mvc,Annotations,Spring Boot,我创建了许多常见的小型bean定义容器(@Configuration),我使用这些容器快速开发具有Spring Boot的应用程序,如: @Import({ FreemarkerViewResolver.class, // registers freemarker that auto appends <#escape etc. ConfigurationFromPropertiesFile.class, // loads conf/configuration.propertie

我创建了许多常见的小型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 ...
所以,我基本上是指“可配置的
@配置
以这种方式进行配置的最佳方式是什么?

也许更像这样(同样是伪代码):

让我引述:

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

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

@配置
公共类MyAppConfiguration{
@自动连线
私人环境署;
//仅为FreeMarkerConfigure提供默认实现
//如果配置的用户没有定义自己的配置程序。
@豆子
@ConditionalOnMissingBean(FreeMarkerConfigurer.class)
public freemarkerconfiguer freemarkerConfig(){
FreeMarkerconfiguer结果=新建FreeMarkerconfiguer();
result.setTemplateLoaderPath(“/WEB-INF/views/”);
返回结果;
}
...
@豆子
公共LocaleResolverConfigurator loc(){
字符串defaultLocale=env.getProperty(“my.app.config.defaultLocale”,“en”);
字符串switchLocale=env.getProperty(“my.app.config.switchLocale”,“/switchLocale/{loc}”);
返回LocaleResolverConfigurator.trackedInCookie().withDefaultLocale(defaultLocale)。withSwitchUrl(switchLocale);
}
对于
LocaleResolverConfigurator
从环境中读取配置,定义有意义的默认值。通过以任何支持的方式(记录在第一个链接中)为配置参数提供不同的值,可以轻松更改默认值-通过命令行或yaml文件。与注释参数相比的优点是,您可以在运行时而不是编译时更改行为

您还可以插入配置参数(如果希望将它们作为实例变量)或者使用许多其他条件,例如和。例如,使用
@ConditionalOnClass
可以检查特定类是否在类路径上,并为该类标识的库提供设置。使用
@ConditionalOnMissingClass
可以提供替代实现。在上面的示例中,我使用了e> ConditionalOnMissingBean
FreeMarkerConfigure
提供默认实现。此实现仅在没有
FreeMarkerConfigure
bean可用时使用,因此可以轻松重写


看看Spring Boot或社区提供的初学者。这也是一本很好的读物。我从中学到了很多,他们在一本德国Java杂志上发表了一系列文章,但部分内容也在线,请参阅(必读),特别是“使用属性配置初学者”一段.

虽然我喜欢将导入参数化的想法,但我认为目前使用
@Import
@Configuration
并不合适

我可以想出两种使用动态配置的方法,它们不依赖于
PropertySource
样式配置

  • 创建一个自定义的
    @ImportConfig
    注释和注释处理器,该处理器接受硬编码到生成的源文件中的配置属性
  • 使用
    BeanFactoryPostProcessor
    BeanPostProcessor
    分别添加或操作包含的bean

  • 这两种方法在我看来都不是特别简单,但因为它看起来像是你有一种特殊的工作方式。因此值得投入时间。

    你确定方法注释应该是
    @Configuration
    ?另外,我非常不喜欢属性驱动的配置,因为我的大多数配置都不依赖于环境,而且这个驱动器也不是o一大包混合在一起的属性。@PiotrMüller你可能应该在问题中提到你对属性的厌恶,因为它改变了一个很好的答案。在配置文件中获得更多结构的一个非常简单的方法是使用YAML。如果你也不喜欢YAML,那么你也应该提到。1)对于e> @Configuration
    annotation:我刚刚把你的代码用在了“属性驱动的配置”中.2)即使对于与环境无关的配置数据,您也可以使用属性。第二个代码块中的所有设置都非常适合在属性中配置。3)除了属性之外,还有很多其他可能性。我用
    @ConditionalOnClass
    的一个场景和一个到博客条目的链接更新了我的答案。@chrlip我在问你对于注释,因为我甚至不知道在方法级别是否允许
    @Configuration
    ,我的代码只是一个伪代码。
    LocaleResolverConfigurator
    是否将作为常规
    @Configuration
    类处理,并且所有包含
    @Bean
    的方法都将创建一个Bean?好的,我知道了。我确实错过了这个。我不知道I don’我不认为这是可能的,我也不太清楚你为什么需要这样做。你有多个配置,你必须像以前一样导入它们-唯一的改变是你可以参数化配置。要摆脱导入,你还可以定义你自己的
    Enable*
    注释,你还可以在一个单独的文件中对多个配置进行分组e
    启用*
    注释。
    @Imports( imports = {
      @FreemarkerViewResolver( escapeHtml = true, autoIncludeSpringMacros = true),
      @ConfigurationFromProperties( path = "conf/configuration.properties" ),
      @ContentTypeResponse( encoding = "UTF-8" ),
      @LocaleResolver( switchLocaleUrl = "/locale/{loc}", defaultLocale = "en"
    })
    
    @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}");
        }