方案:通過拆分模塊和使用 provided 作用域優(yōu)化 SDK 和 API 的依賴
背景:
你們項(xiàng)目的 fat JAR 問題主要集中在 API 和 SDK 包里。通過將 SDK 和 API 進(jìn)行模塊化,并且合理使用 Maven 的 provided 作用域,可以避免不必要的依賴被打包到最終的 JAR 文件中,從而解決 fat JAR 問題。
1. 模塊化項(xiàng)目結(jié)構(gòu):將 SDK 和 API 拆分為獨(dú)立模塊
目標(biāo):通過模塊化管理 SDK 和 API,確保每個(gè)模塊只包含必要的代碼和依賴,不將所有依賴都打包在同一個(gè) JAR 文件中。
步驟:
拆分 SDK 和 API 為獨(dú)立模塊:你可以將 SDK 和 API 分別拆分為獨(dú)立的 Maven 模塊,分別負(fù)責(zé)自己的功能。這樣,SDK 模塊可以單獨(dú)發(fā)布,而 API 模塊僅用于定義接口和通用服務(wù),不包含實(shí)現(xiàn)代碼。
API 模塊:只包含 API 的定義(接口、DTO 等),不包含實(shí)現(xiàn)。這個(gè)模塊將作為 SDK 模塊的依賴。
SDK 模塊:包含 SDK 的實(shí)現(xiàn),依賴于 API 模塊。
目錄結(jié)構(gòu)示例:
my-project
│
├── api # API 模塊
│ ├── src
│ └── pom.xml
│
└── sdk # SDK 模塊
├── src
└── pom.xml
Maven 配置示例:
-
API 模塊(
api/pom.xml):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<!-- No external dependencies needed here, just API definitions -->
</dependencies>
</project>
-
SDK 模塊(
sdk/pom.xml):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sdk</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<!-- SDK depends on the API module -->
<dependency>
<groupId>com.example</groupId>
<artifactId>api</artifactId>
<version>1.0.0</version>
</dependency>
<!-- External dependencies such as Spring, Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> <!-- Container provides this -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
<scope>provided</scope> <!-- Provided by external environment -->
</dependency>
</dependencies>
</project>
解釋:
- 拆分模塊:通過將 SDK 和 API 拆分為獨(dú)立模塊,SDK 模塊只依賴 API 模塊,避免了所有依賴都被打包在同一個(gè) JAR 文件中的問題。
-
減少不必要的依賴:只將 SDK 和 API 需要的依賴包含在 SDK 模塊中,并將這些依賴的
scope設(shè)置為provided,避免它們被打包進(jìn) SDK JAR 中。
2. 使用 provided 作用域來優(yōu)化 SDK 和 API 依賴
目標(biāo):確保在編譯和測試時(shí)需要的依賴,在打包時(shí)不會被包含在最終的 JAR 文件中。
步驟:
標(biāo)記容器提供的依賴:對于那些由外部容器或環(huán)境提供的依賴(例如 Servlet API、JSP、Spring),使用
provided作用域來標(biāo)記它們。SDK 中使用
provided作用域:如果你的 SDK 依賴于一些框架(如 Spring 或 Servlet API),并且這些框架在運(yùn)行時(shí)已經(jīng)由外部容器提供,那么這些依賴應(yīng)設(shè)置為provided,這樣就不會被打包進(jìn) JAR 文件中。
示例配置:
在 SDK 模塊中:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> <!-- Servlet API 由容器提供 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
<scope>provided</scope> <!-- Spring 由應(yīng)用服務(wù)器提供 -->
</dependency>
解釋:
provided作用域:表示這些依賴只在編譯時(shí)可用,運(yùn)行時(shí)由外部容器提供。這樣,它們不會被打包進(jìn) SDK 模塊的 JAR 文件中。減少
fat JAR大小:通過使用provided作用域,容器提供的依賴(如 Servlet API、Spring 等)將不會被打包進(jìn) JAR 文件中,減小了 SDK 的體積。
3. 結(jié)合 spring-boot-maven-plugin 和 provided 作用域避免 fat JAR
目標(biāo):如果你正在使用 Spring Boot,可以通過配置 Spring Boot Maven 插件,避免不必要的依賴被打包進(jìn)最終的 JAR 文件中。
步驟:
- 在
pom.xml中配置spring-boot-maven-plugin,并設(shè)置includeDependencies為false,確保所有依賴不會被打包進(jìn) JAR 文件中。
示例配置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.0</version>
<configuration>
<!-- 不包括 SDK 和 API 依賴 -->
<includeDependencies>false</includeDependencies>
</configuration>
</plugin>
</plugins>
</build>
解釋:
spring-boot-maven-plugin配置:通過設(shè)置includeDependencies=false,Spring Boot 插件會跳過將 SDK 和 API 的依賴打包進(jìn)最終的 JAR 文件中,只將應(yīng)用的代碼打包。減小 fat JAR:最終的 JAR 文件只包含應(yīng)用代碼,而不包含 SDK 和 API 中的外部依賴,從而避免生成 fat JAR。
總結(jié)
針對你的 SDK 和 API 模塊的 fat JAR 問題,以下是優(yōu)化的主要步驟:
- 模塊化項(xiàng)目結(jié)構(gòu):將 SDK 和 API 拆分為獨(dú)立模塊,避免將所有代碼和依賴打包進(jìn)同一個(gè) JAR 文件中。
-
使用
provided作用域:對于由容器提供的依賴(如 Servlet API、Spring 等),在 SDK 模塊中使用provided作用域,確保它們不會被打包進(jìn) JAR 文件中。 -
Spring Boot 插件配置:通過
spring-boot-maven-plugin配置includeDependencies=false,避免將所有依賴打包進(jìn) JAR 文件中,最終減小 JAR 文件體積。
通過這些優(yōu)化,你將能夠有效避免 fat JAR 問題,減小 SDK 和 API 的體積,并且保持模塊的清晰和可維護(hù)性。