简介从SpringBoot1.3开始,我们可以在应用上下文刷新之前,使用EnvironmentPostProcessor自定义应用的Environment。Environment表示当前应用程序运行的环境,可以统一访问各种属性源中的属性,如属性文件、JVM系统属性、系统环境变量、Servlet上下文参数等。EnvironmentPostProcessor可用于在bean初始化之前修改环境。示例让我们想象一个需求。配置文件中的数据库密码为加密密文,如:spring.datasource.password=js8sbAwkduzPTEWQrlDbTw==应用启动时,先解密密文再连接数据库。针对这个需求,可以通过EnvironmentPostProcessor对密文进行解密,放回Environment中。1.实际环境后处理器包一.更多;导入org.springframework.boot.SpringApplication;导入org.springframework.boot.env.EnvironmentPostProcessor;导入org.springframework.core.env.ConfigurableEnvironment;导入org.springframework.core.env.PropertiesPropertySource;importjava.util.Properties;publicclassDecodeEnvironmentPostProcessorimplementsEnvironmentPostProcessor{publicstaticfinalStringSPRING_DATASOURCE_PASSWORD="spring.datasource.password";publicstaticfinalStringAES_SECRET="OneMore";@OverridepublicvoidpostProcessEnvironment(ConfigurableEnvironmentenvironment,SpringApplicationapplication){Stringpassword=environment.getProperty(SPRING_DATASOURCE_PASSWORD);属性properties=newProperties();properties.setProperty(SPRING_DATASOURCE_PASSWORD,AESUtil.decrypt(密码,AES_SECRET));PropertiesPropertySourcepropertiesPropertySource=新PpropertiesPropertySource(SPRING_DATASOURCE_PASSWORD,属性);environment.getPropertySources().addFirst(propertiesPropertySource);}}如果希望EnvironmentPostProcessor按照特定的顺序被调用,可以实现Ordered接口,或者使用@Order注解2.注册实现类在SpringBoot启动过程中要调用这个实现类,我们还需要在META-INF/Spring.factories中注册这个实现类:org.springframework.boot.env.EnvironmentPostProcessor=one.more.DecodeEnvironmentPostProcessor单元测试下面介绍本文的重点:如何对EnvironmentPostProcessor实现类进行单元测试,废话少说,直接上传代码:packageone.more;importorg.junit.Assert;importorg.junit。测试;导入org.springframework。boot.SpringApplication;导入org.springframework.boot.WebApplicationType;导入org.springframework.boot.builder.SpringApplicationBuilder;导入org.springframework.boot.env.EnvironmentPostProcessor;导入org.springframework.context.ConfigurableApplicationContext;导入orgwork.springreframe.env.ConfigurableEnvironment;导入org.springframework.core.env.PropertiesPropertySource;导入java.util.Properties;公共类DecodeEnvironmentPostProcessorTest{@TestpublicvoidtestPostProcessEnvironment(){DecodeEnvironmentPostProcessor处理器=newDecodeEncvironment=newDecodeEncvironment;多一个";Propertiesproperties=newProperties();properties.setProperty(DecodeEnvironmentPostProcessor.SPRING_DATASOURCE_PASSWORD,AESUtil.encrypt(password,DecodeEnvironmentPostProcessor.AES_SECRET));ConfigurableEnvironmentenvironmentpro=getEnvironment.Asspert,Assperts(processor)environment.getProperty(DecodeEnvironmentPostProcessor.SPRING_DATASOURCE_PASSWORD));}/***得到一个EnvironmentPostProcessor处理过的Environment**@paramprocessorEnvironmentPostProcessor实现类的一个实例*@parampropertiespresetpropertiesreadyforunittesting*@returnprocessedEnvironment*/privateConfigurableEnvironmentgetEnvironment(EnvironmentPostProcessorprocessor,Propertiesproperties){//创建一个SpringApplicationSpringApplicationspringApplication=newSpringApplicationBuilder().sources(DecodeEnvironmentPostProcessor.class).web(WebApplicationType.NONE).build();//获取应用上下文ConfigurableApplicationContextcontext=springApplication.run();//获取环境ConfigurableEnvironmentenvironment=context.getEnvironment();//添加单元测试的属性environment.getPropertySources().addFirst(newPropertiesPropertySource("test",properties));processor.postProcessEnvironment(环境,springApplication);上下文.close();回归环境;}}附:加解密工具类代码包one.more;importorg.apache.commons.codec.binary.Base64;importjavax.crypto.Cipher;importjavax.crypto.KeyGenerator;importjavax.crypto.SecretKey;importjavax.crypto.spec.SecretKeySpec;导入java.security.NoSuchAlgorithmException;导入java.security.SecureRandom;publicclassAESUtil{privatestaticfinalStringDEFAULT_CIPHER_ALGORITHM="AES/ECB/PKCS5Padding";私人静态最终字符串KEY_ALGORITHM=“AES”;publicstaticStringencrypt(Stringcontent,Stringpassword){try{Ciphercipher=Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);byte[]byteContent=content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE,getSecretKey(密码));byte[]result=cipher.doFinal(byteContent);返回Base64.encodeBase64String(结果);}catch(Exceptionex){}返回null;}publicstaticStringdecrypt(Stringcontent,Stringpassword){try{Ciphercipher=Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE,getSecretKey(密码));byte[]result=cipher.doFinal(Base64.decodeBase64(content));返回新字符串(结果,“utf-8”);}catch(Exceptionex){}返回null;}privatestaticSecretKeySpecgetSecretKey(最终字符串密码){密钥生成器kg=null;尝试{kg=KeyGenerator.getInstance(KEY_ALGORITHM);kg.init(128,newSecureRandom(password.getBytes()));SecretKeysecretKey=kg.generateKey();返回新的SecretKeySpec(secretKey.getEncoded(),KEY_ALGORITHM);}catch(NoSuchAlgorithmExceptionex){}返回null;}}
