springmvc遷移springboot之路2

1、常規(guī)springmvc的流程

1.1springmvc的啟動過程

首先,對于一個web應(yīng)用,其部署在web容器中保屯,web容器提供其一個全局的上下文環(huán)境,這個上下文就是ServletContext涤垫,其為后面的spring IoC容器提供宿主環(huán)境姑尺;

其次,在web.xml中會提供有contextLoaderListener蝠猬。在web容器啟動時切蟋,會觸發(fā)容器初始化事件,此時contextLoaderListener會監(jiān)聽到這個事件吱雏,其contextInitialized方法會被調(diào)用敦姻,在這個方法中,spring會初始化一個啟動上下文歧杏,這個上下文被稱為根上下文,即WebApplicationContext迷守,這是一個接口類犬绒,確切的說,其實際的實現(xiàn)類是XmlWebApplicationContext兑凿。這個就是spring的IoC容器凯力,其對應(yīng)的Bean定義的配置由web.xml中的context-param標(biāo)簽指定。在這個IoC容器初始化完畢后礼华,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE為屬性Key咐鹤,將其存儲到ServletContext中,便于獲仁バ酢祈惶;

再次,contextLoaderListener監(jiān)聽器初始化完畢后,開始初始化web.xml中配置的Servlet捧请,這個servlet可以配置多個凡涩,以最常見的DispatcherServlet為例,這個servlet實際上是一個標(biāo)準(zhǔn)的前端控制器疹蛉,用以轉(zhuǎn)發(fā)活箕、匹配、處理每個servlet請求可款。DispatcherServlet上下文在初始化的時候會建立自己的IoC上下文育韩,用以持有spring mvc相關(guān)的bean。在建立DispatcherServlet自己的IoC上下文時闺鲸,會利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先從ServletContext中獲取之前的根上下文(即WebApplicationContext)作為自己上下文的parent上下文座慰。有了這個parent上下文之后,再初始化自己持有的上下文翠拣。這個DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到版仔,大概的工作就是初始化處理器映射、視圖解析等误墓。這個servlet自己持有的上下文默認實現(xiàn)類也是mlWebApplicationContext蛮粮。初始化完畢后,spring以與servlet的名字相關(guān)(此處不是簡單的以servlet名為Key谜慌,而是通過一些轉(zhuǎn)換然想,具體可自行查看源碼)的屬性為屬性Key,也將其存到ServletContext中欣范,以便后續(xù)使用变泄。這樣每個servlet就持有自己的上下文,即擁有自己獨立的bean空間恼琼,同時各個servlet共享相同的bean妨蛹,即根上下文(第2步中初始化的上下文)定義的那些bean。

1.2spring mvc工作流程圖

Spring工作流程描述

1.用戶向服務(wù)器發(fā)送請求晴竞,請求被Spring前端控制Servelt DispatcherServlet捕獲蛙卤;

2.?DispatcherServlet對請求URL進行解析,得到請求資源標(biāo)識符(URI)噩死。然后根據(jù)該URI颤难,調(diào)用HandlerMapping獲得該Handler配置的所有相關(guān)的對象(包括Handler對象以及Handler對象對應(yīng)的攔截器),最后以HandlerExecutionChain對象的形式返回已维;

3.?DispatcherServlet根據(jù)獲得的Handler行嗤,選擇一個合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后垛耳,此時將開始執(zhí)行攔截器的preHandler(...)方法)

4.提取Request中的模型數(shù)據(jù)栅屏,填充Handler入?yún)⑵В_始執(zhí)行Handler(Controller)。 在填充Handler的入?yún)⑦^程中既琴,根據(jù)你的配置占婉,Spring將幫你做一些額外的工作:

HttpMessageConveter:將請求消息(如Json、xml等數(shù)據(jù))轉(zhuǎn)換成一個對象甫恩,將對象轉(zhuǎn)換為指定的響應(yīng)信息

數(shù)據(jù)轉(zhuǎn)換:對請求消息進行數(shù)據(jù)轉(zhuǎn)換逆济。如String轉(zhuǎn)換成Integer、Double等

數(shù)據(jù)根式化:對請求消息進行數(shù)據(jù)格式化磺箕。如將字符串轉(zhuǎn)換成格式化數(shù)字或格式化日期等奖慌;

數(shù)據(jù)驗證: 驗證數(shù)據(jù)的有效性(長度、格式等)松靡,驗證結(jié)果存儲到BindingResult或Error中简僧;

5. ?Handler執(zhí)行完成后,向DispatcherServlet返回一個ModelAndView對象雕欺;

6.根據(jù)返回的ModelAndView岛马,選擇一個適合的ViewResolver(必須是已經(jīng)注冊到Spring容器中的ViewResolver)返回給DispatcherServlet;

7.?ViewResolver結(jié)合Model和View屠列,來渲染視圖

8.將渲染結(jié)果返回給客戶端啦逆。

