资讯专栏INFORMATION COLUMN

Java基础-模块系统笔记(1)

learning / 3503人阅读

摘要:模块系统的前身是项目。最初,该项目仅仅是为设计实现一个模块系统。随着项目的不断深入,平台对标准模块系统的呼求也日益增长,批准该项目升级为平台的一部分,也能服务于和平台的需求。自定义的配置,仅包含一组指定的模块及其所需的模块。

我的博客 转载请注明原创出处。

Java 9开始,在Java的世界里多了一个叫模块(JSR376)的特性。模块系统的前身是Jigsaw项目。最初,该项目仅仅是为JDK设计、实现一个模块系统。后来项目组也希望它能为开发者所用——虽然,一开始它并不是Java SE平台规范的组成部分。随着项目的不断深入,Java平台对标准模块系统的呼求也日益增长,JCP批准该项目升级为JavaSE平台的一部分,也能服务于Java MEJava EE平台的需求。

官方对Java平台模块系统是这样描述的: 一种新的Java编程组件,即模块。它是自描述的代码与数据的集合,有以下特性:

引入了一个新的可选阶段——链接时,它介于编译时和运行时之间,在此期间可以将一组模块组装并优化为定制的运行时镜像。

为工具javacjlink增加了一些选项,以及在Java中,你可以指定模块路径,这些路径定位模块的定义。

引入模块化JAR文件,该文件是一个JAR文件,其根目录中包含module-info.class文件。

引入JMOD格式,它是一种类似于JAR的打包格式,但它可以包含原生代码和配置文件。

JDK本身已经模块化。有以下改变:

使你能够将JDK的模块组合成各种配置,包括:

JREJDK一样的配置。

Java SE 8中定义的每个压缩配置文件的内容大致相同。

自定义的配置,仅包含一组指定的模块及其所需的模块。

重构JDKJRE运行时镜像以适应模块并提高性能、安全性和可维护性。

定义了一个新的URI方案,用于命名存储在运行时映像中的模块,类和资源,而不会泄露映像的内部结构或格式。

删除认可的标准覆盖机制和扩展机制。

Java运行时镜像中删除rt.jartools.jar

默认情况下,大多数JDK的内部API都不可访问,但在所有或大部分功能都支持替换之前,可以访问一些关键的、广泛使用的内部API

运行jdeps -jdkinternals命令以确定你的的代码是否使用了内部JDK API

兼容性

先来说说模块系统的兼容性。Java一直是比较保守的,体现在更新上就是良好的兼容性。虽然看了官方对Java平台模块系统的描述好像改动非常大,但是你的旧项目即使不模块化也是能在新JDK上运行的。后面会讲到没有模块化的类包是如何与模块交互的。

为什么要模块化

既然不模块化也能好好的运行,那么为什么要这么大费周章的折腾代码呢?

第一点,Java 9前的Java程序,即使是一个简单的输出Hello World的程序,也必须将整个JDKJRE运行时镜像打包进去才能运行,这时Java引以为傲的数量繁多的类库反而成了累赘。比如开源的优秀编程库——Guava里有很多很实用的工具类,有时我们可能只用到了其中一个类而已,却不得不将整个Guava类库打包进我们的项目。

第二点,没法定义类是否能被其他包里的类引用到。比如我们编写了一个工具类,如果希望这个类只能被某些包里的其他类引用到,不暴露给其他包,Java 9前的Java程序是做不到这一点的。

如何模块化

模块化一个项目只要在项目的根目录创建一个module-info.class文件就可以了。

如图所示,我们创建了一个名为module的模块并用关键字exports导出了test包。如果有其他模块导入module模块就可以引用到Main类了,值得注意的是和test同级的包和test内部的包因为没有被导出,都是不能被引用到的。

而引用一个模块则是用关键字requires

然后就可以使用test包内的类了:

import test.Main;

/**
 * @author Yuicon
 */
public class Test {

    public static void main(String[] args) {
        Main main = new Main();
        System.out.println(main);
    }

}

