Spring Boot:从数据库中检索配置
Posted
技术标签:
【中文标题】Spring Boot:从数据库中检索配置【英文标题】:Spring Boot: Retrieving configuration from a database 【发布时间】:2015-07-24 14:40:36 【问题描述】:谁能给我一些指导,告诉我实现这一目标的最佳方式。
我想扩展 Spring Boot Externalized Configuration 以便我有一个可以从我的应用程序的任何位置调用的方法。此方法将使用键检索属性值。此方法将首先查询一个数据库表,如果它没有找到指定的键,它将回退到 1 中描述的 PropertySource 顺序。
所以我会有类似的服务:
@Service
public class ConfigurationService
private final ConfigurationRepository configurationRepository;
@Autowired
public ConfigurationService(ConfigurationRepository configurationRepository)
this.configurationRepository = configurationRepository;
public String getValue(String key)
Configuration configuration = configurationRepository.findOne(key);
// Add something here to get the property from application.properties if the key does not exist in the db
return configuration == null ? null : configuration.getValue();
我可以使用如下:
foo = configuration.getValue("my.property");
有没有更好的方法来解决这个问题?我是否缺少可以使用的 Spring Boot 功能?
编辑:我希望能够在应用程序运行时更改属性值并获取这些新值。
【问题讨论】:
根据您的项目/部署的规模,这听起来像是 Spring Cloud Config 的潜在案例。 写一个由数据库支持的PropertySource
,这样它就可以与系统的其余部分集成。或者简单地编写一个ApplicationInitializer
,它从数据库中加载所有属性,将它们包装在PropertiesPropertySource
中并将它们添加到环境中。至少您不想在要与默认机制集成的整个地方调用此方法。
如何使用与数据库链接的缓存来存储键值对
我认为由数据库支持的PropertySource
是我所需要的。如何确保在 application.properties 等之前考虑这一点。
将它放在另一个 PropertySources
的顶部或您想要的位置。
【参考方案1】:
我已经使用 EnvironmentPostProcessor spring 特性来做到这一点。
你需要像这样创建一个类:
public class ReadDbPropertiesPostProcessor implements EnvironmentPostProcessor
/**
* Name of the custom property source added by this post processor class
*/
private static final String PROPERTY_SOURCE_NAME = "databaseProperties";
/**
* Adds Spring Environment custom logic. This custom logic fetch properties from database and setting highest precedence
*/
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
Map<String, Object> propertySource = new HashMap<>();
try
// Build manually datasource to ServiceConfig
DataSource ds = DataSourceBuilder
.create()
.username(USERNAME) // replace with your config
.password(PASSWORD) // replace with your config
.url(DATASOURCE-URL)// replace with your config
.driverClassName(DRIVER) // replace with your config
.build();
// Fetch all properties
PreparedStatement preparedStatement = ds.getConnection().prepareStatement("SELECT name, value FROM propertyConfig WHERE service = ?");
preparedStatement.setString(1, APP_NAME);
ResultSet rs = preparedStatement.executeQuery();
// Populate all properties into the property source
while (rs.next())
String propName = rs.getString("name");
propertySource.put(propName, rs.getString("value"));
// Create a custom property source with the highest precedence and add it to Spring Environment
environment.getPropertySources().addFirst(new MapPropertySource(PROPERTY_SOURCE_NAME, propertySource));
catch (Exception e)
throw new RuntimeException("Error fetching properties from db");
由于您需要在春季的早期阶段运行此类,因此您需要创建文件spring.factories
并注册您的环境后处理器。此文件需要位于此处:
src/main/resources/META-INF/spring.factories
在内容中你需要将你的类设置为spring属性:
# Environment Post Processor
org.springframework.boot.env.EnvironmentPostProcessor=com.your.package.ReadDbPropertiesPostProcessor
【讨论】:
什么是 PROPERTY_SOURCE_NAME?在我的情况下,我想将属性添加到默认配置文件:application.properties @user3871754 它是属性源 spring mapMapPropertySource
的“键”名称。 Spring boot 在内部处理存储属性源的映射,我正在添加一个新的 addFirst
我不得不将以下位置用于弹簧工厂。 src/main/resources/META-INF/spring-factories以上是关于Spring Boot:从数据库中检索配置的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中使用特定日期范围和聚合从 MongoDB 数据库中检索数据?
如何检索 Vault 属性以在 application.yml 中配置 MongoDB 属性?
如何在 Spring Boot 中从资源服务器中的令牌中提取声明
Spring Boot 自动配置的 Jackson ObjectMapper 默认不用于 WebFlux WebClient