Spring Boot 的那些事兒

Spring Boot 是個什么東西苹威?官方給出的解釋是Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring. Spring Boot takes an opinionated view of building production-ready applications. 解釋下來就是Spring Boot 是為了快速的啟動且最小化配置Spring應用而設計的。Spring Boot 采用固化視圖來構建生產(chǎn)級別應用圾旨。 這是官網(wǎng)首頁最顯眼的地方擺出的兩句話季稳,當然官網(wǎng)推崇Spring Boot 遠不止這兩句話,下面還來了句更狠的Spring Boot is the starting point for building all Spring-based applications. 這句話有多狠呢?Spring Boot 是都有基于Spring 構建的應用的起點狰住,可見Spring 官方為了推出Spring Boot的決心。

Spring Boot 的特點

下面是官網(wǎng)列出的9個特點齿梁,我們逐一了解下

  • Get started in seconds using Spring Initializr
    使用Spring Initializr 幾秒的時間就可以啟動催植。我個人的理解是在https://start.spring.io/網(wǎng)址花幾秒鐘的時間就可以構建一個Spring Boot 項目,剛好這個網(wǎng)頁的title就叫Spring Initializr勺择。

    Spring Initializr

  • Build anything: REST API, WebSocket, web, streaming, tasks, and more
    可以用來構建任何東西如: REST API创南,WebSocket, web, streaming, tasks 這個我們以后探討。

  • Simplified security
    簡化了安全框架省核,這個比較明確了稿辙,需要實踐發(fā)現(xiàn)如何簡化。

  • Rich support for SQL and NoSQL
    良好的支持了SQL和NoSQL

  • Embedded runtime support: Tomcat, Jetty, and Undertow
    嵌入式運行時容器:Tomcat, Jetty, and Undertow气忠,實際上Spring Boot2.0 加入的Web Flux 默認采用的是Netty容器邻储,當然這個后面討論吧赋咽。

  • Developer productivity tools such as LiveReload and Auto Restart
    開發(fā)者的生產(chǎn)工具如LiveReload 和 Auto Restart

  • Curated dependencies that just work
    更加精簡的依賴

  • Production-ready features such as tracing, metrics, and health status
    提供為生產(chǎn)環(huán)境準備的功能如:跟蹤、度量和運行狀態(tài)

  • Works in your favorite IDE: Spring Tool Suite, IntelliJ IDEA, and NetBeans
    可以在你喜歡的IDE上工作如Spring Tool Suite, IntelliJ IDEA, and NetBeans吨娜,好吧脓匿,我現(xiàn)在用得就是IntelliJ IDEA

說了那么多特點,直接開干就知道了

Spring Initializr直接點generate project 生成項目宦赠,存放到本地陪毡,解壓,目錄如下

demo
    │  .gitignore
    │  HELP.md
    │  mvnw
    │  mvnw.cmd
    │  pom.xml
    │  
    ├─.mvn
    │  └─wrapper
    │          maven-wrapper.jar
    │          maven-wrapper.properties
    │          MavenWrapperDownloader.java
    │          
    └─src
        ├─main
        │  ├─java
        │  │  └─com
        │  │      └─example
        │  │          └─demo
        │  │                  DemoApplication.java
        │  │                  
        │  └─resources
        │          application.properties
        │          
        └─test
            └─java
                └─com
                    └─example
                        └─demo
                                DemoApplicationTests.java

windows 下面列出文件目錄的指令時tree勾扭,將文件和目錄一起列出是tree /f ,輸出到文件中使用tree /f > list.txt

.gitignore 文件存放的是一些流行的IDE的元信息如STS,IntelliJ IDEA,NetBeans,VS Code
mvnw.cmd 文件配置的是一些maven信息毡琉,我們知道Spring Boot 要求使用Maven3.0以上的版本構建,但是有了這個文件后尺借,我們甚至在本機中沒有安裝Maven也能采Maven來構建項目
pom.xml文件绊起,依賴配置文件,這里我們采用的Spring Boot 版本是org.springframework.boot:spring-boot-starter-parent:2.2.0.M2
DemoApplication.java 啟動類

  • 編譯啟動項目
    進入到pom.xml同級目錄使用mvn spring-boot:run 或者mvnw.cmd spring-boot:run啟動項目燎斩,程序就會自動去下載依賴包和編譯虱歪,是不是很方便。

由于國內(nèi)環(huán)境下載速度太慢栅表,推薦使用mvn spring-boot:run ,然后我們對本地的maven配置上阿里云鏡像 修改settings.xml文件修改
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>

