Java™ 教程(配置实用程序)

配置实用程序

本节介绍一些帮助应用程序访问其启动上下文的配置实用程序。

属性

Properties 是作为键/值对管理的配置值,在每对中,键和值都是字符串值,键标识并用于检索值,就像变量名用于检索变量的值一样。例如,能够下载文件的应用程序可能使用名为“ download.lastDirectory ”的属性来跟踪上次下载所使用的目录

要管理属性,请创建 java.util.Properties 的实例,此类提供以下方法:

Properties

有关流的介绍,请参阅基础I/O课程中的I/O流部分。

Properties 扩展了 java.util.Hashtable ,从 Hashtable 继承的一些方法支持以下操作:

Properties
Properties
Properties

安全考虑因素:对属性的访问必须经过当前安全管理器的批准,假定本节中的示例代码段位于独立应用程序中,默认情况下,它们没有安全管理器,applet中的相同代码可能无法运行,具体取决于运行它的浏览器,有关applet安全性限制的信息,请参阅Java Applets课程中Applets可以做什么和不能做什么。

System 类维护一个 Properties 对象,该对象定义当前工作环境的配置,有关这些属性的更多信息,请参阅系统属性,本节的其余部分介绍了如何使用属性来管理应用程序配置。

应用程序生命周期中的属性

下图说明了典型应用程序如何在执行过程中使用 Properties 对象管理其配置数据

Java™ 教程(配置实用程序)

  • Starting Up
    前三个框中给出的操作在应用程序启动时发生。首先,应用程序将默认属性从一个众所周知的位置加载到 Properties 对象中,通常,默认属性与应用程序的 .class 和其他资源文件一起存储在磁盘上的文件中。
    接下来,应用程序创建另一个Properties对象,并加载上次运行应用程序时保存的属性,许多应用程序基于每个用户存储属性,因此在此步骤中加载的属性通常位于此应用程序在用户主目录中维护的特定目录中的特定文件中,最后,应用程序使用默认和记住的属性来初始化自身。
    这里的关键是一致性,应用程序必须始终将属性加载并保存到同一位置,以便下次执行时可以找到它们。
  • Running
    在执行应用程序期间,用户可能会在“首选项”窗口中更改某些设置,并更新 Properties 对象以反映这些更改,如果要在将来的会话中记住用户更改,则必须保存它们。
  • Exiting
    退出时,应用程序将属性保存到其已知位置,以便在下次启动应用程序时再次加载。

设置属性对象

以下Java代码执行上一节中描述的前两个步骤:加载默认属性并加载记住的属性:

. . .
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();

// create application properties with default
Properties applicationProps = new Properties(defaultProps);

// now load properties 
// from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
. . .

首先,应用程序设置默认的 Properties 对象,如果未在其他位置显式设置值,则此对象包含要使用的属性集,然后, load 方法从名为 defaultProperties 的磁盘上的文件中读取默认值。

接下来,应用程序使用不同的构造函数来创建第二个 Properties 对象 applicationProps ,其默认值包含在 defaultProps 中,在检索属性时,默认值开始起作用,如果在 applicationProps 中找不到该属性,则搜索其默认列表。

最后,代码从名为 appProperties 的文件中将一组属性加载到 applicationProps 中,此文件中的属性是上次调用时从应用程序保存的属性,如下一节中所述。

保存属性

以下示例使用 Properties.store 从上一个示例中写出应用程序属性,每次都不需要保存默认属性,因为它们永远不会更改。

FileOutputStream out = new FileOutputStream("appProperties");
applicationProps.store(out, "---No Comment---");
out.close();

store 方法需要一个要写入的流,以及一个用作输出顶部注释的字符串。

获取属性信息

应用程序设置其 Properties 对象后,应用程序可以查询对象以获取有关其包含的各种键和值的信息,应用程序在启动后从 Properties 对象获取信息,以便它可以根据用户的选择初始化自身, Properties 类有几种获取属性信息的方法:

  • contains(Object value)containsKey(Object key)
    如果值或键位于 Properties 对象中,则返回 true ,属性从 Hashtable 继承这些方法,因此,它们接受 Object 参数,但只应使用 String 值。
  • getProperty(String key)getProperty(String key, String default)
    返回指定属性的值,第二个版本提供默认值,如果未找到键,则返回默认值。
  • list(PrintStream s)list(PrintWriter w)
    将所有属性写入指定的流或写入器,这对调试很有用。
  • elements()keys() 、和 propertyNames()
    返回包含 Properties 对象中包含的键或值(由方法名称指示)的 Enumerationkeys 方法只返回对象本身的键, propertyNames 方法也返回默认属性的键。
  • stringPropertyNames()
    propertyNames 类似,但返回 Set<String> ,并且仅返回其中键和值都是字符串的属性的名称,请注意, Set 对象不受 Properties 对象的支持,因此一个对象的更改不会影响另一个。
  • size()
    返回当前键/值对的数量。

设置属性

在执行期间用户与应用程序的交互可能会影响属性设置,这些更改应反映在 Properties 对象中,以便在应用程序退出时保存它们(并调用 store 方法),以下方法更改 Properties 对象中的属性:

  • setProperty(String key, String value)
    将键/值对放在 Properties 对象中。
  • remove(Object key)
    移除与键关联的键/值对。

