似乎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,但有趣的是也没用。
答案 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
将是一个谨慎的选择。