从Java9开始支持了模块化机制,可以按照模块划分功能,总结下来Module有以下优点:
- JRE可定制化
Java9前需要在目标机器上安装完整的JRE环境,JRE是包含运行java程序的所有需要的库,但里面的东西并不是所有应用都需要,通过Module可以为应用量身定制JRE,这大大减少了JRE的大小和运行时内存消耗,如应用只需要依赖java.base模块,那么我们可以定制一个只包含java.base模块的JRE,这样去掉用大量无需用到的类库,整个JRE的运行消耗更少,更轻量化。
- 封装性
可以导出组件被外部访问,未导出的组件仅模块内部可见,package(包机制)也有访问权限控制,但有一个缺点,包机制可以通过反射等手段绕过。
通过实例来学习Module机制的应用
基于module机制的demo
建立一个简单maven quickstart项目,项目结构如下:
App.java 向标准输出打印hello,word
package mone.pkg;
public class App {
public static void main(String[] args){
System.out.println("hello,word");
}
}
module-info.java 这个文件表示该项目是一个模块(module),它描述了这个模块的信息,如 模块依赖哪些其它模块,模块内部的导出类(能够被其它模块访问)等。
module mone.a.b.c{
requires java.base;
exports mone.pkg;
}
module关键字声明一个模块域,后面定义这个模块的命名空间。
requires表示依赖的外部模块
exports 该模块导出的包
使用jdk9及以上版本编译它。
javac -d mods /testj9/mone/src/main/java/mone/pkg/App.java /testj9/mone/src/main/java/mone/pkg/module-info.java
运行
java --module-path=/Users/zhangqiang/Documents/temp/testj9/mods/ -m mone.a.b.c/mone.pkg.App
- 将模块打包为jar包
jar -v --create --file=/testj9/mone/mlib/mone.jar --module-version=1.0 -C /testj9/mone/src/main/java/mods . --main-class=mone.pkg.App
和普通java项目打包没有太大区别,--module-version 指定模块版本,--main-class 模块的可执行类
运行jar
java -p /testj9/mone/mlib -m mone.a.b.c/mone.pkg.App
打印jar包内模块的描述信息
jar --describe-module --file=/testj9/mone/mlib/mone.jar
- 定制JRE
定制用于运行特定java应用程序的jre,该jre仅包含java应用依赖的模块,比如定制包含mone.a.b.c的JRE,它仅包含mone模块依赖的模块 java.base,定制的jre更轻量级,更高效,因为它无需加载整个java基础类库。
jlink --module-path /testj9/mone/mlib:mone --add-modules mone.a.b.c --output jreoutput