SpringBoot配置走数据库(自定义配置源)
SpringBoot配置走数据库(自定义配置源)
有时候我们想更改一些配置而又不像重新修改yml或者properties文件重新打包,除了springcloud的config之外,我们可以把配置写在数据库中通过 @Value("${xxx.xxx}")的方式去使用。
Mysql定义配置表格
DROP TABLE IF EXISTS `tb_system_properties`;
CREATE TABLE `tb_system_properties` (
`k` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '键',
`v` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '值',
`remark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '备注',
PRIMARY KEY (`k`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '系统属性表' ROW_FORMAT = Dynamic;
自定义配置源
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
/**
* @author oujiangping
*/
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) {
System.out.println("DbPropertiesPostProcessor.postProcessEnvironment");
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.url"))
.driverClassName("com.mysql.jdbc.Driver")
.build();
// Fetch all properties
Connection connection = ds.getConnection();
System.out.println("ReadDbPropertiesPostProcessor configuracion from database");
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM tb_system_properties");
ResultSet rs = preparedStatement.executeQuery();
// Populate all properties into the property source
while (rs.next()) {
propertySource.put(rs.getString("k"), rs.getString("v"));
}
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) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
指定EnvironmentPostProcessor
在resources目录下添加文件META-INF/spring.factories,内容如下:
org.springframework.boot.env.EnvironmentPostProcessor=xxx.xxx.DbPropertiesPostProcessor
使用
- 数据库添加配置如:k = test.abc, v= hello world
- 在使用的地方使用@Value("${test.abc}")既可以使用
大功告成!!!