java 外部特性的Spring条件OnProperty

pbpqsu0x  于 2023-01-19  发布在  Java
关注(0)|答案(1)|浏览(143)

看起来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上下文可用。或者任何其他方法?我也尝试了@DependsOnFeatureOne中的PropertyConfigurer,但有趣的是,它们也不起作用。

wz8daaqr

wz8daaqr1#

看起来ConditionalOnProperty只对类路径中的属性有效,如application.properties资源文件夹中的www.example.com。
不完全是。它也可以处理外部文件,只要它们在运行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将是一个谨慎的选择。

相关问题