有时为了数据安全,需要对相关配置文件中某些属性进行加密,例如数据库连接、账号密码,及其他相关加密秘钥等
EnvironmentPostProcessor
EnvironmentPostProcessor在ConfigurableEnvironment被完全初始化之前修改环境的配置
下面使用EnvironmentPostProcessor进行相关配置项解密
1.创建 MyEnvironmentPostProcessor实现EnvironmentPostProcessor接口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import java.util.HashMap;
import java.util.Map;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : propertySources) {
// 获取YML、Properties类型属性源文件
if (propertySource instanceof OriginTrackedMapPropertySource) {
Map<String,Object> propertySourceMap = new HashMap<>();
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) propertySource;
for (String propertyName : source.getPropertyNames()) {
Object sourceValue = source.getProperty(propertyName);
// 查找带有指定前缀的配置项
if (sourceValue instanceof String && sourceValue.toString().startsWith("{'abcd'}")) {
String value = (String) sourceValue;
// 模拟解密
value = value.replace("{'abcd'}","");
propertySourceMap.put(propertyName,value);
}
}
// addFirst,添加到最高优先级
if (!propertySourceMap.isEmpty()) {
propertySources.addFirst(new OriginTrackedMapPropertySource(propertySource.getName(),propertySourceMap));
}
}
}
}
// 优先级最高
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
2.注册EnvironmentPostProcessor
在src/main/resources/META-INF/spring.factories文件中添加以下行:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.cpu.mem.cpumemory.beans.MyEnvironmentPostProcessor
注意事项
EnvironmentPostProcessor在ApplicationEnvironmentPreparedEvent事件之后调用,这意味着在此阶段Environment已经包含了从application.properties或application.yml文件中读取的属性,以及其他来源的配置。EnvironmentPostProcessor的顺序很重要,Spring Boot允许注册多个EnvironmentPostProcessor,它们将按照在spring.factories文件中声明的顺序执行。因此,如果你想覆盖其他处理器的行为,需要考虑Ordered接口的实现来控制执行顺序。