看起来ConditionalOnProperty
只适用于类路径中的属性,比如resources文件夹中的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");
}
}
正如你所想象的,我从来没有看到“Feature initialized”,因为“featureOne”属性直到这个类被构造之后才对spring上下文可用。是否有某种方法可以强制@PropertySource
的属性在类示例化时对spring上下文可用。或者任何其他方法?我也尝试了@DependsOn
和FeatureOne
中的PropertyConfigurer
,但有趣的是,它们也不起作用。
1条答案
按热度按时间wz8daaqr1#
看起来ConditionalOnProperty只对类路径中的属性有效,如application.properties资源文件夹中的www.example.com。
不完全是。它也可以处理外部文件,只要它们在运行
spring.config.location
选项时被指定为程序参数。问题是
@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
将是一个谨慎的选择。