使用Spring加载properties配置文件.md
背景
类似于datasource.properties之类的配置文件,最初通过Java的Properties类进行处理。这种方式有许多弊端,如每次都需要读取配置文件;若将Properties作为成员变量,则当配置文件缺失时,可能直接会导致程序运行失败。
使用Spring读取并装配配置文件,则可以避免上述麻烦。思路是将配置文件装配到一个具体类上,使用配置项的时候可通过该类的get()方法即可获取。
Java类
如配置类BspAuthConfig.java类如下:
package com.inspur.analysis.tool.user.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * Created by liutingna on 2017/8/22.
 */
@Component("bspAuthConfig")
public class BspAuthConfig {
    @Value("#{bspAuthConfigBean['analysis-tool-authentification']}")
    private String bspAuthUrl;
    public String getBspAuthUrl() {
        return bspAuthUrl;
    }
    public void setBspAuthUrl(String bspAuthUrl) {
        this.bspAuthUrl = bspAuthUrl;
    }
}
以上,@Component注解即表示装配生成的配置类BspAuthConfig的名字bspAuthConfig;
@Value注解,对应.properties配置文件中的配置项,如取属性配置Bean名称为bspAuthConfigBean的analysis-tool-authentification配置项;
属性配置bspAuthConfigBean通过Spring配置类进行配置,如下所示。
Spring配置
Spring配置有两个作用,一是读取.properties配置文件,并装配为名为bspAuthConfigBean的Bean;二是扫描自定义的配置类BspAuthConfig。
<!--BSP认证配置-->
<context:component-scan base-package="com.inspur.analysis.tool.user.config"/>
<bean id="bspAuthConfigBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
   <property name="locations">
      <array>
         <value>classpath:conf.properties</value>
      </array>
   </property>
</bean>
对应的一个.properties配置文件示例如下:
analysis-tool-authentification=http://localhost:8081/analysis-tool-authentification
应用
子需要配置类的地方,直接创建成员变量,然后使用get方法获取配置项。如:
private static BspAuthConfig bspAuthConfig=null;
static {
   bspAuthConfig= ContextUtils.getBean(BspAuthConfig.class, "bspAuthConfig");
}
这里使用了一个工具类ContextUtils,该类比较简单,即获取上下文中的Bean对象,如下:
package com.inspur.analysis.tool.common.utils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.loushang.framework.util.SpringContextHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * 上下文协助
 * @author xie_yh
 *
 */
public class ContextUtils {
   private static ApplicationContext defaultContext = null;
   /**
    * 获取context
    * @return
    */
   public static ApplicationContext getContext(){
      if(defaultContext != null){
         return defaultContext;
      }
      return SpringContextHolder.getApplicationContext();
   }
   /**
    * 获取bean
    * @param name
    * @return
    */
   public static Object getBean(String name){
      return getContext().getBean(name);
   }
   /**
    * 获取bean
    * @param clz
    * @return
    */
   public static <T> T getBean(Class<T> clz){
      return getContext().getBean(clz);
   }
   /**
    * 获取bean
    * @param clz
    * @param name
    * @return
    */
   public static <T> T getBean(Class<T> clz,String name){
      return getContext().getBean(name, clz);
   }
   /**
    * 获取值
    * @param name
    * @param keyname
    * @param defaultValue
    * @return
    */
   public static String getValue(String name,String keyname,String defaultValue){
      Object bean = getBean(name);
      try {
         return StringUtils.defaultIfBlank(BeanUtils.getProperty(bean, keyname),defaultValue);
      } catch (Exception e) {
      }
      return defaultValue;
   }
   /**
    * 初始化脚本
    * @param xmls
    */
   public void initContext(String[] xmls){
      //加载spirng配置文件
      defaultContext= new ClassPathXmlApplicationContext(xmls);
   }
}
注意
需要注意的是配置文件key的写法,上述示例中使用中括号:
@Value("#{bspAuthConfigBean['analysis-tool-authentification']}")
另外还可以使用点号 . 的方式,如:
@Value("#{cmspconfig.cmsp_ip}")
但是这是要求配置文件key不能以点号 . 或者中划线 - 等字符分割。
改进
上述配置,当properties配置文件缺少相应的配置项时,会造成注解失败。而按照需求,当缺少properties配置文件时,使用默认值替代,那么可以使用以下方式进行配置。
(注意:这里展示另一个例子,相关Java类与配置文件与上面并不一致)
- Java配置类
 配置类@Value注解中,使用美元符号($)读取默认项,且直接使用properties文件中的配置项即可,无需再使用xml中配置的bean的id。(即无需propertyConfigurer.file_storage_server_type或propertyConfigurer['file_storage_server_type'],直接使用file_storage_server_type即可。)
 当读取不到配置项时,使用org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer填充默认值,只需要在配置项后面加上冒号和默认值即可。如下默认值为空:
