Java 是否可以将Spring@Import或@Configuration参数化?
我创建了许多常见的小型bean定义容器(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
@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}");
}