上面描述的一些方法是在 Hashtable 中定义的,因此接受除 String 之外的键和值参数类型,始终使用字符串作为键和值,即使该方法允许其他类型,也不要在 Properties 对象上调用 Hashtable.setHastable.setAll ,始终使用 Properties.setProperty

命令行参数

Java应用程序可以从命令行接受任意数量的参数,这允许用户在启动应用程序时指定配置信息。

用户在调用应用程序时输入命令行参数,并在要运行的类的名称后指定它们。例如,假设一个名为 Sort 的Java应用程序对文件中的行进行排序,要对名为 friends.txt 的文件中的数据进行排序,用户将输入:

java Sort friends.txt

启动应用程序时,运行时系统会通过字符串数组将命令行参数传递给应用程序的 main 方法,在前面的示例中,命令行参数在包含单个 String :“friends.txt”的数组中传递给 Sort 应用程序。

回应命令行参数

Echo 示例单独在一行上显示其每个命令行参数:

public class Echo {
    public static void main (String[] args) {
        for (String s: args) {
            System.out.println(s);
        }
    }
}

以下示例显示用户如何运行 Echo

java Echo Drink Hot Java
Drink
Hot
Java

请注意,应用程序单独显示每个单词 — Drink、Hot和Java,这是因为空格字符分隔了命令行参数,要将Drink、Hot和Java解释为单个参数,用户可以通过将它们括在引号内来加入它们。

java Echo "Drink Hot Java"
Drink Hot Java

解析数字命令行参数

如果应用程序需要支持数字命令行参数,它必须将表示数字的 String 参数(例如“34”)转换为数字值,这是一个将命令行参数转换为 int 的代码片段:

int firstArg;
if (args.length > 0) {
    try {
        firstArg = Integer.parseInt(args[0]);
    } catch (NumberFormatException e) {
        System.err.println("Argument" + args[0] + " must be an integer.");
        System.exit(1);
    }
}

如果 args[0] 的格式无效,则 parseInt 会抛出 NumberFormatException ,所有 Number 类 — IntegerFloatDouble 等 — 都有 parseXXX 方法,它们将表示数字的 String 转换为其类型的对象。

环境变量

许多操作系统使用环境变量将配置信息传递给应用程序,与Java平台中的属性一样,环境变量是键/值对,其中键和值都是字符串,设置和使用环境变量的约定因操作系统和命令行解释器之间而异,要了解如何将环境变量传递给系统上的应用程序,请参阅系统文档。

查询环境变量

在Java平台上,应用程序使用 System.getenv 来检索环境变量值,如果没有参数, getenv 将返回 java.util.Map 的只读实例,其中映射键是环境变量名称,映射值是环境变量值,这在 EnvMap 示例中进行了演示:

import java.util.Map;

public class EnvMap {
    public static void main (String[] args) {
        Map<String, String> env = System.getenv();
        for (String envName : env.keySet()) {
            System.out.format("%s=%s%n",
                              envName,
                              env.get(envName));
        }
    }
}

使用 String 参数, getenv 返回指定变量的值,如果未定义变量,则 getenv 返回 null , Env 示例使用 getenv 以这种方式查询在命令行上指定的特定环境变量:

public class Env {
    public static void main (String[] args) {
        for (String env: args) {
            String value = System.getenv(env);
            if (value != null) {
                System.out.format("%s=%s%n",
                                  env, value);
            } else {
                System.out.format("%s is"
                    + " not assigned.%n", env);
            }
        }
    }
}

将环境变量传递给新进程

当Java应用程序使用 ProcessBuilder 对象创建新进程时,传递给新进程的默认环境变量集与提供给应用程序虚拟机进程的集合相同,应用程序可以使用 ProcessBuilder.environment 更改此集。

平台依赖问题

在不同系统上实现环境变量的方式之间存在许多细微差别,例如,Windows忽略环境变量名称中的大小写,而UNIX则不会。使用环境变量的方式也各不相同,例如,Windows在名为 USERNAME 的环境变量中提供用户名,而UNIX实现可能在 USERLOGNAME 或两者中提供用户名。

为了最大化可移植性,当系统属性中的相同值可用时,请不要引用环境变量,例如,如果操作系统提供用户名,则它将始终在系统属性 user.name 中可用。

其他配置实用程序

以下是一些其他配置实用程序的汇总。

Preferences API允许应用程序在依赖于实现的备份存储中存储和检索配置数据,支持异步更新,并且多个线程甚至多个应用程序可以安全地更新同一组首选项,有关更多信息,请参阅 Preferences API指南 。

部署在JAR存档中的应用程序使用 manifest 来描述存档的内容,有关更多信息,请参阅JAR文件中的打包程序课程。

Java Web Start应用程序的配置包含在JNLP文件中,有关更多信息,请参阅Java Web Start课程。

Java Plug-in applet的配置部分取决于用于在网页中嵌入applet的HTML标记,这些标记可以包含<applet>、<object>、<embed>和<param>,具体取决于applet和浏览器,有关更多信息,请参阅Java Applets课程。

java.util.ServiceLoader 类提供了一个简单的service provider设施,service provider是service的实现 — 一组众所周知的接口和(通常是抽象的)类。service provider中的类通常实现接口并子类化service中定义的类,service provider可以作为扩展安装(请参阅扩展机制),通过将Providers添加到类路径或通过其他特定于平台的方式,也可以使Providers可用。

上一篇:原子变量

原文 

https://segmentfault.com/a/1190000018507089

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java™ 教程(配置实用程序)

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址