14.2 Java平台模块化
模块化是目前软件开发中经常会用到的设计理念。把系统划分成不同的模块之后,开发团队可以分工合作,快速高效地完成开发工作。采用模块化设计的系统也更容易复用、维护和更新。不过Java平台本身并没有对模块化的系统的实现提供很多的支持。一般的做法是把Java类组织在不同的名称空间中,多个Java类组织在一个jar包中,多个jar包同时出现在程序的类路径(CLASSPATH)中。由于不同jar包中可能存在同名的Java类,加上复杂的类加载器实现机制,使Java程序经常出现与类加载相关的问题。由于Java平台本身存在限制,为Java平台提供模块化支持的OSGi技术得到了广泛的流行,这也从侧面反应了开发者社区对于模块化的需求。OpenJDK中的Jigsaw项目的目标在于为Java平台增加模块化的支持,这也是Java SE 8的重要组成部分。
Jigsaw项目为Java语言增加了模块的概念。模块是Java类型的集合。每个模块有自己的名称、一个可选的版本号,以及当前模块和其他模块之间关系的描述。模块之间最重要的关系是依赖关系。一个模块可以依赖其他的模块,并利用所依赖的模块提供出的Java类。对于一个模块来说,模块本身的信息由名为module-info.java的Java文件来提供。代码清单14-10给出了module-info.java文件的内容示例。模块“com.my.base”的版本号是1.0,依赖于版本号为2.0的“com.example”模块。通过“exports”声明了模块“com.my.base”中的“com.my.base.utils”包对依赖它的模块是可见的。通过“class”声明了模块“com.my.base”的主Java类是“com.my.base.MainApp”。
代码清单14-10 module-info.java文件的内容示例
module com.my.base@1.0{
requires com.example@2.0;
exports com.my.base.utils;
class com.my.base.MainApp;
}
module com.my.ui@1.0{
requires com.my.base;
}
在模块中,除了module-info.java文件之外,其他的内容与一般的Java程序中可以包含的内容相同,可以包括Java源代码、资源文件、配置文件和本地代码等。在编译过程中,模块中包含的源代码会被编译,然后进行打包和发布。打包好的模块可以安装到某个模块仓库中。这个仓库中包含了所有可用的模块。在运行时,虚拟机会负责从模块仓库中加载模块,并与它所依赖的其他模块进行链接,之后就可以运行该模块了。