不过在导入前还需要在模块依赖里添加要导入的模块:

java.base模块是默认导入的,里面有我们常用的类库:

模块的强封装性

我们知道模块化后就能控制那些包可以被引用到了。不过不止如此,一个模块的类是不能访问到其他模块里的类的私有属性的。听起来好像是理所当然的,这是因为原先我们是可以用反射来访问到私有属性的。模块化后就算反射也不能访问到了,算是加强了安全性。

不过这样的话,那些依赖反射来获取私有属性的框架和库就倒霉了。为了兼容这些框架和库,我们可以在模块定义里加一个关键字open

module-info.class

open module module {
    exports test;
}

这样我们就声明了一个开放的模块,在模块的所有软件包上授予深入的反射访问权限(访问公共和私有API)。

模块语句

在模块声明文件里一共有五种模块语句,分别是:

导出语句(exports statement)

开放语句(opens statement)

需要语句(requires statement)

使用语句(uses statement)

提供语句(provides statement)

package test.driver;

/**
 * @author Yuicon
 */
public interface Driver {

    int getCode();

}
package test;


import test.driver.Driver;


/**
 * @author Yuicon
 */
public class DriverImpl implements Driver {

    @Override
    public int getCode() {
        return 10086;
    }
}
module module {
    exports test.driver; // 导出包
    provides Driver
            with DriverImpl; // 为接口Driver提供实现
}

module queue {
    requires module; // 导入包
    opens test; // 开放包的反射权限
    uses Driver; // 声明使用接口
}
package main;

import test.driver.Driver;

import java.util.ServiceLoader;


/**
 * @author Yuicon
 */
public class Main {

    public static void main(String[] args) {
        // 获取实现
        ServiceLoader serviceLoader = ServiceLoader.load(Driver.class);
        serviceLoader.findFirst().ifPresent(driver -> System.out.println(driver.getCode()));
    }

}

输出:

10086

Process finished with exit code 0
聚合模块

你可以创建一个不包含任何代码的模块,它收集并重新导出其他模块的内容,这样的模块称为聚合模块。假设有几个模块依赖于五个模块,你可以为这五个模块创建一个聚合模块。现在,你的模块只能依赖于一个模块——聚合模块。

为了方便,Java 9包含几个聚合模块,如java.sejava.se.eejava.se模块收集Java SE的不与Java EE重叠的部分。java.se.ee模块收集组成Java SE的所有模块,包括与Java EE重叠的模块。

待续

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71719.html

相关文章

  • Java应用架构设计:模块化模式与OSGi》读书笔记

    摘要:本书概括以软件系统为例,重点讲解了应用架构中的物理设计问题,即如何将软件系统拆分为模块化系统。容器独立模块不依赖于具体容器,采用轻量级容器,如独立部署模块可独立部署可用性模式发布接口暴露外部配置使用独立的配置文件用于不同的上下文。 本文为读书笔记,对书中内容进行重点概括,并将书中的模块化结合微服务、Java9 Jigsaw谈谈理解。 本书概括 以Java软件系统为例,重点讲解了应用架构...

    seanHai 评论0 收藏0
  • (CZ深入浅出Java基础)设计模式笔记

    摘要:在设计模式中,所有的设计模式都遵循这一原则。其实就是说在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。使用设计模式是为了可重用代码让代码更容易被他人理解保证代码可靠性。 这是刘意老师的JAVA基础教程的笔记讲的贼好,附上传送门 传智风清扬-超全面的Java基础 一、面向对象思想设计原则 1.单一职责原则 其实就是开发人员经常说的高...

    李昌杰 评论0 收藏0
  • 《大型网站系统Java中间件》读书笔记(上)

    摘要:另一个用户请求过来,负载均衡器指派这个请求到服务器。这样就平摊了请求这种方式就叫做轮询策略还有很多种,就看你想怎么实现了,反正这个逻辑的代码放在负载均衡器上。 前言 只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 这本书买了一段时间了,之前在杭州没带过去,现在读完第三章,来做做笔记 showI...

    baukh789 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<