JDK9 module 新特性
模块结构
- 模块
- src
- 包
- 代码.java
- module-info.java
- 包
- src
requires/exports
requires代表需要某个模块、exports代表暴露出哪些包里的类;
● 创建hello.module
module hello.module {
exports com.adi;
}
public class HelloProvider {
public void sayHello() {
System.out.println("hello world~");
}
}
● 创建client.module
module client.module {
requires hello.module;
}
public class HelloModule {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
HelloProvider helloProvider = new HelloProvider();
helloProvider.sayHello();
}
}
transitive
表示依赖传递,例如存在模块A、B、C,B依赖C,如果B声明transitive C,那么A依赖B的情况下自动依赖C;
● 创建base.module
module base.module {
exports com.adi.base;
}
public class Base {
private String info;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void base() {
System.out.println("base module~");
}
}
● 调整hello.module
module hello.module {
exports com.adi;
requires transitive base.module; // 增加
}
● 调整client.module
public class HelloModule {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
Base base = new Base(); // 可以直接访问到Base
base.base();
}
}
opens
该机制主要声明模块内的相关类可以直接暴露给反射机制进行访问;
● 调整base.module
module base.module {
exports com.adi.base;
// 代表可以被反射获取
opens com.adi.base;
}
● 调整client.module
public class HelloModule {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
// 可以反射处理Base的相关成员属性
Field info = base.getClass().getDeclaredField("info");
info.setAccessible(true);
info.set(base, "This is base info test");
System.out.println(base.getInfo());
}
}
providers…with…/uses
主要服务于spi机制,可以通过uses直接获取spi服务接口进行load;
● 调整base.module、新增BaseService、修改module-info
public interface BaseService {
void service();
}
● 新增service.module
public class ProductService implements BaseService {
@Override
public void service() {
System.out.println("product service ~");
}
}
public class SupplyService implements BaseService {
@Override
public void service() {
System.out.println("supply service ~");
}
}
module service.module {
requires base.module;
// 声明spi provides [接口] with [暴露出去的service实现类]
provides com.adi.base.BaseService with com.adi.service.ProductService, com.adi.service.SupplyService;
}
● 调整client.module,新增uses声明
module client.module {
requires hello.module;
// 声明使用spi
requires service.module;
uses com.adi.base.BaseService;
}
public class HelloModule {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
// spi加载service实现
ServiceLoader<BaseService> load = ServiceLoader.load(BaseService.class);
load.forEach(BaseService::service);
}
}
命令行相关操作
● 编译
javac <–module-path 模块存放目录> -d <编译内容存放的目录> [<编译的相关类> <编译的相关类>…]
● 执行
java <–module-path 模块存放目录> -m 主入口类