zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    python中如何将两个list合并成一个list,不用for语句
    python print的用法
    Pandas Timestamp 和 python 中 datetime 的互相转换
    python eval, exec. compile
    python 用 __all__ 暴露接口
    python functiontools 模块
    Python 修饰符, 装饰符
    Python 字典(Dictionary) update()方法
    Python :random 随机数生成
    Pandas dataframe 标记删除重复记录
  • 原文地址:https://www.cnblogs.com/myitroad/p/7421703.html
Copyright © 2011-2022 走看看