2springboot搭建

2.1選取ide工具

下圖是spring官網(wǎng)提供的ide工具

要創(chuàng)建springboot項目可以下載spring官網(wǎng)提供的sts這款I(lǐng)DE笛洛,自動集成了創(chuàng)建boot項目所需的插件,當(dāng)然對使用eclipse的開發(fā)者也可以安裝對應(yīng)系統(tǒng)的插件進行構(gòu)建boot項目沟蔑。

2.2創(chuàng)建項目

File> New > Spring Starter Project

Next> Finish

項目創(chuàng)建完成:

可以看出瘦材,項目源碼就一個Java類,在pom.xml中有spring-boot-starter-web的依賴宇色。

SpringBootSampleApplication.java

packageorg.springboot.sample;

importorg.springframework.boot.SpringApplication;

importorg.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

publicclass SpringBootSampleApplication {

public static void main(String[] args) {

SpringApplication.run(SpringBootSampleApplication.class,args);

}

}

pom.xml


4.0.0

org.springboot.sample

spring-boot-sample

0.0.1-SNAPSHOT

jar

spring-boot-sample

Spring Boot Sample WebApplication

org.springframework.boot

spring-boot-starter-parent

1.3.1.RELEASE


UTF-8

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

這樣就完成了項目的創(chuàng)建颁湖,下面我們創(chuàng)建一個HelloController.java定義3個方法

packageorg.springboot.sample.controller;

importjava.util.ArrayList;

importjava.util.HashMap;

importjava.util.List;

importjava.util.Map;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.RequestParam;

importorg.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/hello")

publicclass HelloController {

@RequestMapping

public String hello() {

return "Hello Spring-Boot";

}

@RequestMapping("/info")

public Map getInfo(@RequestParamString name) {

Map map = newHashMap<>();

map.put("name", name);

return map;

}

@RequestMapping("/list")

public List>getList() {

List> list= new ArrayList<>();

Map map = null;

for (int i = 1; i <= 5; i++) {

map = new HashMap<>();

map.put("name", "Shanhy-"+ i);

list.add(map);

}

return list;

}

}

然后現(xiàn)在可以直接運行SpringBootSampleApplication的main方法例隆,和執(zhí)行普通java程序一樣。

然后可以看到spring-boot內(nèi)置server容器(默認為Tomcat)镰禾,這一切spring-boot都幫我們做好了皿曲。

控制臺輸出內(nèi)容Started SpringBootSampleApplication in 7.358 seconds (JVM running

for 9.154)表示服務(wù)已經(jīng)啟動。

在瀏覽器輸入我們3個請求便可看到結(jié)果吴侦。http://localhost:8080/hello

輸出:HelloSpring-Boothttp://localhost:8080/hello/info?name=shanhy

輸出:{“name”:”shanhy”}http://localhost:8080/hello/list

輸出:[{“name”:”Shanhy-1”},{“name”:”Shanhy-2”},{“name”:”Shanhy-3”},{“name”:”Shanhy-4”},{“name”:”Shanhy-5”}]

通過我們的Hello實例屋休,相信大家一目了然,可謂spring-boot創(chuàng)建一個項目如此簡單备韧,完全可以在幾分鐘內(nèi)將服務(wù)啟動劫樟。spring-boot拋棄繁瑣的配置,讓開發(fā)人員更專注與業(yè)務(wù)邏輯的實現(xiàn)织堂。后面幾篇文章將會對spring-boot的多個方面通過實例的方式呈現(xiàn)給大家叠艳。

3springboot的運行原理

系統(tǒng)啟動類視圖如下:

可以發(fā)現(xiàn)啟動類有個@SpringBootApplication注解,這是一個組合注解易阳,結(jié)構(gòu)如下圖:

@SpringBootApplication注解的功能主要由@ EnableAutoCongiguration附较、@componentScan組成。

@EnableAutoCongiguration負責(zé)啟動自動配置功能潦俺,在main方法中的SpringApplication啟動的方法中拒课,如下圖:

在SpringApplication啟動時,依據(jù)@ EnableAutoCongiguration設(shè)定的自動配置功能事示,有一部分功能是去掃描maven內(nèi)所有jar包下的spring.factories文件早像,構(gòu)建成一個配置文件鏈表,如果系統(tǒng)有引用很魂,則根據(jù)條件注解去初始化bean扎酷,例如:

@componentScan負責(zé)掃描啟動類所在package下子package的所有需要實例化的bean的IOC,比如@controller遏匆、@service法挨、@Component、@Configuration幅聘、@bean等凡纳。

boot提供了默認的配置文件:application.xml,集成了各類starter服務(wù)的配置屬性定制化帝蒿,簡單舉幾個例子:

日志配置

web服務(wù)器配置

模板配置

http編碼、json和微服務(wù)配置

mvc交互配置

認證配置

