spring.datasource.password=js8sbAwkduzPTEWQrlDbTw==
在应用启动时,对密文进行解密后再进行数据库的连接。
针对这种需求,就可以通过EnvironmentPostProcessor对密文进行解密,重新放到Environment中。
1.实现EnvironmentPostProcessor
package one.more;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import java.util.Properties;
public class DecodeEnvironmentPostProcessor implements EnvironmentPostProcessor {
public static final String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password";
public static final String AES_SECRET = "OneMore";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String password = environment.getProperty(SPRING_DATASOURCE_PASSWORD);
Properties properties = new Properties();
properties.setProperty(SPRING_DATASOURCE_PASSWORD, AESUtil.decrypt(password, AES_SECRET));
PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource(SPRING_DATASOURCE_PASSWORD,
properties);
environment.getPropertySources().addFirst(propertiesPropertySource);
}
}
如果你希望EnvironmentPostProcessor按照特定的顺序被调用,可以实现Ordered接口,或者使用@Order注解。
2.注册实现类
想要在Spring Boot启动过程中调用这个实现类,我们还需要在META-INF/ Spring .factories中注册这个实现类:
org.springframework.boot.env.EnvironmentPostProcessor=
one.more.DecodeEnvironmentPostProcessor
单元测试
下面介绍本文的重点:怎么做EnvironmentPostProcessor实现类的单元测试,话不多说,直接上代码:
package one.more;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import java.util.Properties;
public class DecodeEnvironmentPostProcessorTest {
@Test
public void testPostProcessEnvironment() {
DecodeEnvironmentPostProcessor processor = new DecodeEnvironmentPostProcessor();
String password = "one-more";
Properties properties = new Properties();
properties.setProperty(DecodeEnvironmentPostProcessor.SPRING_DATASOURCE_PASSWORD,
AESUtil.encrypt(password, DecodeEnvironmentPostProcessor.AES_SECRET));
ConfigurableEnvironment environment = getEnvironment(processor, properties);
Assert.assertEquals(password,
environment.getProperty(DecodeEnvironmentPostProcessor.SPRING_DATASOURCE_PASSWORD));
}
/**
-
获取一个经过EnvironmentPostProcessor处理过的Environment
-
@param processor EnvironmentPostProcessor实现类的实例
-
@param properties 预置准备做单元测试的属性
-
@return 处理过的Environment
*/
private ConfigurableEnvironment getEnvironment(EnvironmentPostProcessor processor, Properties properties) {
// 创建一个SpringApplication
SpringApplication springApplication = new SpringApplicationBuilder()
.sources(DecodeEnvironmentPostProcessor.class)
.web(WebApplicationType.NONE).build();
// 获取应用上下文
ConfigurableApplicationContext context = springApplication.run();
// 获取Environment
ConfigurableEnvironment environment = context.getEnvironment();
//添加准备做单元测试的属性
environment.getPropertySources()
.addFirst(new PropertiesPropertySource("test", properties));
processor.postProcessEnvironment(environment, springApplication);
context.close();