JAVA9模块化详解(二)——模块的使用

时间:2023-03-09 01:12:31
JAVA9模块化详解(二)——模块的使用

JAVA9模块化详解(二)——模块的使用

二、模块的使用

  各自的模块可以在模块工件中定义,要么就是在编译期或者运行期嵌入的环境中。为了提供可靠的配置和强健的封装性,在分块的模块系统中利用他们,必须确定它们的位置,然后决定他们如何关联彼此。

2.1 模块的路径

  为了在确定在工件中定义的模块的位置,模块系统搜索模块的路径,它在主系统中定义。模块路径是一个序列,它的每一个元素要么是一个模块工件,要么是一个包含模块工件的目录。模块路径中的元素被第一个工件有序的搜索,这个工件定义了一个合适的模块。模块的路径在物理上不同于类路径,而且更强大。类路径天生的脆弱性是它定位了路径下所有工件中的个体类型,在工件中间没有任何的区分。这使得它在工件丢失时不可能提前告知,它也允许不同的工件在相同的包中定义类型,即使那些工件代表中相同程序组件的不同版本,或者完全不同的组件。

  相比之下,模块路径定位整个的模块,而不是个体类型。如果模块系统不能从模块路径中处理工件的特殊依赖,或者如果它在相同的目录下遇到了两个模块名字相同的工件,这是编译器或者虚拟机将报告一个错误并退出。

  嵌入到编译器或运行期环境的模块,连同模块路径下工件定义的模块被交付到全局的可被观察的模块。

2.2 解决方案

  假设我们有一个应用,它使用了上一章讲到的com.foo.bar模块,也用到了java.sql模块,包含了应用核心的模块声明如下:

module com.foo.app {
requires com.foo.bar;
requires java.sql;
}

  给出的这个最初的应用模块,模块系统解决了requires项表达的依赖,它通过定位额外可观察到的模块完成了依赖的任务,然后解决那些模块的依赖,等等,直到每一个模块的每一个依赖都解决完。这个传递闭包计算的结果是一个模块图,它包含了从第一个模块到第二个模块的矢量,依赖的每一个模块通过一些其他的模块解决。

  为了构建com.foo.bar模块的模块图,模块系统检测到了java.sql的模块声明,如下:

module java.sql {
requires java.logging;
requires java.xml;
exports java.sql;
exports javax.sql;
exports javax.transaction.xa;
}

  它也检测到了com.foo.bar的模块声明,在上面已经展示过,同时也检测到了org.baz.qux,java.logging,和java.xml模块,为了简洁,后三个模块在这里不做展示,它们也没有声明依赖其他模块。基于这些模块的声明,com.foo.app模块计算出的模块图包含如下的节点和边界:

    aaarticlea/png;base64,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" alt="" width="452" height="221" />

  在上面的图中,深蓝色的线代表着确定的依赖关系,它在requires项中定义,浅蓝色的线代表着隐性的依赖,每一个模块都依赖基础模块(base module)。

 2.3 可读性

  在模块图中,当一个模块直接依赖另一个时,第一个模块中的代码可以访问第二个模块中的类型。因此,我们说第一个模块读取第二个模块,相等的,也可以说第二个模块对于第一个模块是可读的。于是,上面的图中,com.foo.app模块读取com.foo.bar和java.sql,但是不读取org.baz.qux,java.xml和java.logging。java.logging模块对于java.sql模块是可读的,对于其他模块不可读。

  在模块图中可读性定义的关系是可靠性配置的基础:模块系统确保每一个依赖都被确定的其他的模块解决,模块图是非循环的,每一个模块最多读取一个模块定义的包(package),定义了相同名字的模块彼此间互不干扰。

  可靠性配置不仅仅是更可靠,它也更快。当一个模块中的代码涉及到一个包(package)中的类型时,这个包肯定被定义在这个模块中,或者这个模块确切读取的其他模块中。因此,当寻找确切类型的定义时,不需要在多个模块中寻找,也不需要更糟的在类路径下寻找。

