我本地寫了一個rabbitmq fanout模式的demo。consumer啟動類和producer啟動類都放到了一個springboot程式里。本地調試通過。 突然有個疑問,springboot項目是怎麼來發現主啟動類的呢? 我們知道,預設使用maven打包時,是個普通的可供依賴的jar包,僅包含 ...
我本地寫了一個rabbitmq fanout模式的demo。consumer啟動類和producer啟動類都放到了一個springboot程式里。本地調試通過。
突然有個疑問,springboot項目是怎麼來發現主啟動類的呢?
我們知道,預設使用maven打包時,是個普通的可供依賴的jar包,僅包含來自項目源的資源和已編譯的Java類,並不能單獨運行。
鑒於上面的疑問,我在pom裡加上spring-boot-maven-plugins,讓這個項目作為一個springboot程式。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
這時,執行mvn package或mvn install命令時,發現報錯--無法從兩個候選的main程式類來選定一個作為主啟動類。具體錯誤信息如下:
Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.2.0.RELEASE:repackage (repackage) on project fanoutx: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.2.0.RELEASE:repackage failed: Unable to find a single main class from the following candidates [com.fanoutconsumer.FanoutConsumerApplication, com.fanoutproducer.FanoutProducerApplication]
這才知道,在這種情況下,需要使用configuration節點來指定主啟動類。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.fanoutconsumer.FanoutConsumerApplication</mainClass> </configuration> </plugin> </plugins> </build>
當然,話說回來,在企業應用中,我們通常也不會在一個springboot程式里寫兩個或多個啟動類(只會寫一個),所以也就不用顯式指定啟動類了。
springboot可執行程式包預設也是.jar。那麼,對於同一個springboot項目,打出來的普通可依賴jar與springboot可執行jar有什麼區別呢?
我們看兩種情況下的jar包里的文件結構及文件目錄
1)作為普通可依賴jar包的 fanoutx-1.0-SNAPSHOT.jar
fanoutx-1.0-SNAPSHOT.jar application.yml +com(項目已編譯類,.class文件) +META-INF MANIFEST.MF +maven +org.example +fanoutx pom.properties pom.xml
其中,META-INF/MANIFEST.MF內容為:
Manifest-Version: 1.0 Implementation-Title: fanoutx Implementation-Version: 1.0-SNAPSHOT Build-Jdk-Spec: 1.8 Created-By: Maven Archiver 3.4.0
2)作為springboot可執行jar包 的 fanoutx-1.0-SNAPSHOT.jar 是一個“胖jar”(有時稱為“fat jars”)
fanoutx-1.0-SNAPSHOT.jar +BOOT-INF +classes application.yml +com(項目已編譯類,.class文件) +lib (項目依賴的lib包) +META-INF MANIFEST.MF +maven +org.example +fanoutx pom.properties pom.xml +org +springframework +boot +loader +archive +data ExecutableArchiveLauncher.class +jar JarLauncher.class LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class LaunchedURLClassLoader.class Launcher.class MainMethodRunner.class PropertiesLauncher$1.class PropertiesLauncher$ArchiveEntryFilter.class PropertiesLauncher$PrefixMatchingArchiveFilter.class PropertiesLauncher.class +util WarLauncher.class
其中,META-INF/MANIFEST.MF內容為:
Manifest-Version: 1.0 Implementation-Title: fanoutx Implementation-Version: 1.0-SNAPSHOT Start-Class: com.fanoutconsumer.FanoutConsumerApplication Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Build-Jdk-Spec: 1.8 Spring-Boot-Version: 2.2.0.RELEASE Created-By: Maven Archiver 3.4.0 Main-Class: org.springframework.boot.loader.JarLauncher
可見,主要是有個 BOOT-INF ,還有 org/springframework/boot/loader/ 。---------->不僅具有來自項目的已編譯Java類,還包括代碼需要運行的所有 jar 依賴項,而且還具有啟動Spring Boot應用程式所需的所有運行時庫。
另外還可以看到,兩者的 META-INF/MANIFEST.MF 文件里的內容不同,可執行jar里定義了Jarlauncher 及 Start-Class。
BTW,兩者里,pom.xml內容與原始的pom.xml相同。pom.properties定義了artifact
version=1.0-SNAPSHOT groupId=org.example artifactId=fanoutx
【the end】
ref1:Maven-build之spring-boot-maven-plugin
ref2:baidu:Jarlauncher的實現原理
ref3:baidu:Springboot 創建可執行 Jar
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請註明原文鏈接:https://www.cnblogs.com/buguge/p/16373686.html