編譯啟動

這個時候笋鄙,程序直接退出了,主要原因是沒有嵌入式web容器怪瓶,就是說剛才啟動的就是一個普通的Java項目萧落,執(zhí)行完后就退出了。我們添加依賴org.springframework.boot:spring-boot-starter-web 再啟動洗贰,這個時候我們就可以去訪問http://localhost:8080/ 返回404找岖,當然,我們沒有配置信息敛滋,至少可以確定许布,服務器已經(jīng)啟動了。

  • 打包
    剛才已經(jīng)說過了绎晃,我們可以采用mvn spring-boot:run 指令來啟動項目蜜唾,而我們線上環(huán)境當然不能那么草率的啟動,還是需要jar包或者war包的形式的庶艾。我們知道m(xù)aven的打包指令時mvn package 袁余。那么我們直接試試吧。


    打包

    打包成功咱揍,生成了兩個文件16.3M的demo-0.0.1-SNAPSHOT.jar和2.75K的demo-0.0.1-SNAPSHOT.jar.original颖榜。
    我們再試試打war包,修改pom的packaging為war。執(zhí)行mvn clean package朱转。如果嫌測試麻煩加上-Dmaven.test.skip=true,打包成功蟹地,同樣生成demo-0.0.1-SNAPSHOT.war和demo-0.0.1-SNAPSHOT.war.original积暖,這樣我們就可以用java -jar 的指令來啟動了藤为。

  • 分析包
    解壓下demo-0.0.1-SNAPSHOT.jar ,包的目錄如下
├─BOOT-INF
│  ├─classes
│  │  └─com
│  │      └─example
│  │          └─demo
│  └─lib
├─META-INF
│  └─maven
│      └─com.example
│          └─demo
└─org
    └─springframework
        └─boot
            └─loader
                ├─archive
                ├─data
                ├─jar
                └─util

我們發(fā)現(xiàn)BOOT-INF目錄下面有classes目錄和lib目錄夺刑,這個是不是感覺似曾相識缅疟?沒錯,就是WEB-INF目錄嘛遍愿,當然存淫,web.xml是不存在的。這么看來沼填,classes我們理解成我們寫的Java代碼編譯目錄桅咆,lib為依賴jar包,這就是個web項目嘛坞笙。我們大膽猜測下岩饼,Spring Boot其實就是模擬的一個JavaEE項目。
我們再看下jar包的元信息薛夜,META-INF/MANIFEST.MF

Manifest-Version: 1.0
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: DELL
Implementation-Vendor-Id: com.example
Spring-Boot-Version: 2.2.0.M2
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.2
Build-Jdk: 1.8.0_141
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
 ot-starter-parent/demo

我們知道java -jar 指令程序的入口是Main-Class籍茧。這個文件中的Main-Class 是JarLauncher,并不是我們的啟動類DemoApplication梯澜,我們猜想下寞冯,使用java JarLauncher 命令是不是也能啟動項目。驗證了下晚伙,發(fā)現(xiàn)真的可以啟動項目吮龄。


image.png

我們假設下jar包里面org目錄下為Tomcat容器,那么通過啟動Tomcat容器來啟動我們的Spring Boot 項目咆疗,那么這一切就解釋的通了(ps 個人看法)

理解嵌入式Web容器

首先我們將demo項目導入到IDEA中漓帚,然后查看下IDEA下的maven依賴如下圖:


image.png

我們看到spring-boot-starter-web下面有spring-boot-stater-tomcat的依賴,所以容器默認使用tomcat民傻。如果我們要用Jetty或者Undertow呢胰默?我們以Undertow為例,修改pom.xml文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

再次啟動項目


image.png

什么鬼漓踢,不生效牵署。
根據(jù)上面的依賴關系,我們知道spring-boot-starter-web內(nèi)部有了tomcat的依賴喧半,如果我們不移出的話奴迅,依舊會使用tomcat作為容器,那么我們就需要修改spring-boot-satrter-web依賴了

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

重啟下項目


image.png

這個時候就使用了Undertow作為web容器了。

從pom.xml為入口再談編譯

首先取具,Spring 文檔中提到了一個Executable Jar的概念脖隶,也稱為fat jars。就是說將我們的Spring Boot 項目打成一個可執(zhí)行的jar包暇检,那么如何打包呢产阱?

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