package com.inspur.analysis.tool.dispatcher.ontology.document.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("fileStorageConfig")
public class FileStorageConfig {
    @Value("${file_storage_server_type:}")
    private String fileStorageServerType;
    @Value("${file_storage_server_ip:}")
    private String fileStorageServerIp;
    @Value("${file_storage_server_port:}")
    private String fileStorageServerPort;
    @Value("${file_storage_server_username:}")
    private String fileStorageServerUsername;
    @Value("${file_storage_server_password:}")
    private String fileStorageServerPassword;
    @Value("${file_storage_server_path:}")
    private String fileStorageServerPath;
    public String getFileStorageServerType() {
        return fileStorageServerType;
    }
    public void setFileStorageServerType(String fileStorageServerType) {
        this.fileStorageServerType = fileStorageServerType;
    }
    public String getFileStorageServerIp() {
        return fileStorageServerIp;
    }
    public void setFileStorageServerIp(String fileStorageServerIp) {
        this.fileStorageServerIp = fileStorageServerIp;
    }
    public String getFileStorageServerPort() {
        return fileStorageServerPort;
    }
    public void setFileStorageServerPort(String fileStorageServerPort) {
        this.fileStorageServerPort = fileStorageServerPort;
    }
    public String getFileStorageServerUsername() {
        return fileStorageServerUsername;
    }
    public void setFileStorageServerUsername(String fileStorageServerUsername) {
        this.fileStorageServerUsername = fileStorageServerUsername;
    }
    public String getFileStorageServerPassword() {
        return fileStorageServerPassword;
    }
    public void setFileStorageServerPassword(String fileStorageServerPassword) {
        this.fileStorageServerPassword = fileStorageServerPassword;
    }
    public String getFileStorageServerPath() {
        return fileStorageServerPath;
    }
    public void setFileStorageServerPath(String fileStorageServerPath) {
        this.fileStorageServerPath = fileStorageServerPath;
    }
}
- xml配置文件
 该xml需要在Web项目启动时,在上下文参数中加载。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <!-- 注释资源扫描包路径 -->
    <context:component-scan base-package="com.inspur.analysis.tool.dispatcher.**.config"/>
    <bean id="fileStorageConfigBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <array>
                <value>classpath:datasource.properties</value>
            </array>
        </property>
    </bean>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="properties" ref="fileStorageConfigBean"/>
    </bean>
</beans>
改进2
参见参考资料4.
- Java配置
 默认值支持字符串、整型等多种类型:
@Value("#{fileDatasourceConfig['file_ds_server_type']?:1}")
private int serverType;
@Value("#{fileDatasourceConfig['file_ds_server_ip']?:''}")
private String serverIP;
@Value("#{fileDatasourceConfig['file_ds_server_port']?:21}")
private int serverPort;
@Value("#{fileDatasourceConfig['file_ds_server_username']?:''}")
private String username;
@Value("#{fileDatasourceConfig['file_ds_server_password']?:''}")
private String password;
@Value("#{fileDatasourceConfig['file_ds_server_path']?:''}")
private String structuredFilePath;
- xml配置
 使用util:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:beans="http://www.springframework.org/schema/beans"
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:task="http://www.springframework.org/schema/task"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context-3.1.xsd
                    http://www.springframework.org/schema/mvc
                    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                    http://www.springframework.org/schema/task
               http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    <!--文档数据源配置类-->
    <context:component-scan base-package="com.inspur.analysis.tool.datasource.**.config"/>
   <bean id="fileDatasourceConfig" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
     <property name="locations">
      <array>
         <value>classpath:datasource.properties</value>
      </array>
     </property>
   </bean>
   <bean id="fileDsRefConf" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
     <property name="properties" ref="fileDatasourceConfig"/>
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
   <!--以下加载方式对项目中datasource.xml配置加载数据源datasource.properties文件有些影响-->
   <!--<util:properties id="fileDatasourceConfig" location="classpath:datasource.properties"/>-->
