Spring Boot魔術背後的剖析
隨著微服務架構和雲端計算的出現,對工件部署的新方法的需求日益增長:獨立的Java應用程式。在很短的時間內, Spring Boot 已成為該領域的領先技術。其優勢包括:
- 有自己意見的觀點 - 這意味著它在你的位置做了很多工作;
- 一個非常快速的專案啟動:依賴關係按主題分組為所謂的“啟動器”
- 可執行jar:生成的工件是可執行的JAR(或更好的Uber JAR);
我對Spring Boot的看法
從我的角度來看,這是“控制反轉”實現的一個例子 - 通常,你選擇一組庫,然後嘗試將它們配置為一起工作,但在這種情況下,你將控制權交給了需要注意的框架配置。
應用程式啟動時,框架會檢測類路徑的依賴關係並嘗試對其進行配置。例如,當Spring Boot 在類路徑上檢測到 Hibernate jar時,它會為您配置資料來源,或者當找到Spring MVC jar時,它會配置Dispatcher Servlet。啟用自動配置非常簡單; 只需使用自動配置註釋您的主配置類,可以通過使用@SpringBootApplication或註釋您的主類來啟用@EnableAutoConfiguration。
自動配置應用程式所需的所有邏輯都由spring-boot-autoconfigure庫處理,該庫包含打包以執行特定配置邏輯的所有類。
此外,通過在類路徑上提供名為application.properties(或application.yaml)的檔案,實現了一種極端的“約定優於配置”方法來定製自動配置的幾乎每個方面。
在此檔案中,您可以將自動配置的特定方面控制為伺服器埠:
server.port=8090
並且,可排除特定類如下所示:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.
快速專案啟動
大多數情況下,要啟動Spring Boot專案,只需轉到start.spring.io,選擇要使用的技術,然後下載一個zip檔案,其專案結構為Maven或Gradle專案。
請注意,我寫的是“技術”,而不是“庫”;這是因為你可以說:“我想要一個帶有安全性和JPA的Web應用程式”,Spring將為您選擇合適的庫。
在我看來,最不平凡的事情不是啟動一個專案這麼容易的事實,而是Spring以如此優雅的方式完成它的方式。
我們的想法是將一組有用且集中的庫分組到一個多模組專案中,然後將其作為依賴項包含在內。
例如,當您選擇“Web”選項時,start.spring.io會新增:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
下面只是一個多模組專案,它收集執行包含嵌入式Tomcat的Web應用程式所需的所有庫:
<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </dependency>
這種方法最顯著的好處之一是您不必擔心庫版本相容性 - 啟動器將此作為保證。
可執行的Jar
將配置檢測和啟動器放在一起,唯一缺少的是分發更方便的方法。Spring Boot通過將整個專案打包為Uber JAR來解決這個問題。
Uber JAR是一個常規JAR,其中包含所需的所有依賴項。這是使用:
- spring-boot-maven-plugin:你可以在pom的外掛plugins部分找到它;
- maven-shade-plugin:它是spring-boot-starter-parent提供的,它創造了有效的Uber Jar。
特別是maven-shade-plugin負責打包依賴,並通過變換器配置 - 特定檔案,如:
- ManifestResourceTransformer將MANIFEST.MF處理到META-INF下;
- ServicesResourceTransformer將服務提供者配置檔案放入META-INFservices 下。
以下是與Spring Boot Loader相容的JAR結構的示例:
+-META-INF |+-MANIFEST.MF +-org |+-springframework |+-boot |+-loader |+- Main-Class +-BOOT-INF +-classes |+- Start-Class +-lib +-dependency.jar
為了使其可執行,使用以下屬性初始化META-INF\MANIFEST.MF檔案:
Main-Class: org.springframework.boot.loader.JarLauncher Start-Class: com.yourcompany.MainCOnfigurationCLass Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/
當應用程式啟動時 - 使用
java -jar application.jar
- META-INF\MANIFEST.MF被讀取。在這裡,org.springframework.boot.loader.JarLauncher作為主類載入 - 它的工作是載入以下內容:
- 將庫放入BOOT-INF/lib
- 將應用程式類放入BOOT-INFclasses。
BOOT-INF\classes包含啟動類- 一個帶註釋@SpringBootApplication的類實際上啟動並引導Spring應用程式。
結論
Spring Boot是一個完善架構的一個非凡例子:它完成特定任務,使用現代方法,並提出所有熱門話題的解決方案。
如果有人發現Spring Boot限制太多,那是因為它的功能在於其配置發現及其依賴關係的管理 - 這可能會迫使使用者失去控制權。例如,使用不同的父POM而不是spring-boot-starter-parent並不是一件容易的事。
在我看來,Spring Boot必須被視為一個框架,目標作為標準化的工具集合而不是實用程式庫。如果你不使用Spring Boot,您建立一個類似Spring Boot的應用程式(即本機雲Java應用程式)。
如果以這種方式思考,那麼您可以享受Spring Boot方式來做事並從中獲得最大收益!快樂的編碼!