有时候会遇到"配置文件内不能存在明文密码"的要求,但是就目前互联网上搜索的方法而言,基本是通过引入外部包来实现的,而且还对加解密的方式有要求,比如只能AES/DES之类的。
昨天研究了很久,终于研究出个方法出来,可以在不多加依赖关系的情况下完成配置项预处理。
打个比方,我现在把一些可以随时更改的配置项抽取成一个单独的配置文件[static.yml]放在服务器的文件系统里而不是打包进整个jar包里。
里面姑且放了一个配置项:
spring:
datasource:
password: 加密后的字符串
然后一些写死的配置还是丢在classpath里面的application.yml里,比如驱动啊,用户名,URL之类的,这里就不贴了。
然后重要的来了。
首先新建一个类,这里命名为ProjectPropertiesConfigurer,要实现PropertySourceFactory的方法。
这个类是干什么用的叻?这个是自定义配置文件解析类。
public class ProjectPropertiesConfigurer implements PropertySourceFactory {
@Override public PropertySource<?> createPropertySource(String name, EncodedResource resource) {
String staticPath = "config/static.yml";
Properties properties = new Properties();
// 加载默认配置项
LOGGER.info("load root yml");
loadProperties(properties, resource.getResource());
// 加载静态配置项
LOGGER.info("load static yml");
loadProperties(properties, new FileSystemResource(staticPath));
// 特殊处理配置项
operate(properties);
return name != null
? new PropertiesPropertySource(name, properties)
: new PropertiesPropertySource(resource.getResource().getFilename(), properties);
}
private void loadProperties(Properties properties, Resource resources) {
YamlPropertiesFactoryBean bean = new YamlPropertiesFactoryBean();
bean.setResources(resources);
Properties extendProperties = bean.getObject();
if (null != extendProperties) {
properties.putAll(extendProperties);
}
}
private void operate(Properties properties) {
try {
// 解密指定配置项, 这个解密工具是我自己写的, 此处可替换为你自己的加解密方法
properties.setProperty("spring.datasource.password", Common.decryptX16(properties.getProperty("spring.datasource.password")));
}
catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException("...");
}
}
}
可以看到,在读取默认配置文件和static.yml并进行合并后,对指定的配置项进行了解密处理
然后在SpringBoot启动类加上关键注解:
@PropertySource(value = "classpath:application.yml", factory = ProjectPropertiesConfigurer.class)
意思就是,项目的配置文件还是依赖classpath下的application.yml,但是使用自定义的解析器。
特别注意一下,如果在这个解析器里使用了日志打印的话,日志配置项就不能配在外部配置文件里了,必须得写到classpath的配置文件里,这个目前我也没找到什么绕开的方法,算了,权当日志配置写死了。
以上就可以在不引入其他依赖关系的情况下简单完成配置项的预处理,根据实际情况还可以进行配置项的额外注入/删除/修改等等操作,反正就是十分的自由。