我們可以通過spring-boot-maven-plugin插件將我們的項目打成可執(zhí)行jar包。這就完事了块仆?當然不可能构蹬,我們看下這句話If you do not use the parent POM, you need to declare this configuration yourself. 就是說,我們不是以spring-boot-starter-parent 作為parent的話悔据,需要自己聲明配置庄敛。
那么問題來了,如何不以spring-boot-starter-parent為parent構建Spring Boot 項目呢科汗?

  • 搭建不以spring-boot-starter-parent為parent 的Spring Boot 項目
    為了演示方便藻烤,我們修改下啟動類DemoApplication.java,將訪問http://localhost:8080/ 返回字符串头滔,而不再是報404錯誤怖亭。
@RestController
@SpringBootApplication
public class DemoApplication {
    @RequestMapping("/")
    public String hello(){
        return "hello spring boot";
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

我們再將pom.xml的parent注釋掉,然后修改spring-boot-starter-web的依賴拙毫,添加版本號

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>

我們執(zhí)行下mvn spring-boot:run 我們發(fā)現(xiàn)依许,啟動時成功的,訪問下http://localhost:8080/

image.png

返回也沒有問題缀蹄,那么說是不是我們的項目搭建成功了呢峭跳?別急,打包試試缺前。篇幅有限蛀醉,我這里不截圖了,打包也是成功的衅码,包是demo-0.0.1-SNAPSHOT.jar拯刁,但是我們發(fā)現(xiàn)一個問題,這個包只有3K逝段,肯定不是fat jars垛玻。
我們翻看下官方文檔的 Using Spring Boot without the Parent POM章節(jié),說的是需要添加dependencyManagement依賴奶躯,好吧帚桩,我們試試。再次maven clean package 發(fā)現(xiàn)沒什么卵用嘹黔,還是打的3K的jar包账嚎,看來問題不是這個,我們再試試其他辦法。(其實dependencyManagement是為了約定spring boot 的版本郭蕉,我們使用了spring-boot-starter-web:2.1.4.RELEASE 指定好了版本號加不加入影響不大)
我們猜想應該是maven插件的問題了疼邀,修改下pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.4.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

repackage描述: create a jar or war file that is auto-executable. It can replace the regular artifact or can be attached to the build lifecycle with a separate classifier. 好吧,這句話就是說創(chuàng)建fat jars召锈,我們加入后旁振,發(fā)現(xiàn)打包后和parent效果是一樣的。至于為什么使用parent后不需要repackage就能生成fat jars烟勋,這個我就不知道了规求,希望大家?guī)兔獯鹣隆?/p>

之前的依賴發(fā)現(xiàn)使用的是2.2.0.M2版本,由于這個是里程碑版本卵惦,pom中需要加入一些依賴信息,我們?yōu)榱朔奖汩喿x瓦戚,之后采取2.1.4.RELEASE版本沮尿。剛好,官方的最新文檔也是這個版本较解。

未完畜疾,待續(xù)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市印衔,隨后出現(xiàn)的幾起案子啡捶,更是在濱河造成了極大的恐慌,老刑警劉巖奸焙,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞎暑,死亡現(xiàn)場離奇詭異,居然都是意外死亡与帆,警方通過查閱死者的電腦和手機了赌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玄糟,“玉大人勿她,你說我怎么就攤上這事≌篝幔” “怎么了逢并?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長郭卫。 經(jīng)常有香客問我砍聊,道長,這世上最難降的妖魔是什么箱沦? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任辩恼,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘灶伊。我一直安慰自己疆前,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布聘萨。 她就那樣靜靜地躺著竹椒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪米辐。 梳的紋絲不亂的頭發(fā)上胸完,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音翘贮,去河邊找鬼赊窥。 笑死,一個胖子當著我的面吹牛狸页,可吹牛的內(nèi)容都是我干的锨能。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼芍耘,長吁一口氣:“原來是場噩夢啊……” “哼址遇!你這毒婦竟也來了?” 一聲冷哼從身側響起斋竞,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤倔约,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坝初,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浸剩,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年脖卖,在試婚紗的時候發(fā)現(xiàn)自己被綠了乒省。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡畦木,死狀恐怖袖扛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情十籍,我是刑警寧澤蛆封,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站勾栗,受9級特大地震影響惨篱,放射性物質發(fā)生泄漏。R本人自食惡果不足惜围俘,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一砸讳、第九天 我趴在偏房一處隱蔽的房頂上張望琢融。 院中可真熱鬧,春花似錦簿寂、人聲如沸漾抬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纳令。三九已至,卻和暖如春克胳,著一層夾襖步出監(jiān)牢的瞬間平绩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工漠另, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捏雌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓酗钞,卻偏偏與公主長得像腹忽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砚作,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356