版本
<!-- 配置文件加密 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.14</version>
</dependency>
背景
在写一些组件中,难免会遇到需要使用用户自定义的类的场景,解决方案有很多种。
- 非spring下,可以使用spi的思想
- spring下,可以自定义注解或一个接口供用户使用,并在容器启动时,通过各种后置处理器从容器中获取到bean,然后就可以决定是执行用户的bean还是自身的bean
- 配置@AutoConfigureAfter并且和@ConditionalOnMissingBean配合使用。@AutoConfigureAfter这个需要用户去处理,将用户自己的configuration配置在框架自身的configuration之前执行。@ConditionalOnMissingBean需要组件处理
- spring下,jasypt的处理模式
- ...
jasypt的处理方式
先看代码com.ulisesbocchio.jasyptspringboot.configuration.EncryptablePropertyResolverConfiguration,下面这段代码给用户开了个口子,表示用户自定义的bean的名称,冒号之后是默认值,即用户不自定义则使用默认值jasyptStringEncryptor
private static final String ENCRYPTOR_BEAN_PLACEHOLDER = "${jasypt.encryptor.bean:jasyptStringEncryptor}";
下面在看一段bean的配置代码
@Bean(name = ENCRYPTOR_BEAN_NAME)
public StringEncryptor stringEncryptor(EnvCopy envCopy, BeanFactory bf) {
String customEncryptorBeanName = "${jasypt.encryptor.bean}"; //这个参数的值
return new DefaultLazyEncryptor(envCopy.get(), customEncryptorBeanName, bf);
}
public class DefaultLazyEncryptor implements StringEncryptor {
//用来暂存用户的bean或默认的bean
Singleton<StringEncryptor> singleton;
public DefaultLazyEncryptor(Environment e, String customEncryptorBeanName, BeanFactory bf) {
singleton = new Singleton<>(() ->
Optional.of(customEncryptorBeanName)
.filter(bf::containsBean)
//通过用户自定义的beanName从spring中获取这个bean
.map(name -> (StringEncryptor) bf.getBean(name))
//如果存在,则使用用户的bean
.map(bean -> {
log.info("Found Custom Encryptor Bean {} with name: {}", bean, customEncryptorBeanName);
return bean;
})
//如果不存在,则默认创建一个
.orElseGet(() -> {
log.info("String Encryptor custom Bean not found with name '{}'. Initializing Default String Encryptor", customEncryptorBeanName);
return createDefault(e);
}));
}
}