spring 配置 读取 properties文件 改为 读取数据库

一. 问题

       spring 配置通常读取  .properties 文件;小项目 配置少;分布式项目 配置文件比较多;不容易运维维护;可以改为读取数据库,在数据库维护;

二. Spring 的已有解决方案

    参考:https://www.codeproject.com/articles/28893/loading-application-properties-from-a-database

    

必须的jar包

  • spring.jar (Spring Core) [PropertiesPlaceholderConfigurer]
  • spring-modules.jar (Spring Modules) [CommonsConfigurationFactoryBean]
  • commons-configuration.jar (Commons Configuration) [DatabaseConfiguration]

需要数据库里 有一个表:

For this example, the database has a schema in it called TEST_SCHEMA and a table calledAPPLICATION_PROPERTIES_TABLE with two columns KEY and VALUE*.

TEST_SCHEMA.APPLICATION_PROPERTIES_TABLE

 

 

Spring Configuration

<!-- Required to connect to datasource -->
<bean name="PropertyPlaceholderConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     <property name="properties" ref="CommonsConfigurationFactoryBean"/>
</bean>
   
<bean name="CommonsConfigurationFactoryBean"
    class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
       <constructor-arg ref="DatabaseConfiguration"/>
</bean>
   
<bean name="DatabaseConfiguration"
         class="org.apache.commons.configuration.DatabaseConfiguration">
        <constructor-arg type="javax.sql.DataSource" ref="someDataSource"/>
        <constructor-arg index="1" value="TEST_SCHEMA.APPLICATION_PROPERTIES_TABLE"/>
        <constructor-arg index="2" value="KEY"/>
        <constructor-arg index="3" value="VALUE"/>
</bean>

<!-- Included to elaborate functionality -->

<bean name="PropertiesPrinter " class="example.PropertiesPrinter"
     initMethod="displayAllProperties">
    <property name="fileLocation" value="${file.location}"/>
    <property name="petDogsName" value="${pet.dogs.name}"/>
    <property name="keyOne" value="${key.one}"/>
</bean>
<!-- 
 PropertiesPrinter 为测试 类
-->

 三 .自己的方案:

      以上方法是通过commons-configuration  来实现,这种每次读取和变动都会访问数据库,在我们的实际应用中,应该是启动的时候读取一次就可以了,没有必要占着数据库连接,而且全局配置不允许应用修改的。

 

spring 配置:

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
	 <property name="properties"  ref="dataBaseProperties"/>  
    </bean>  
  
   <bean id="dataBaseProperties" class="com.test.common.utils.DatabaseProperties" >  
       <constructor-arg type="javax.sql.DataSource" ref="confDataSource"/>  
       <constructor-arg value="select key_p,value_p from tb_application_properties where type='common' or type='test' "/>  
   </bean>  
   <bean name="confDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
     <property name="driverClassName"  value="com.mysql.jdbc.Driver" />  
     <property name="url" value="jdbc:mysql://127.0.0.1:8066/test" />  
     <property name="username" value="test" />  
     <property name="password" value="test" />  
   </bean>  

 

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
 * DatabaseProperties
 * @version 1.0 2016年12月1日
 * @since 1.0
 */
public class DatabaseProperties implements InitializingBean, FactoryBean{

	
	private static final Logger log = LoggerFactory.getLogger(DatabaseProperties.class);  
    private static Properties props = new Properties();  
    private DataSource datasource;  //数据源  
    private String query;  //读取的sql  
  
    public static final String SHIRO_USER_URL = "shiroUserUrl";
    
    public static final String LOCAL_SERVICE = "localService";
    
    public DatabaseProperties(DataSource datasource, String query) {  
        this.datasource = datasource;  
        this.query = query;  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
        initProperties();  
    }  
  
    @Override  
    public Object getObject() throws Exception {  
        return props;  
    }  
  
    @Override  
    public Class getObjectType() {  
        return Properties.class;  
    }  
  
    @Override  
    public boolean isSingleton() {  
        return true;  
    }  
  
    private void initProperties() {  
        Connection connection = null;  
        try {  
            connection = datasource.getConnection();  
            PreparedStatement ps = connection.prepareStatement(query);  
            ResultSet rs = ps.executeQuery();  
            while (rs.next()) {  
                String key = rs.getString(1);  
                String value = rs.getString(2);  
                if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {  
                    log.debug("load property. Key=" + key + ",Value=" + value);  
                    props.setProperty(key, value);  
                }  
            }  
            rs.close();  
            ps.close();  
        } catch (Exception e) {  
            log.error(e.getMessage());  
        } finally {  
            if (connection != null) {  
                try {  
                    connection.close();  
                } catch (Exception e) {  
                    log.error(e.getMessage());  
                }  
            }  
        }  
    }  

}

 这样 更灵活,参数在数据库里自己配,项目中可以 调用 DatabaseProperties  Properties props 取得 配置的信息; 

 参考原文博客:

http://blog.csdn.net/maoxiang/article/details/4829553

 

猜你喜欢

转载自feiteyizu.iteye.com/blog/2342483
今日推荐