</beans>
参考资料
【1】spring中@value注解需要注意
【2】给Spring的placeholder设置默认值
【3】spring报“Could not resolve placeholder”错误
【4】Spring @Value default value
使用Spring加载properties配置文件.md的更多相关文章
- Spring加载Properties配置文件的三种方式
		一.通过 context:property-placeholder 标签实现配置文件加载 1) 用法: 1.在spring.xml配置文件中添加标签 <context:property-plac ... 
- spring加载properties配置文件
		public static void main(String[] args){ String path="E:/workspace/bocMarketData/src/config/P ... 
- Spring加载properties文件的两种方式
		在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ... 
- Java加载Properties配置文件工具类
		Java加载Properties配置文件工具类 import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; ... 
- 加载Properties配置文件
		/** * 加载Properties配置文件 * * @author ZhangHaiNing * @param file 要读取的文件 * @return */ public static Prop ... 
- Spring加载properties文件的属性的值
		要使用配置文件的值首先在spring.xml配置加载properties文件 <context:property-placeholder location="classpath:ife ... 
- spring加载属性配置文件内容
		在spring中提供了一个专门加载文件的类PropertyPlaceholderConfigurer,通过这个类我们只需要给定需要加载文件的路径就可以 通过该类加载到项目,但是为了后面在程序中需要使用 ... 
- Spring加载xml配置文件的方式 ApplicationContext
		大家都知道Java读普通文件是通过Basic I/O 中的InputStream.OutStream.Reader.Writer 等实现的.在spring 框架中,它是怎样识别xml这个配置文件的呢? ... 
- Spring加载XML配置文件
		原创链接:http://www.cnblogs.com/yanqin/p/5282929.html(允许转载,但请注明原创链接) BeanFactory加载单个文件 当使用beanfactory去获取 ... 
随机推荐
- Webpack之“多页面开发”最佳实战
			前言:相信之前看过这篇文章,前端构建工具之“Webpack”的朋友,对于Webpack有了一定的了解.那么今天就跟大家分享下:如何利用webpack,来进行多页面项目实战开发. 一.项目初始化安装 1 ... 
- [转]angular的路由机制
			在谈路由机制前有必要先提一下现在比较流行的单页面应用,就是所谓的single page APP.为了实现无刷新的视图切换,我们通常会用ajax请求从后台取数据,然后套上HTML模板渲染在页面上,然而a ... 
- Visualforce入门第一篇_2017.3.1
			什么是Visualforce?? Visualforce是Forcce.com平台上的试图控制技术,结构与标记与HTML非常相似.Visualforce页面可以显示从数据库或者Web服务器得到的数 ... 
- MSSQL2008 常用sql语句
			一.基础 1.说明:创建数据库 Create DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ... 
- POJ3009(dfs)
			Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17672 Accepted: 7262 Desc ... 
- hibernate中mysql数据交互中文乱码问题
			来源于"http://www.cnblogs.com/jiafuwei/p/4423101.html"; 修改hibernate的配置文件hibernate.cfg.xml,在配置 ... 
- Swing编程---添加背景图片的方法
			总结:看下我的运行图片.这个图片很重要.很能说明问题.它的frame就是一个小图片.就是背景.么手贱把它放大. 在微软的操作系统上,你放多大,窗口就有多大,你看到背景就成了小图片,就会误以为不是背景. ... 
- git学习5  ecipse集成git(转载)
			原文地址:http://blog.csdn.net/hhhccckkk/article/details/10458159 有的eclipse已经自带了GIt了,就不用安装了 1: 进行安装Git,和安 ... 
- OpenCV 视频监控(Video Surveilance)的算法体系
			如前面说到的,OpenCV VS提供了6组算法的接口,分别是:前景检测.新目标检测.目标跟踪.轨迹生成.跟踪后处理.轨迹分析,除了轨迹生成用于轨迹数据的保存以外,其他5个部分都是标准的视频监控算法体系 ... 
- django的settings.py设置session
			############ # SESSIONS # ############ SESSION_CACHE_ALIAS = 'default' # Cache to store session data ... 
