Spring ConditionalOnProperty 用于外部属性

Posted

技术标签:

【中文标题】Spring ConditionalOnProperty 用于外部属性【英文标题】:Spring ConditionalOnProperty for external properties 【发布时间】:2018-07-20 21:13:40 【问题描述】:

似乎 ConditionalOnProperty 仅适用于类路径中的属性,例如资源文件夹中的 application.properties。我需要一个最终用户可以通过外部属性打开和关闭的属性。一个例子非常简单:

配置类,读取外部属性。 Sys.out 以显示它正在正确读取文件。

@Configuration
@EnableAutoConfiguration
@PropertySource("file:/Users/end.user/MyApp/config/MyApp.properties")
public class PropertyConfigurer 
    @Value("$featureOne")
    private String featureOne;

    @PostConstruct
    public void init() 
        System.out.println("FeatureOne : " + featureOne);
    

Feature 类,如果通过 ConditionalOnProperty 启用该属性,则该组件类将被放入应用程序上下文中以便能够使用,否则永远不会实例化该组件。

@Component
@ConditionalOnProperty(name="featureOne", havingValue = "true")
public class FeatureOne 
    @PostConstruct
    public void init() 
        System.out.println("Feature initialized");
    

你可以想象我从来没有看到“功能初始化”,因为“featureOne”属性直到这个类被构造之后才可用于spring上下文。如果有某种方法可以强制 @PropertySource 中的属性在类实例化时可用于 spring 上下文。还是有什么其他方式?我还尝试了 FeatureOne 中的 @DependsOn PropertyConfigurer,但有趣的是,这也没有用。

【问题讨论】:

【参考方案1】:

似乎 ConditionalOnProperty 仅适用于 类路径,如资源文件夹中的 application.properties。

不完全是。它也适用于外部文件,前提是它们在运行期间使用spring.config.location 选项指定为程序参数。

--spring.config.location=file:/Users/end.user/MyApp/config/MyApp.properties

问题是@PropertySource 正在被org.springframework.context.annotation.ConfigurationClassParser::processPropertySource 方法读取。并且 @ConditionalOnProperty 正在通过 org.springframework.boot.autoconfigure.condition.OnPropertyCondition::getMatchOutcome 方法进行验证。 如果你在这两个地方进行调试,你会发现先执行getMatchOutcome,然后执行processPropertySource。因此,您的情况不适用于@PropertySource

但是如果你以java -jar abc.jar --spring.config.location=file:/Users/end.user/MyApp/config/MyApp.properties 运行你的应用程序,那么这些属性将被添加到context.environment 中,因此@ConditionalOnProperty 可以工作。

如果有某种方法可以强制 @PropertySource 中的属性 在类实例化时可用于 spring 上下文

我不确定是否有任何方法可以做到这一点。但是考虑到您的要求(我需要一个最终用户可以通过外部属性打开和关闭的属性),使用spring.config.location 将是一个谨慎的选择。

【讨论】:

以上是关于Spring ConditionalOnProperty 用于外部属性的主要内容,如果未能解决你的问题,请参考以下文章

你了解Spring从Spring3到Spring5的变迁吗?

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring事务管理和Spring事务传播行为