• home > java > spring >

    java项目动态配置常量和peiconfig.properties配置使用详解

    Author:zhoulujun Date:

    Java工程中配置信息一般都写在 properties文件中,下面这篇文章是对java基础配置的一点学习心得整理后汇总分享,以便脑袋短路时查阅。prope

     Java工程中配置信息一般都写在.properties文件中,下面这篇文章是对java基础配置的一点学习心得整理后汇总分享,以便脑袋短路时查阅。

    properties文件解释:


    .properties是一种主要在Java相关技术中用来存储应用程序的可配置参数的文件的文件扩展名。它们也可以存储用于国际化和本地化的字符串,这种文件被称为属性资源包(Property Resource Bundles)。

    每个参数被存储为一对字符串:一个存储名称参数(被称为“键”),另一个存储值。


    如何配置Properties文件?


    其实Java的Properties类可以读取多种文件,比如txt格式,xml格式,不过,这里只推.properties 文件格式:

    对于每一行可能有这么几种格式,包括键=值,键 = 值,键:值,以及键 值。

    .properties文件可以使用井号(#)或叹号(!)作为一行中第一个非空白字符来表示它后面的所有文本都是一个注释。反斜杠(\)用于转义字符。

    #请求地址

    ROOT_URL_SIT=https://www.zhoulujun.cn

    #ROOT_URL=https://app.sf-financial.com

    ROOT_URL=https://sit.sf-financial.com:7443

    #android apk 下载地址

    aboutUrl=https://www.zhoulujun.cn/about.php


    properties该放到哪里?

    在本地类库中,我经常使用当前目录来放置.properties文件,这时调用方只要引用我的jar,并且将我的.properties放在他的classpath里面即可,比如:

    p.load(new FileInputStream("config.properties"));

    但是到了Web项目时,情况大不相同。在Tomcat下,classpath里只含apache-tomcat-8.0.14\bin目录下有限的几个jar,根本没有目录,更不用提当前目录了

    Using CATALINA_BASE:   "\system\tomcat\Tomcat_8_0_14_InteljSearch"
    Using CATALINA_HOME:   "\apache-tomcat-8.0.14"
    Using CATALINA_TMPDIR: "\apache-tomcat-8.0.14\temp"
    Using JRE_HOME:        "\Java\jdk1.7.0_45"
    Using CLASSPATH:       "\apache-tomcat-8.0.14\bin\bootstrap.jar;\apache-tomcat-8.0.14\bin\tomcat-juli.jar"

    一般而言,有三种方案:

    A:通过 ClassLoader#getResourceAsStream() 来加载:

    p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("HanLP.properties"));

    此时HanLP.properties可以放在下列目录:

    Webapp/WEB-INF/lib

    Webapp/WEB-INF/classes

    Appserver/lib

    JRE/lib

    特别的,如果你正处于开发状态,可以简单地将HanLP.properties扔到src目录里或者resource目录里。提醒,如果放到src或者resource目录里,那么每次deploy都会覆写classes目录下的配置文件,并且你无法使用Properties#store()来保存配置文件。

    Screen Shot 2017-09-15 at 17.35.41.png

    B:放到 web 目录下,通过ServletContext#getResourceAsStream() 读取

    Properties properties = new Properties();
    properties.load(getServletContext().getResourceAsStream("/WEB-INF/filename.properties"));

    C:用绝对路径,通过普通的 java.io 方式读取

    Properties properties = new Properties();
    properties.load(new FileInputStream("/absolute/path/to/filename.properties");

    不过这种方式的可移植性并不好,并不推荐。


     JAVA操作properties配置文件

    Java.util.Properties,此类是Java中比较重要的类,主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置文件中很多变量是经常改变的,这样做也是为了方便用户,让用户能够脱离程序本身去修改相关的变量设置。

    此类是线程安全的:多个线程可以共享单个 Properties 对象而无需进行外部同步。

    它提供了几个主要的方法:

    •  getProperty ( String key):用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。

    •  load ( InputStream inStream):从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。

    • setProperty ( String key, String value) :调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。

    • store ( OutputStream out, String comments):以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。

    •  clear ():清除所有装载的 键 - 值对。该方法在基类中提供。


    因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。

    如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。

    类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。

    Java读取Properties文件的方法,还是参考此文章: JAVA操作properties配置文件——总结(Locale&ResourceBundle& PropertyResourceBundle)

    public class Demo{
      public static void main(String[] args){
        Properties props = new Properties();
        
        InputStream in = Demo.class.getResourceAsStream("../config.properties");
    
        // 或使用文件输入流(不推荐),假设当前工作目录为bin
        //InputStream in = new FileInputStream("./config.properties");
    
        props.load(in);
        in.close();
        
        // 读取特定属性
        String key = "ip";
        String ip = props.getProperty(key);
    
        // 遍历所有属性,方式一
        Set keys = props.keySet();
        for (Interator it = keys.iterator(); it.hasNext();){
            String k = it.next();
            System.out.println(k + ":" + props.getProperty(k));
        }
         // 遍历所有属性,方式二
        Enumeration en = props.propertyNames();
        while (en.hasMoreElements()){
            String k = en.nextElement();
            System.out.println(k + ":" + props.getProperty(k));
        }
      }
    }

    1. 通过 Demo.class.getResourceAsStream("../config.properties"); 读取配置文件,配置文件的相对路径以类文件所在目录作为当前目录。


       2. 通过 new FileInputStream("./config.properties"); 读取配置文件,配置文件的相对路径以工作目录(可以通过 System.getProperty("user.dir") 获取工作目录)作为当前目录。

    注意:上述两种方式获取的配置文件均没有被缓存。每次都要重新加载配置文件。


     Java动态给类中配置常量赋值的三种方法


    当我们需要给Configuration类中的CONFIG常量第一次使用时动态指定一个值时,而此时我们又不想去修改源代码,那我们有三种方法去实现这种需求。


    第一种:使用一个static静态代码块来指定,然后在静态代码块中,我们去动态读取外部的一个Properties文件的值。(最推荐)

    import java.util.Properties;  
      
      
    /** 
     * 第一种实现方法 
     * @author William 
     * 
     */  
    public class Configuration {  
      
        public static final String CONFIG;//常量声明时不马上初始化  
          
        static {  
            Properties properties = new Properties();  
            //把一个properties读进来  
            CONFIG = "properties.getConfig";//通过properties的配置项config来初始化我们的常量config  
        }  
    }

    第二种:我们可以配置Java的运行时配置,来指定一个-Dname=value的参数,这样也可以在类内部动态的接受到运行时指定的一个参数。

    /** 
     * 第二种实现方法 
     * @author William 
     * 
     */  
    public class Configuration {  
      
        public static final String CONFIG;//常量声明时不马上初始化  
          
        static {  
            CONFIG = System.getProperty("CONFIG");//通过系统的-D配置参数name=value形式来拿到这个配置值  
            //如果是eclipse,右键->RUN AS->Run Configurations->arguments->VMarguments 里输入(-DCONFIG=我们想要加入的配置)  
        }  
          
        public static void main(String[] args) {  
            System.out.println(Configuration.CONFIG);  
        }  
    }

    第三种:我们还可以读的到系统配置的PATH或者CLASSPATH里面的值,同理,我们也可以配置自己的环境变量,然后在程序中一样也能读到这些配置的环境变量。

    /** 
     * 第三种实现方法 
     * @author William 
     * 
     */  
    public class Configuration {  
      
        public static final String CONFIG;//常量声明时不马上初始化  
          
        static {  
            CONFIG = System.getenv("PATH");//通过System.getenv()方法可以拿到系统环境变量,但我自己指定的环境变量没有取得成功,如果有知道原因的给我留言哈谢谢  
              
        }  
          
        public static void main(String[] args) {  
            System.out.println(Configuration.CONFIG);  
        }  
    }



    参考文章:

    http://www.hankcs.com/program/java/placement-and-read-the-properties-file-jspservlet-in-web-application.html

     JAVA操作properties配置文件——总结(Locale&ResourceBundle& PropertyResourceBundle)

    http://www.cnblogs.com/fsjohnhuang/p/3995386.html

    http://www.cnblogs.com/panjun-Donet/archive/2009/07/17/1525597.html








    转载本站文章《java项目动态配置常量和peiconfig.properties配置使用详解》,
    请注明出处:https://www.zhoulujun.cn/html/java/spring/2017_0915_8051.html