2.4 可接入性

  模块中定义的可读性关系,结合了模块声明中的exports项,是强健的封装性的基础:java编译器和虚拟机认为,只有当第一个模块被其他模块读取时,第一个模块包中的公共类型才能被其他包访问,按照这个意思,第一个模块输出了可访问的包。如果S和T两个类型定义在不同的模块中,T是公共的(public),S中的代码可以访问T的要求如下:

  1.   S模块读取(requires)T模块;
  2.   T模块输出(exports)T包;

  一个类型用这种方式引用了不可访问的模块边界是不可用的,比如它访问的私有的方法或变量是不可用的。任何使用它的尝试都会引起编译器报告错误,或者被虚拟机抛出一个IllegalAccessError的错误,或者被运行期的反射API抛出IllegalAccessException 的错误。因此,一个类型即使是public,但是它并没有在模块声明中输出(exports),它也只能在自己的模块中被访问。

  如果一个模块的封装类型是可以访问的或者成员的声明是可以访问的,则通过模块边界引用的方法和字段也是可以访问的。

  为了看到强大的封装性是如何工作的,我们在上面的模块图中,添加了标注

  JAVA9模块化详解(二)——模块的使用

  com.foo.app模块中的代码可以访问com.foo.bar.alpha包中的公共类型,英文com.foo.app依赖,也可以说读取com.foo.bar模块,并且英文com.foo.bar输出com.foo.bar.alpha包。如果com.foo.bar包含了一个内部的包com.foo.bar.internal,并且com.foo.bar不输出它,则com.foo.app不能访问这个包中的任何类型。com.foo.app中的代码不能涉及org.baz.qux中的类型,英文com.foo.app不依赖org.baz.qux。

2.5 隐性可读性

  如果一个模块读取另一个,在某种情况下,它在逻辑上也读取其他的一些模块。举个例子,平台模块java.sql依赖java.logging和java.xml模块,它不仅使用了那些模块中的类型实现了代码,并且还定义了那些模块中的类型。比较特殊的,java.sql.Driver接口定义了公共方法:

public Logger getParentLogger();

  在这里,Logger是java.logging模块中java.util.logging包输出的类型。假如com.foo.app模块引用了这个方法,并且打印了日志:

String url = ...;
Properties props = ...;
Driver d = DriverManager.getDriver(url);
Connection c = d.connect(url, props);
d.getParentLogger().info("Connection acquired");

  如果com.foo.app模块像上面那样声明,它是不会工作的。getParentLogger方法返回了一个Logger,它在java.logging模块中声明,它不被com.foo.app模块读取,所以Logger类中的info方法在编译期和运行期都是失败的,因为那个类是不能被访问的。

  解决这个问题的一个方法是希望每一个模块的作者,在依赖了java.sql模块并且使用Logger类时,在声明一个java.logging的依赖。这种方法是不可靠的,它违反了最少意外的原则:如果一个模块依赖了第二个模块,它非常自然的希望,第一个模块需要使用的类型,即使这个类型定义在第二个模块中,其他模块仅仅依赖第一个模块就可以直接访问。

  于是,我们扩展了模块声明,一个模块可以把可读性授权给另外的,依赖它的模块,扩展可读性的表达式(public)在requires项上,如下所示:

module java.sql {
requires public java.logging;
requires public java.xml;
exports java.sql;
exports javax.sql;
exports javax.transaction.xa;
}

  public修饰语的意思是任何依赖了java.sql模块的模块,不仅可以读取java.sql模块,还可以读取java.logging和java.xml模块。com.foo.app的模块图增加了另外两个深蓝色的线,他们被绿线连接到了java.sql模块。如图:

JAVA9模块化详解(二)——模块的使用

  现在com.foo.app模块可以读取java.xml和java.logging模块中的所有公共类型,虽然它的声明中并没有提到那些模块。

  总的来说,如果一个模块输出一个包,这个包包含了第二个模块中的包的类型,则第一个模块应该声明为 requires public ,依赖第二个模块。这可以保证其他依赖了第一个模块的模块可以自动读取第二个模块,因此,可以访问那个模块输出包中的所有公共类型。

  至此,JAVA9模块化详解(二)——模块的使用就先介绍到这里,这个系列还会继续,请大家多多支持,有不妥之处,还请大家多多交流。