Spring Boot如何在创建数据源前解密application.properties中的加密数据库密码
Spring Boot 数据源创建前解密加密数据库密码的实现方案
下面是两种生产环境常用的实现方式,你可以根据项目情况选择:
方案一:实现EnvironmentPostProcessor(推荐,全局生效无侵入)
这个方式会在Spring Boot加载完所有配置文件后、所有Bean(包括数据源)初始化前执行,完全不影响原有业务逻辑,兼容性最好。
- 第一步:自定义处理器类实现
EnvironmentPostProcessor接口,在方法中读取加密的密码,调用你已经实现的解密逻辑,替换原配置值
import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import java.util.HashMap; import java.util.Map; public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor { // 你自己实现的解密工具类 private final YourDecryptUtil decryptUtil = new YourDecryptUtil(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { // 读取配置里的加密密码 String encryptPwd = environment.getProperty("spring.datasource.password"); // 解密 String decryptPwd = decryptUtil.decrypt(encryptPwd); // 把解密后的密码放到配置源最前面,优先级最高会覆盖原来的加密值 Map<String, Object> overrideMap = new HashMap<>(); overrideMap.put("spring.datasource.password", decryptPwd); MapPropertySource overrideSource = new MapPropertySource("overrideDecryptConfig", overrideMap); environment.getPropertySources().addFirst(overrideSource); } }
- 第二步:注册自定义处理器,在项目
resources/META-INF/spring.factories文件中添加以下配置:
org.springframework.boot.env.EnvironmentPostProcessor=com.yourpackage.DecryptEnvironmentPostProcessor
把上面的包路径替换成你自己的处理器类所在的包即可。
方案二:手动自定义数据源Bean(灵活可控,适合简单项目)
如果你的项目不需要全局处理加密配置,只需要处理数据源密码,可以直接手动创建数据源,跳过自动配置:
- 第一步:排除数据源自动配置,在启动类注解上添加排除规则:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
- 第二步:自定义数据源Bean,在构造时完成密码解密
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.zaxxer.hikari.HikariDataSource; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String encryptPwd; @Value("${spring.datasource.driver-class-name}") private String driverClassName; // 你的解密工具类 private final YourDecryptUtil decryptUtil = new YourDecryptUtil(); @Bean public DataSource dataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(dbUrl); dataSource.setUsername(username); // 解密后设置密码 dataSource.setPassword(decryptUtil.decrypt(encryptPwd)); dataSource.setDriverClassName(driverClassName); // 其他数据源配置可以自行设置 return dataSource; } }
如果用的是Druid等其他数据源,替换对应的实现类即可。
注意事项
- 解密逻辑不要依赖其他Spring托管的Bean,避免出现加载顺序依赖问题导致初始化失败
- 建议加密配置统一加特殊前缀比如
ENC(加密后内容),处理时先判断是否有该前缀再解密,避免误处理普通明文配置 - 不要把解密密钥硬编码在代码里,建议放到环境变量或者启动参数中读取
内容的提问来源于stack exchange,提问作者VLN
相关产品推荐
相关产品推荐

