Java 9模塊化關鍵字及應用場景
一、背景
Spring Boot 3.0最低要求jdk17,為跟上節奏儲備知識。
二、簡介
| 關鍵字 | 描述 | 應用場景 |
|---|---|---|
| module | 定義一個模塊 | 代碼隔離,依賴控制,代碼可重用性 |
| open module | 定義一個像java9之前的開放模塊 | 像Java的舊版本那樣允許完全反射 |
| exports...to | 指定模塊的一部分對外提供的包 | 限制代碼對外可見性,防止包沖突 |
| requires | 指定當前模塊依賴的另一個模塊 | 控制依賴,避免沖突,提高系統可靠性 |
| requires static | 聲明一組模塊的靜態依賴關系 | 編譯時檢查依賴關系,以確保程序在運行時能夠正確地工作。這對于使用反射或動態類加載的程序特別有用,因為這些程序在編譯時無法檢測到某些依賴關系,需要在運行時才能動態地加載類。 |
| opens...to | 類似于exports,但是會開放當前模塊內的包訪問權限,便于反射使用 | 某些框架、工具需要使用反射機制,但是反射機制需要訪問私有成員 |
| uses | 指定當前模塊使用的服務類型 | 提供SPI機制支持,方便應用程序擴展 |
| provides ...with | 指定當前模塊提供的服務類型和實現類 | 提供SPI機制支持,方便應用程序擴展 |
Java 9模塊化關鍵字應用場景:
- module:模塊化開發,將代碼分成多個模塊,隔離不同模塊的功能,增加代碼可重用性。
- exports:限制代碼對外可見性,防止包沖突,控制API的訪問權限。
- requires:控制依賴,避免沖突,提高系統可靠性。避免類路徑的問題,方便模塊的重構和管理。
- opens:提供某些框架、工具需要使用反射機制,但是反射機制需要訪問私有成員。
- uses:提供SPI機制支持,方便應用程序擴展。
- provides:提供SPI機制支持,方便應用程序擴展。
三、基礎聲明模塊與引用
1. 聲明一個模塊
module com.example.myapp {
requires java.base;
requires com.example.mymodule;
}
上述代碼定義了一個名為 com.example.myapp 的模塊,該模塊依賴于 java.base 和 com.example.mymodule 模塊。
2.導出包
module com.example.myapp {
requires java.base;
requires com.example.mymodule;
exports com.example.myapp.api;
}
上述代碼將 com.example.myapp.api 包導出到其他模塊中,使其可以訪問。
3.開放反射訪問
module com.example.myapp {
requires java.base;
requires com.example.mymodule;
opens com.example.myapp.internal to com.example.anothermodule;
}
上述代碼將 com.example.myapp.internal 包開放給 com.example.anothermodule 模塊,以便其可以使用反射訪問該包中的類和方法。
4.使用自定義模塊路徑
module com.example.myapp {
requires java.base;
requires com.example.mymodule;
exports com.example.myapp.api;
}
上述代碼使用 modules 目錄中的模塊路徑來運行 com.example.myapp.Main 類。
四、SPI聲明與引用
1.聲明所需服務
uses關鍵字用于指定模塊所需的服務,它可以出現在模塊描述文件(module-info.java)中。下面是一個示例:
module com.example.myapp {
requires java.base;
requires com.example.mymodule;
exports com.example.myapp.api;
}
在上面的示例中,my.module模塊依賴于some.module模塊,并使用了com.example.service.SomeService服務。
2.對外聲明所提供服務
provides關鍵字用于指定模塊提供的服務和實現,它也可以出現在模塊描述文件(module-info.java)中。下面是一個示例:
module my.module {
provides com.example.service.SomeService with com.example.service.impl.MyServiceImpl;
}
在上面的示例中,my.module模塊提供了com.example.service.SomeService服務,并使用了com.example.service.impl.MyServiceImpl實現。
使用了provides關鍵字的模塊還需要使用uses關鍵字來指定所需的服務,例如:
public interface SomeService {
void sayHello();
}
public class MyServiceImplimplements SomeService {
public static void doSomething() {
System.out.println("Hello, Modules!");
}
public void sayHello() {
System.out.println("Hello!");
}
}
module my.module {
uses com.example.service.impl.MyServiceImpl;
}
Iterable<SomeService> services = ServiceLoader.load(SomeService.class);
SomeService service = services.iterator().next();
service.sayHello();
浮生潦草閑愁廣,一聽啤酒一口盡
浙公網安備 33010602011771號