项目中用到了两种加载properties文件的方式:
1.maven profile中配置,使用maven-resources-plugin替换占位符,然后保存到一个新的properties中:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resource</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<outputDirectory>src/main/webapp/WEB-INF/config</outputDirectory>
<resources>
<resource>
<directory>filters/config</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
2.使用spring的PropertyPlaceholderConfigure类:PropertyPlaceholderConfigurer是bean工厂后置类处理器(BeanFactoryPostProcessor)的一个实现,作用是将beanFactory定义的内容放到一个以.properties后缀的文件中,然后会将xml文件中的占位符${key}替换成指定properties中的值。
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:runtime.properties
</value>
</property>
</bean>
那要怎么在spring启动时替换密码呢?
对于第一种方式,因为启动时property已经替换过一次了,所以只能在具体使用到密码的地方做处理(例如数据库连接池的类中):
下面给出c3p0和Druid两种连接池的替换过程:
1.c3p0:
<bean id="SourceProperties" class="xxx.aws.secretManager.ReplaceFactoryBeanForC3p0">
<property name="properties">
<props>
<prop key="user">user</prop>
<prop key="password">pwd</prop>
</props>
</property>
</bean>
<bean id="SourceData"
class="xxx.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>com.microsoft.sqlserver.jdbc.SQLServerDriver</value>
</property>
<property name="jdbcUrl">
<value>jdbc:sqlserver://${url}:1433;database=xxx</value>
</property>
<property name="properties" ref="SourceProperties"/>
<!--<property name="user">-->
<!--<value>${db_username}</value>-->
<!--</property>-->
<!--<property name="password">-->
<!--<value>${db_password}</value>-->
<!--</property>-->
<property name="minPoolSize">
<value>3</value>
</property>
<property name="maxPoolSize">
<value>100</value>
</property>
<property name="initialPoolSize">
<value>3</value>
</property>
<property name="acquireIncrement">
<value>3</value>
</property>
<property name="idleConnectionTestPeriod">
<value>600</value>
</property>
<property name="maxIdleTime">
<value>1800</value>
</property>
</bean>
public class RepleceFactoryBeanForC3p0 implements FactoryBean<Object>{
private static final Logger logger = Logger.getLogger(SecretFactoryBeanForC3p0.class);
private Properties properties;
@Override
public Object getObject() throws Exception {
return getProperties();
}
@Override
public Class<?> getObjectType() {
return java.util.Properties.class;
}
@Override
public boolean isSingleton() {
return true;
}
public Properties getProperties(){
return properties;
}
public void setProperties(Properties inProperties){
this.properties = inProperties;
//要实现的账号密码替换逻辑:...
properties.put("user",xxx);
properties.put("password",xxx);
}
}
2.Druid: 把username和password放到connectionProperties中
<bean id="dbPasswordCallback" class="xxx.aws.secretManager.PawwsordCallbackForReplace" lazy-init="true">
//类的相关属性
</bean>
<bean id="DataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url">
<value>jdbc:sqlserver://${url}:1433;database=${xxx};sendStringParametersAsUnicode=false</value>
</property>
<!--<property name="username">-->
<!--<value>${username}</value>-->
<!--</property>-->
<!--<property name="password">-->
<!--<value>${password}</value>-->
<!--</property>-->
<property name="connectionProperties" value="username=;password=;druid.stat.slowSqlMillis=3000"/>
<property name="dbType" value="sqlserver" />
<property name="initialSize" value="3" />
<property name="minIdle" value="3" />
<property name="maxActive" value="100" />
<property name="maxWait" value="60000" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<property name="filters" value="mergeStat" />
<property name="passwordCallback" ref="dbPasswordCallback"/>
</bean>
public class DruidPasswordCallbackForReplace extends DruidPasswordCallback {
@Override
public void setProperties(Properties properties){
super.setProperties(properties);
//替换逻辑:...
properties.put("username",username);
properties.put("password",password);
}
}
网友评论