gpt4 book ai didi

java - 我可以在没有 Spring AppContext 的情况下手动加载 @ConfigurationProperties 吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:03:49 24 4
gpt4 key购买 nike

有什么方法可以在不直接使用 Spring Context 的情况下加载标有 @ConfigurationProperties 的类?基本上我想重用 Spring 所做的所有智能逻辑,但对于我在 Spring 生命周期之外手动实例化的 bean。

我有一个在 Spring (Boot) 中愉快加载的 bean,我可以将它注入(inject)到我的其他服务 bean 中:

@ConfigurationProperties(prefix="my")
public class MySettings {
String property1;
File property2;
}

有关更多信息,请参阅 spring docco http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-external-config-command-line-args

但现在我需要从在 Spring 之外(由 Hibernate)创建的类访问这个 bean。该类在应用程序启动过程中创建得如此之早,以至于 Spring Boot 尚未通过经典的查找帮助器方法或 roll-my-own 静态引用使应用程序上下文可用。

所以我反而想做这样的事情:

MySettings mySettings = new MySettings(); 
SpringPropertyLoadingMagicClass loader = new SpringPropertyLoadingMagicClass();
loader.populatePropertyValues(mySettings);

并且让 MySettings 最终从命令行、系统属性、app.properties 等加载所有值。Spring 中是否有某个类执行类似的操作,或者它是否与应用程序上下文交织在一起?

显然我可以自己加载 Properties 文件,但我真的想保留 Spring Boot 围绕使用命令行变量(例如 --my.property1=xxx)、系统变量、application.properties 甚至 yaml 的逻辑文件,以及它围绕宽松绑定(bind)和类型转换的逻辑(例如 property2 是一个文件),因此它的工作方式与在 Spring 上下文中使用时完全相同。

可能还是白日梦?

感谢您的帮助!

最佳答案

我有同样的“问题”。这是我在 SpringBoot 版本 1.3.xxx 和 1.4.1 中解决它的方法。

假设我们有以下 yaml 配置文件:

foo:
apis:
-
name: Happy Api
path: /happyApi.json?v=bar
-
name: Grumpy Api
path: /grumpyApi.json?v=grrr

我们有以下ConfigurationProperties:

@ConfigurationProperties(prefix = "foo")
public class ApisProperties {
private List<ApiPath> apis = Lists.newArrayList();

public ApisProperties() {
}

public List<ApiPath> getApis() {
return apis;
}

public static class ApiPath {
private String name;
private String path;

public String getName() {
return name;
}

public void setName(final String aName) {
name = aName;
}

public String getPath() {
return path;
}

public void setPath(final String aPath) {
path = aPath;
}
}
}

然后,要以编程方式 执行 Spring Boot 的“神奇”操作(例如,在静态方法中加载一些属性),您可以执行以下操作:

private static ApisProperties apiProperties() {
try {
ClassPathResource resource;
resource = new ClassPathResource("/config/application.yml");

YamlPropertiesFactoryBean factoryBean;
factoryBean = new YamlPropertiesFactoryBean();
factoryBean.setSingleton(true); // optional depends on your use-case
factoryBean.setResources(resource);

Properties properties;
properties = factoryBean.getObject();

MutablePropertySources propertySources;
propertySources = new MutablePropertySources();
propertySources.addLast(new PropertiesPropertySource("apis", properties));

ApisProperties apisProperties;
apisProperties = new ApisProperties();

PropertiesConfigurationFactory<ApisProperties> configurationFactory;
configurationFactory = new PropertiesConfigurationFactory<>(apisProperties);
configurationFactory.setPropertySources(propertySources);
configurationFactory.setTargetName("foo"); // it's the same prefix as the one defined in the @ConfigurationProperties

configurationFactory.bindPropertiesToTarget();
return apisProperties; // apiProperties are fed with the values defined in the application.yaml

} catch (BindException e) {
throw new IllegalArgumentException(e);

}
}

关于java - 我可以在没有 Spring AppContext 的情况下手动加载 @ConfigurationProperties 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26940583/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com