java

spring启动时替换密码

2019-04-16  本文已影响0人  小明17

项目中用到了两种加载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);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读