日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

maven springboot 除去指定的jar包_SpringBoot的运行机制

發布時間:2023/12/10 javascript 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 maven springboot 除去指定的jar包_SpringBoot的运行机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringBoot打包機制

先看一眼spring-boot的maven插件打包后的target目錄:

其中有一個.jar.original的文件,一個.jar文件,其中.jar.original才是原始的jar包,而.jar文件是經過spring-boot的maven插件處理過后的jar,springboot的maven插件會將原始jar重命名成.jar.original,然后按springboot自己的規范打出一個可執行的jar包。

將該jar包重命名成.zip文件后打開即可看到文件中的內容:

可以看到,springboot執行的jar并不是一個java標準的jar,其中包含了springboot自身定義的內容。我們再打開其中的META-INF/MANIFEST.MF文件,看看其中指定的內容:

Main-Class是其中的啟動類,springboot打包出來的jar,啟動類并不是工程中包含main方法的啟動類,而是springboot自己的JarLauncher類,而工程中定義的啟動類在這里變成了Start-Class,由此也可以看出springboot應用在IDE里通過main方法運行與通過java -jar命令運行的區別。

SpringBoot應用的啟動

打開springboot的Main-Class JarLauncher類,其中包含main方法:

這是springboot啟動的入口,JarLauncher類繼承自ExecutableArchiveLauncher類,進入到launch方法可以看到springboot有一個archive的概念,archive是歸檔的意思,springboot打出來的jar包就是一個archive。

ExecutableArchiveLauncher類的createArchive方法可以看到啟動時的archive創建,通過當前類找到jar包的路徑,并創建JarFileArchive:

通過getNestedArchives方法可以看到Archive是一個遞歸的概念,JarFileArchive中可以有其它嵌套的Archive:

在launch方法中,有getClassPathArchives方法的調用,此方法中調用了前面的getNestedArchives方法,傳入的Filter是lambda表達式,通過isNestedArchive方法對JarFileArchive中的Entry做過濾:

可以得知,springboot打出的archive jar包中,ROOT-INF/classes/目錄被認為是一個嵌套的Archive,ROOT-INF/lib/下的每一個jar包也被認為是一個Archive

因為springboot的archive不是一個標準的jar包,java提供的ClassLoader無法加載到archive中的依賴以及class,springboot提供了新的classloader的實現用來做Archive中類的加載:

可以看到springboot使用的是LaunchedURLClassLoader這個ClassLoader做的類的加載。創建好類加載器后,需要調用Start-Class,即應用中的main方法:

MainMethodRunner.run方法非常簡單,邏輯是通過反射調用應用的main:

這一步之后,進入到了應用代碼中。

SpringBoot應用初始化

在使用spring boot時,我們在main方法中調用SpringApplication.run進行初始化:

在SpringApplication.run方法中做了Spring的初始化:

可以清晰的看到spring的初始化。創建ApplicationContext對象使用的是createApplicationContext方法,此方法實現如下:

對于非WEB應用,使用的ApplicationContext的實例是DEFAULT_CONTEXT_CLASS,此常用定義為AnnotationConfigApplicationContext類,在依賴注入中提到的這個類,此類用于實現注解配置的ApplicationContext。

回到啟動類,啟動類上加了一個@SpringBootApplication注解,此注解的定義:

前面Annotation的解析機制中提到,spring能通過解析@ComponentScan注解注冊bean,但是springboot中,@ComponentScan標識在SpringBootApplication注解上,AnnotationConfigApplicationContext是定義在spring-context包中的,而@SpringBootApplication是定義在spring-boot-autoconfig中的注解,spring-context包并不依賴于spring-boot-autoconfig包,AnnotationConfigApplicationContext能通過@SpringBootApplication注解完成初始化是因為spring的注解處理工具類能識別出@SpringBootApplication的元注解@ComponentScan以及@AliasFor注解標識 的屬性,實現邏輯在spring-core包中的AnnotationConfigUtils類中。

最后看看SpringApplication類的構造器:

在getSpringFactoriesInstances方法中,使用了SpringFactoriesLoader:

打開spring-boot相關的包,能看到spring.factories文件:

SpringFactoriesLoader是spring-core中提供的類,用于處理spring.factories文件,SpringFactoriesLoader.loadFactoryNames方法會讀取類路徑下的所有META-INF/spring.factories文件:

AutoConfiguration

回到@SpringBootApplication注解的定義:

其注解上被標記了@EnableAutoConfiguration注解,此注解用于實現autoconfiguration。打開此注解可以看到它實際上是使用了注解解析機制中的@Import注解:

如何使用ImportSelector就回到了@Import的處理邏輯中(見前面的文章)??梢钥吹?#xff0c;實現autoconfiguration的入口正是這個EnableAutoConfigurationImportSelector類,此類的selectImports方法返回的是需要作為配置類的類,這里的具體作用就是拿到類路徑下的所有的自動配置的類,其代碼實現:

AutoConfigurationMetadataLoader.loadMetadata方法的實現比較簡單

即從META-INF/spring-autoconfigure-metadata.properties文件中加載數據,此文件在classpath下可以有多個(每個jar包中都可以有一個),隨便打開一個配置文件,看看其中的內容:

里面都是一些配置類。@Import將這些配置類導入給spring的注解處理器ConfigurationClassParser就完成了bean的配置。

另外,在@SpringBootApplication注解上,還標記了一個@ComponentScan注解,其中的excludeFilters中有一個是AutoConfigurationExcludeFilter:

此類會判斷如果class標了@Configuration并且此類包含spring.factories文件中,則在處理@Configuration注解時排除此類:

上面的代碼中,getAutoConfigurations方法是從SpringFactoriesLoader中取的EnableAutoConfiguration關聯的類。

總結

以上是生活随笔為你收集整理的maven springboot 除去指定的jar包_SpringBoot的运行机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。