2021-01-21

EnvironmentPostProcessor怎么做单元测试?阿里P7解答

我们经常使用EnvironmentPostProcessor来自定义应用程序的环境变量,那么EnvironmentPostProcessor的单元测试怎么做呢?

简介

从Spring Boot 1.3开始,我们可以在应用程序上下文刷新之前使用EnvironmentPostProcessor来自定义应用程序的EnvironmentEnvironment表示当前应用程序运行的环境,它可以统一访问各种属性源中的属性,如属性文件、JVM系统属性、系统环境变量和Servlet上下文参数。使用EnvironmentPostProcessor可以在bean初始化之前对Environment进行修改。

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

使用示例

让我们设想一个需求,配置文件中的数据库密码是加密后的密文,如:

spring.datasource.password=js8sbAwkduzPTEWQrlDbTw==

在应用启动时,对密文进行解密后再进行数据库的连接。

针对这种需求,就可以通过EnvironmentPostProcessor对密文进行解密,重新放到Environment中。

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

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

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

单元测试

下面介绍本文的重点:怎么做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();  return environment; }}

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

附:加解密工具类代码

package one.more;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;public class AESUtil { private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; private static final String KEY_ALGORITHM = "AES"; public static String encrypt(String content, String password) {  try {   Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);   byte[] byteContent = content.getBytes("utf-8");   cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));   byte[] result = cipher.doFinal(byteContent);   return Base64.encodeBase64String(result);  } catch (Exception ex) {  }  return null; } public static String decrypt(String content, String password) {  try {   Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);   cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));   byte[] result = cipher.doFinal(Base64.decodeBase64(content));   return new String(result, "utf-8");  } catch (Exception ex) {  }  return null; } private static SecretKeySpec getSecretKey(final String password) {  KeyGenerator kg = null;  try {   kg = KeyGenerator.getInstance(KEY_ALGORITHM);   kg.init(128, new SecureRandom(password.getBytes()));   SecretKey secretKey = kg.generateKey();   return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);  } catch (NoSuchAlgorithmException ex) {  }  return null; }}

微信公众号:万猫学社

微信扫描二维码

关注后回复「电子书」

获取12本Java必读技术书籍











原文转载:http://www.shaoqun.com/a/512459.html

跨境电商:https://www.ikjzd.com/

tinypic:https://www.ikjzd.com/w/114

巨鲸:https://www.ikjzd.com/w/1986


我们经常使用EnvironmentPostProcessor来自定义应用程序的环境变量,那么EnvironmentPostProcessor的单元测试怎么做呢?简介从SpringBoot1.3开始,我们可以在应用程序上下文刷新之前使用EnvironmentPostProcessor来自定义应用程序的Environment。Environment表示当前应用程序运行的环境,它可以统一访问各种属性源中
海淘贝:海淘贝
c2c模式:c2c模式
2018美国黑色星期五销售额破60亿!对比阿里究竟谁更强?:2018美国黑色星期五销售额破60亿!对比阿里究竟谁更强?
刚刚!深圳机场跨境电商保税进口(1210)业务正式开通:刚刚!深圳机场跨境电商保税进口(1210)业务正式开通
中山悦来亲子王国具体位置?悦来亲子王国交通方便吗?:中山悦来亲子王国具体位置?悦来亲子王国交通方便吗?

No comments:

Post a Comment