java 模块设计模式_Java9模块化学习笔记二之模块设计模式

模块设计的原则:

1、防止出现编译时循环依赖(主要是编译器不支持),但运行时是允许循环依赖的,比如GUI应用

2、明确模块的边界

几种模块设计:

API模块,聚合模块(比如java.base)

可选依赖

两种方式:

1、可选的编译时依赖(类似于maven的provided scope)声明: requires static , requires transitive static

2、使用services模式,缺点就是需要使用侵入性的ServiceLoader API

使用编译时可选依赖

module framework {

requires static fastjsonlib;

}

public static void main(String... args) {

try {

Class> clazz = Class.forName("javamodularity.fastjsonlib.FastJson");

FastJson instance =

(FastJson) clazz.getConstructor().newInstance();

System.out.println("Using FastJson");

} catch (ReflectiveOperationException e) {

System.out.println("Oops, we need a fallback!");

}

}

注意,通过requires static声明后,运行时,即使fastjsonlib模块在模块路径中,仍然会跑到异常块中,因为requies static声明的模块不会出现在模块解析路径上。除非你通过jlink打包时,加入--add-modules fastjsonlib选项来显式将其添加到模块解析路径(通过--add-modules也是作为一个root module).

使用Services模式的可选依赖

请参考之前的对于Services的探讨

Versioned Modules

jar命令打包时可以通过 --module-version=选项支持将版本添加到module-info.class中作为一个属性。但是对于模块解析而言,版本是没有意义的,模块解析过程中,只看模块名,不支持版本。

所以如果需要版本化,还是得借助于Maven,Gradle之类的打包工具。

资源封装

分模块内资源访问、模块间资源访问

模块内资源访问

firstresourcemodule/

├── javamodularity

│   └── firstresourcemodule

│   ├── ResourcesInModule.java

│   ├── ResourcesOtherModule.java

│   └── resource_in_package.txt 包内资源

├── module-info.java

└── top_level_resource.txt 与module-info.java平级的资源

访问方式有几种,见下面代码:

public class ResourcesInModule {

public static void main(String... args) throws Exception {

Class clazz = ResourcesInModule.class;

InputStream cz_pkg = clazz.getResourceAsStream("resource_in_package.txt"); //<1>

URL cz_tl = clazz.getResource("/top_level_resource.txt"); //<2>

Module m = clazz.getModule(); //<3>

InputStream m_pkg = m.getResourceAsStream(

"javamodularity/firstresourcemodule/resource_in_package.txt"); //<4>

InputStream m_tl = m.getResourceAsStream("top_level_resource.txt"); //<5>

assert Stream.of(cz_pkg, cz_tl, m_pkg, m_tl)

.noneMatch(Objects::isNull);

}

}

在模块化中,不推荐使用ClassLoder::getResource*

注意上面代码中用到了Module API

跨模块资源访问

.

├── firstresourcemodule

│   ├── javamodularity

│   │   └── firstresourcemodule

│   │   ├── ResourcesInModule.java

│   │   ├── ResourcesOtherModule.java

│   │   └── resource_in_package.txt

│   ├── module-info.java

│   └── top_level_resource.txt

└── secondresourcemodule

├── META-INF

│   └── resource_in_metainf.txt

├── foo

│   └── foo.txt

├── javamodularity

│   └── secondresourcemodule

│   ├── A.java

│   └── resource_in_package2.txt

├── module-info.java

└── top_level_resource2.txt

注意,下面代码的前提是两个模块的包都没暴露给对方

public class ResourcesOtherModule {

public static void main(String... args) throws Exception {

Optional otherModule = ModuleLayer.boot().findModule("secondresourcemodule"); //<1>

otherModule.ifPresent(other -> {

try {

InputStream m_tl = other.get

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值