還有spring.data.*和spring.datasource.*的異構(gòu)數(shù)據(jù)源的配置等等,具體詳情參考

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

4springmvc遷移springboot

4.1零配置

常規(guī)springmvc的整體結(jié)構(gòu)如下圖:


springboot的整體結(jié)構(gòu)如下圖:


綜合對比答渔,springmvc要遷移springboot沼撕,首當(dāng)其中的就是springboot是如何去XML(web.xml和applicationcontext.xml)的务豺。

去web.xml:依賴內(nèi)置web服務(wù)器啟動初始化應(yīng)用的上下文笼沥;

去applicationcontext.xml:依賴java注解和條件注解技術(shù)敬拓,使用自動配置功能實現(xiàn)。

4.2web.xml

對于一些springboot

application.xml中沒有的服務(wù)厕诡,有三種解決方式:

1灵嫌、自定義starter pom

2寿羞、原始方式自己編寫服務(wù)

3绪穆、原始引用XML

對于springboot服務(wù)不好用玖院,想進行變更的第岖,boot設(shè)計中為它的任何一個服務(wù)都提供了可擴展性的方式進行變更蔑滓,比如如何解決web.xml內(nèi)配置的filter键袱、Listener蹄咖、Interceptor等,可通過注解方式(比如@Component比藻、@Configuration)自行擴展對應(yīng)的服務(wù)银亲。

5樣例

5.1pom文件配置


5.2application.xml配置

環(huán)境分流配置

開啟shutdown功能

配置內(nèi)容

5.3平滑升級


6總結(jié)

使用springboot馏段,首選需要判斷boot是否提供了服務(wù)院喜,boot有一些服務(wù)是自動配置加載的,有一些服務(wù)是需要enable*打開才能用的砍濒,比如定時@EnableScheduling硫麻、異步@EnableAsync服務(wù)等拿愧,如果boot目前還無法定制某項目的個性化服務(wù),可自行擴展券敌,擴展方式參考4.2小節(jié)描述內(nèi)容陪白。

對于jar包版本一致性問題也是同理咱士,先判斷boot是否提供了對應(yīng)的jar服務(wù)序厉,決定是否需要自行擴展弛房。

springboot可以導(dǎo)出jar包也可以導(dǎo)出war包文捶,war包基本依賴外部應(yīng)用服務(wù)器,可以利用外部應(yīng)用服務(wù)器的shutdown功能平滑升級种远。但jar包形式依賴linux sh腳本的運行坠敷,基本都會使用kill去暴力殺線程膝迎,這是會影響線上業(yè)務(wù)的胰耗,所以為了保證線上線程不會突然崩潰影響業(yè)務(wù)宪郊,sringboot也考慮了這一點,在監(jiān)控Actuator中提供了優(yōu)雅的shutdown功能懊亡,只要我們在sh腳本中訪問線上服務(wù)的shutdown地址店枣,即可優(yōu)雅的關(guān)閉線上服務(wù)鸯两,平滑升級了钧唐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钝侠,一起剝皮案震驚了整個濱河市帅韧,隨后出現(xiàn)的幾起案子忽舟,更是在濱河造成了極大的恐慌刁品,老刑警劉巖帘饶,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件及刻,死亡現(xiàn)場離奇詭異缴饭,居然都是意外死亡颗搂,警方通過查閱死者的電腦和手機丢氢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仇奶,“玉大人该溯,你說我怎么就攤上這事狈茉÷惹欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長粒督。 經(jīng)常有香客問我,道長族跛,這世上最難降的妖魔是什么礁哄? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任桐绒,我火速辦了婚禮茉继,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菲茬。我一直安慰自己婉弹,他們只是感情好镀赌,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布佩脊。 她就那樣靜靜地躺著威彰,像睡著了一般歇盼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豹缀,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音侍匙,去河邊找鬼。 笑死帘不,一個胖子當(dāng)著我的面吹牛寞焙,可吹牛的內(nèi)容都是我干的捣郊。 我是一名探鬼主播擒悬,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尊勿!你這毒婦竟也來了躯保?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尸变,沒想到半個月后减俏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娃承,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡历筝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年梳猪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碟婆。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡蝙叛,死狀恐怖借帘,靈堂內(nèi)的尸體忽然破棺而出肺然,到底是詐尸還是另有隱情际起,我是刑警寧澤吐葱,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布灾前,位于F島的核電站哎甲,受9級特大地震影響炭玫,放射性物質(zhì)發(fā)生泄漏础嫡。R本人自食惡果不足惜榴鼎,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一巫财、第九天 我趴在偏房一處隱蔽的房頂上張望平项。 院中可真熱鬧,春花似錦接癌、人聲如沸缺猛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荔燎。三九已至,卻和暖如春销钝,著一層夾襖步出監(jiān)牢的瞬間有咨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工蒸健, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留座享,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓似忧,卻偏偏與公主長得像征讲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子癣籽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容