掌握了生命周期好处是什么?以beanPostProcessor为例,昨天在项目中遇到的一个实际的情况。
背景是 公司有一个线上数据源加密包, 这个包是在原开源包基础上修改了源码把明文的password设置了密文, 随着时间推移这个包没人维护,配置产生了各种问题, 很多项目时间浪费在了配置这个数据源上面。 我在搭建一个新项目就遇到了这样的问题。
问题是我不想使用这个陈旧的被修改了7源码的数据源,那么面临的问题是:
开源数据源包仅支持明文密码的配置, 我得需求是配置文件中的密码为密文, 在dataSource的bean加载之后动态的将配置文件密文解密为明文, 并且setPassword到DataSource。
这样提出一个问题, 如何在dataSource 的 bean 初始化(将配置文件中的url,password等加载到bean中)后, 在dataSource被调用前, 获取到bean的password字段 ,解密, 重新set进去?
如果了解spring生命周期的同学应该很熟悉spring的BeanPostProcessor接口, 实现了该接口的类中有个方法:
@Override public Object postProcessAfterInitialization(Object bean, String name) throws BeansException { return bean; }
在spring容器初始化过程中, 会在bean被初始化后统一循环调用实现BeanPostProcessor接口并配置到IOC容器的bean 的 该方法。
那么在方法体获取DataSource的password , 解密, 设置明文密码就能达到开始时候的需求了。
完整代码:
public class DataSourcePasswordEncryptPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String name) throws BeansException { // TODO Auto-generated method stub if(bean instanceof ProxoolDataSource){ ProxoolDataSource ds = (ProxoolDataSource)bean; String password = ds.getPassword(); PBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); encryptor.setPassword("xxxxxxx"); //明文密码 String encPassword = encryptor.decrypt(password); ds.setPassword(encPassword); } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException { // TODO Auto-generated method stub return bean; } }