注入一个表作为配置源的PropertySource。PostProcessor实现了EnvironmentPostProcessor接口,每当Springboot程序重启时都会被执行
public class DbPropertiesPostProcessor 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(environment.getProperty("spring.datasource.username"))
.password(environment.getProperty("spring.datasource.password"))
.url(environment.getProperty("spring.datasource.jdbc-url"))
.driverClassName("com.mysql.jdbc.Driver")
.build();
// Fetch all properties
Connection connection = ds.getConnection();
log.info("cargando configuracion de la base de datos");
PreparedStatement preparedStatement = connection.prepareStatement("select `key` , `value` from sys_config where `status` = 1");
ResultSet rs = preparedStatement.executeQuery();
// Populate all properties into the property source
while (rs.next()) {
propertySource.put(rs.getString("key"), rs.getString("value"));
}
rs.close();
preparedStatement.clearParameters();
preparedStatement.close();
connection.close();
// 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 (Throwable e) {
throw new RuntimeException(e);
}
}
}
在resource/META-INF
目录下新建spring.factories
文件。类型Springboot Starter 通过spring.factories
文件制定的类会被Spring加载到容器中。
org.springframework.boot.env.EnvironmentPostProcessor=github.jiancai.wang.web.core.DbPropertiesPostProcessor
通过SpringCloud的ContextRefresher
完成配置热更新