Spring ConditionalOnProperty用于外部属性

时间:2018-02-10 03:50:01

标签: java spring spring-boot properties configuration

似乎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);
    }
}

要素类,如果通过ConditionalOnProperty启用该属性,则此组件类将放在应用程序上下文中,否则该组件永远不会被实例化。

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

您可以想象,由于“featureOne”属性在构建此类之后才可用于spring上下文,因此我从未看到“Feature initialized”。如果有一些方法可以强制@PropertySource中的属性在类实例化时可用于spring上下文。还是其他任何方式?我也试过@DependsOn来自FeatureOne的PropertyConfigurer,但有趣的是也没用。

1 个答案:

答案 0 :(得分:3)

  

似乎ConditionalOnProperty仅适用于其中的属性   classpath就像资源文件夹中的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.config.location将是一个谨慎的选择。