maven打包springboot項目的插件配置概覽


jar包的術語背景:
  1. normal jar: 普通的jar,用於項目依賴引入,不能通過java -jar xx.jar執行,一般不包含其它依賴的jar包。
  2. fat jar: 也叫做uber jar,是一種可執行的jar(executable jar),既包含自己代碼中的class ,也包含第三方依賴的jar。
  3. 不可執行,但包含第三方依賴的jar包,避免生成的jar與第三方引入后出現依賴版本沖突。
POM文件中的內置屬性(Maven預定義可以直接使用): 
 ${basedir} 項目根目錄
 ${version} 表示項目版本;
 ${project.basedir} 同${basedir};
 ${project.version} 表示項目版本,與${version}相同;
 ${project.build.directory} 構建目錄,缺省為target;
 ${project.build.sourceEncoding} 表示主源碼的編碼格式;
 ${project.build.sourceDirectory} 表示主源碼路徑;
 ${project.build.finalName} 表示輸出文件名稱;
 ${project.build.outputDirectory} 構建過程輸出目錄,缺省為target/classes
1. 第一類需求: 生成單個fat jar

使用springboot提供的maven打包插件spring-boot-maven-plugin即可,方便快捷,pom文件的配置如下:

<!-- 測試本地jar包引入和打包 -->
<!-- 項目管理的角度,盡量不使用本地jar包,搭建maven私服可以統一更新管理自研jar包 -->
<dependency>
    <groupId>cn.henry.test</groupId>
    <artifactId>local_test</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${basedir}/src/main/local_lib/local_test.jar</systemPath>
</dependency>
<build>
    <plugins>
        <!-- 常規打包,flat jar,打出來的jar很大,不易於修改部分文件后增量發布 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!-- 作用:項目打成jar的同時將本地jar包也引入進去 -->
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>
2. 第二類需求: 啟動項和依賴包分離的fat jar

項目文件和依賴的jar包分離,因為引用的jar變動較少,項目發布時只需替換項目jar包或class即可,使用常規maven打包插件, maven-jar-plugin, maven-dependency-plugin,輸出為可執行的jar和lib包,pom文件的配置如下:

<!-- 測試本地jar包引入和打包 -->
<!-- 項目管理的角度,盡量不使用本地jar包,搭建maven私服可以統一更新管理自研jar包 -->
<dependency>
    <groupId>cn.henry.test</groupId>
    <artifactId>local_test</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${basedir}/src/main/local_lib/local_test.jar</systemPath>
</dependency>
<build>
     <!-- 配置文件,依賴jar和可執行jar分離的包,便於文件替換發布 -->
     <plugins>
           <!-- 復制依賴的jar包到指定的文件夾里,相當於:mvn dependency:copy-dependencies -DoutputDirectory=lib -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- 配置依賴和啟動類-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <!-- MANIFEST.MF 中 Class-Path 加入前綴 -->
                        <classpathPrefix>lib/</classpathPrefix>
                        <!--指定入口類 -->
                        <mainClass>cn.henry.study.FileMessageServer</mainClass>
                    </manifest>
                    <manifestEntries>
                        <!-- 在Class-Path下添加配置文件的路徑,本地jar的引入方式: dependency中的artifactid-version.jar -->
                        <Class-Path>lib/local_test-1.0.0.jar</Class-Path>
                        <!--這里表示jar路徑加入到MANIFEST.MF-->
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
3. 第三類需求: 提供給第三方使用的,包含所有依賴的普通jar

解決項目jar中依賴與引用方jar包版本沖突的問題,提高jar包的易用性和獨立性,缺點是打出來的包較大,jar包內置依賴不透明。 使用maven打包插件maven-shade-plugin,pom文件的配置如下:

在cmd中切換到local_test.jar包所在的目錄,執行
mvn install:install-file "-DgroupId=cn.henry.frame" "-DartifactId=local_test" "-Dversion=1.0.0" "-Dpackaging=jar" "-Dfile=local_test.jar"
其中:
-DgroupId 為maven依賴的groupId
-DartifactId 為maven依賴的artifactId
-Dversion 為maven依賴的version
-Dfile 為local_test.jar包的文件名

引入安裝后的local_test.jar包,maven依賴如下:
<!-- 項目管理的角度,盡量不使用本地jar包,搭建maven私服可以統一更新管理自研jar包 -->
<dependency>
    <groupId>cn.henry.frame</groupId>
    <artifactId>local_test</artifactId>
    <version>1.0.0</version>
</dependency>

<build>
    <plugins>
        <!-- 提供給第三方使用的,包含所有依賴的普通jar -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <!-- 加入啟動類 -->
                        <!--<transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>xxx.xxx</mainClass>
                            </transformer>
                        </transformers>-->
                        <createDependencyReducedPom>false</createDependencyReducedPom>
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.SF</exclude>
                                    <exclude>META-INF/*.DSA</exclude>
                                    <exclude>META-INF/*.RSA</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
4. 第四類需求: 提供給第三方使用的,僅包含項目代碼的普通jar

通用模式,如果項目中有使用到第三方依賴,需要提供說明,否則會直接報class not found exception。 使用maven打包插件maven-jar-plugin,pom文件的配置如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
            </manifest>
        </archive>
    </configuration>
</plugin>

注意打包插件的版本選擇,盡量使用高版本,官方可能修復了已存在的問題,按項目的需求選取打包方式。
maven的打包插件官網: http://maven.apache.org/plugins

用maven查看jar依賴:mvn dependency:tree

插件打包的原理:讀取xml配置,組裝成規范的jar文件

jar規范可以閱讀oracle的官方文檔:https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html

重點關注的部分: JAR文件格式中META-INF目錄下的MANIFEST.MF文件,用於定義擴展和包相關的數據。主屬性: Manifest-Version(MF文件版本號), Main-Class(包含main方法的類), Class-Path(執行這個jar包時的ClassPath,第三方依賴)

Manifest-Version: 1.0 
Main-Class: test.Main 
Class-Path: ./ ./lib/commons-collections-3.2.jar ./lib/commons-lang-2.3.jar ./lib/commons-logging-1.1.jar 

打包的一般做法是掃描項目所依賴的包,按照規范拼接Class-Path的value值,寫入MF文件。但這種做法不夠靈活,框架通常會從MF文件獲取自定義信息,使用classloader動態加載依賴的jar包,並控制文件的合並,過濾等規則。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM