部署Java应用程序

JAR文件

Java归档(JAR)文件用于将应用程序打包成一个单独的文件,一个JAR文件既可以包含类文件,也可以包含诸如图像和声音这些其他类型的文件。JAR文件是压缩的,使用了ZIP压缩格式。

创建JAR文件

在jdk/bin目录下的jar工具可制作JAR文件,创建JAR文件常见命令格式为:jar cvf JARFileName File1 File2 … 。

此外,还有一些其他命令,格式为: jar options File1 File2 。下面为一些可选项:

optionsfunction
c创建一个新的JAR存入文件
v生成详细的输出结果
m将一个清单文件添加到JAR中
f将JAR文件指定为第二个命令行参数
e在JAR文件中添加一个条目
i建立索引文件
x解压文件
0只存储,不压缩

清单文件(manifest)

除了类文件、图像和其他资源外,每个JAR文件还包含一个用于描述归档特征的清单文件。

清单文件被命名为MANIFEST.MF,它位于JAR文件的一个特殊META-INF子目录中,最小的符合标准的清单文件是:Manifest-Version:1.0,复杂的清单文件可能包含更多条目,这些清单条目被分成多个节,第一节称为主节(main section),它作用于整个JAR文件,随后的条目用来指定已命名条目的属性,这些已命名的条目可以是某个文件、包或者URL,它们都必须起始于名为Name的条目,例如:Name:[Class].class。节与节之间用空行分开。

要编辑清单文件,需要将希望添加到清单文件中的行放到文本文件中,然后运行:jar cfm [JARFileName] [ManifestFileName] …

要更新一个已有的JAR文件的清单,需要将增加的部分放置到一个文本文件中,然后执行命令:jar ufm [MyArchive].jar manifest-additions.mf

可执行JAR文件

可以使用jar命令的e选项指定程序的入口点,即通常需要在调用java程序加载器时指定的类:jar cvfe [Myprogram].jar [MainClass] [files]

或者可以在清单中指定应用程序的主类:Main-Class:[MainClass]

清单文件最后一行必须以换行符结束,可以用java -jar命令启动应用程序。

资源

资源是在applet和应用程序中使用的类使用的一些相关数据文件,包括图像、音频、带消息字符串和按钮标签的文本文件、二进制数据文件等。

获取资源的步骤如下:

  • 获得具有资源的Class对象;
  • 如果资源是一个图像或声音文件,那么就需要调用getresource(filename)获得作为URL的资源位置,然后利用getImage或getAudioClip方法进行读取;
  • 与图像或声音文件不同,其他资源可用getResourceAsStream方法读取文件中的数据。

密封(seal)

可以将Java包密封以保证不会有其他的类加入到其中。如果在代码中使用了包可见的类、方法和域,就可能希望密封包。密封一个包,要将包中所有类放入一个JAR文件,在清单文件主节加入一行:Sealed:true改变全局默认设定,对每个包,可以在JAR文件清单增加一行:Sealed:true。

应用首选项的存储

用户通常希望保存它们的首选项和定制信息,再次启动时就可以恢复这些信息,Java传统做法是将配置信息保存在属性文件中,此外还有更健壮的方法:首选项API。

属性映射(property map)

属性映射是一种存储键值对的数据结构,通常用来存储配置信息:

  • 键和值是字符串;
  • 映射可以很容易的存入文件以及从文件加载;
  • 有一个二级表保存默认值。

实现属性映射的类为Properties。以下是一些基本操作:

Properties settings = new Properties();
settings.setProperty("width", "200");
settings.setProperty("title", "Hello, World!"); //指定配置信息

OutputStream out = new FileOutputStream("program.properties");
settings.store(out, "Program Properties"); //将属性映射保存到第一个参数表示的文件,第二个参数是包含在文件中的注释。

InputStream in = new FileInputStream("program.properties");
settings.load(in);  //从文件中加载属性

System.getProperties();  //主目录对应的属性映射
String userDir = System.getProperty("user.home")  //读取单个键

String title = settings.getProperty("title", "Default title")  //如果映射中有一个属性为第一个参数title,title设置为相应的字符串,否则,设为默认值第二个参数Default title。

/*将默认值放在一个二级属性映射中,在主属性映射的构造器中提供这个二级映射*/
Propertier defaultSettings = new Properties();
defaultSettings.setProperty("width", "300");
defaultSettings.setProperty("height", "200");
defaultSettings.setProperty("title", "Default title");
Properties settings = new Properties(defaultSettings);

属性映射实现了Map接口,不过put和get方法操作的是Object对象,getProperty和setProperty操作的是字符串。


属性映射是没有层次的简单类,如果存储复杂的配置信息,应当使用Preferences类。

首选项API

使用属性映射有以下缺点:

  • 有些操作系统没有主目录的概念,很难找到一个统一的配置文件位置;
  • 有些配置文件的命名没有标准约定,用户安装多个Java应用时,容易发生命名冲突。

有些操作系统有一个存储配置信息的中心存储库,如Windows的注册表。Preferences类以一种平台无关的方式提供了这样一个中心存储库。在Windows中,以注册表存储信息,在Linux中,存在本地文件系统。Preferences存储库有一个树状结构,结点路径名类似于包名,以避免命名冲突。存储库的各个节点分别有一个单独的键值对表,可以用来存储数值、字符串或字节数组,但不能存储可串行化的对象。可以有多个并行的数,操作系统使用当前用户对应的树。下面是一些基本操作:

Preference root = Preferences.userRoot();  //用户根节点
Preference root = Preferences.systemRoot();  //系统根节点

Preference node = root.node("com/mycompany/myapp")  //目录访问结点
Preferences node = Preferences.userNodeForPackage(obj.getClass);  //用对象访问结点

/*访问键值表*/
int getInt(String key, int defval); 
long getLong(String key, long defval);

/*写数据*/
put(String key, String value);
putInt(String key, int value);

注册表这样的存储库存在两个问题:

  • 他们会变成充斥着过期信息的垃圾场;
  • 配置数据与存储库纠缠在一起,以至于很难把首选项搬到新平台。

对于第二点,可以用exportSubtree(OutputStream out)和exportNode(OutputStream out)方法导出一个子树或结点的首选项。

数据用XML格式保存,可调用importPreferences(InputStream in)方法将数据导入到另一个存储库。

服务加载器

对于采用插件体系结构的应用,JDK提供了ServiceLoader类加载符合公共接口的插件。

定义一个接口,其中包含服务的各个实例应当提供的方法,服务提供者提供一个或多个实现这个服务的类,实现类可以放在任何包中,每个实现类必须有一个无参构造器。把这些类的类名增加到META-INF/services目录下的一个UTF-8编码文本文件中,文件名必须与完全限定类名一致。假设接口名为Service,程序可这样初始化一个服务加载器:public static ServiceLoader< Service > serviceLoader = ServiceLoader.load(Service.class);

服务加载器的iterator方法会对服务提供的所有实现返回一个迭代器。可以遍历所有对象,选择适当的对象使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值