在属性文件中将数据库的用户名和密码等敏感信息以明文的方式写在文件中,这是非常不安全的,所以我们就需要将属性文件中的部分信息进行加密处理以提高安全性。
下面介绍如何运用spring中的PropertyPlaceholderConfigurer
类对加密的属性值进行解密处理。
PropertyPlaceholderConfigurer
类本身对加密的数据不做任何处理的,所以我们需要自定义类继承PropertyPlaceholderConfigurer
,并且重写父类中的方法。通过spring源码我们可以看到PropertyPlaceholderConfigurer
类uml图如下所示。
PropertyResourceConfigurer
类实现BeanFactoryPostProcessor
接口是一个后置处理器类,找到postProcessBeanFactory
方法发现跟获取属性值有关的方法为convertProperties
方法,源码如下所示:
protected void convertProperties(Properties props) {
for(Enumeration propertyNames = props.propertyNames(); propertyNames.hasMoreElements();){
String propertyName = (String) propertyNames.nextElement();
String propertyValue = props.getProperty(propertyName);
String convertedValue = convertProperty(propertyName, propertyValue);
if(!ObjectUtils.nullSafeEquals(propertyValue, convertedValue))
props.setProperty(propertyName, convertedValue);
}
}
protected String convertProperty(String propertyName,String propertyValue) {
return convertPropertyValue(propertyValue);
}
protected String convertPropertyValue(String originalValue) {
return originalValue;
}
看到这里我们就可以清楚的知道spring是通过该类中的 convertProperty
方法返回对应属性名处理后的属性值的,convertProperty
方法中调用了convertPropertyValue
方法用于返回属性值。
所以如果我们要对属性文件中的所有属性值进行解密处理,就只需重写convertPropertyValue
方法, 如果针对指定的属性名做解密处理,重写convertProperty
方法就可以了。子类代码如下所示:
//指定的属性名解密
public class ConvertPwdPropertyConfigurer extends PropertyPlaceholderConfigurer{
@Override
protected String convertProperty(String propertyName, String propertyValue) {
System.out.println("=================="+propertyName+":"+propertyValue);
if("userName".equals(propertyName)){
return DesUtils.getDecryptString(propertyValue);//调用解密方法
}
if("password".equals(propertyName)){
return DesUtils.getDecryptString(propertyValue);//调用解密方法
}
return propertyValue;
}
}
然后将上面完成的类替换配置文件中的PropertyPlaceholderConfigurer
:
<bean id="propertyConfigurer" class="com.mandi.common.ConvertPwdPropertyConfigurer ">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${userName}"></property>
<property name="password" value="${password}"></property>
······