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(); // 可以直接访问到Basebase.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 {@Overridepublic void service() {System.out.println("product service ~");}
}
public class SupplyService implements BaseService {@Overridepublic 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;// 声明使用spirequires 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 主入口类