在springboot启动的时候会初始化ApplicationListener相关的监听类
加密的框架在spring.factories中定义
通过无参构造方法来实例化EnableEncryptablePropertiesBeanFactoryPostProcessor(容器还没托管,只是赋值给了SpringApplication的listeners变量)
进入springboot 的run方法,会在org.springframework.boot.SpringApplication#refreshContext中调用
@EnableEncryptableProperties在引入了EnableEncryptablePropertiesConfiguration的配置类
在org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
中,由于enableEncryptablePropertySourcesPostProcessor实现了BeanFactoryPostProcessor和Ordered接口,所以会在这里进行实例化加载,这个时候enableEncryptablePropertySourcesPostProcessor对象由容器来托管。
调用postProcessBeanFactory方法,
1.构造Encryptable自己的属性解析器
2.获取容器所有的属性源,可以看到ApolloBootstrapPropertySources也在这里面
3.对propertySource进行包装,换成Encryptable自己的类方便操作
把ApolloBootstrapPropertySources包装成了EncryptableEnumerablePropertySourceWrapper类
执行完convertPropertySources后,属性源propSources全替换成了EncryptableEnumerablePropertySourceWrapper包装类,
delegate为源属性源,resolver为懒加载的属性解析器
在容器加载类的时候,比如有的service用到了redis.就会把redisTemplate给进行加载
redisTemplate需要注入redis相关的属性类。
绑定redis相关属性,可以看到这里的source已经是替换过的包装类了EncryptableEnumerablePropertySourceWrapper
给属性赋值的过程,就是循环的去包装类的属性源中找对应的name。例如循环找spring.redis.host。
最后就找到了包装类EncryptableEnumerablePropertySourceWrapper
如果在属性源ApolloBootstrapPropertySources 中找到了spring.redis.host 这个配置,如果是String类型的,需要判断是否需要解码
如果是以ENC(开头,以)结尾的字符串就需要解码,然后进行返回