Spring,Spring MVC及Spring Boot區(qū)別

對于一個Java開發(fā)者來說,Spring可謂如雷貫耳,無論是Spring框架,還是Spring引領(lǐng)的IOC,AOP風(fēng)格,都對后續(xù)Java開發(fā)產(chǎn)生的深遠(yuǎn)的影響,同時,Spring社區(qū)總能及時響應(yīng)開發(fā)者的需求,推出適應(yīng)潮流發(fā)展的新功能特定;而對于大部分開發(fā)者而言,平時接觸最多的應(yīng)該就是Spring MVC以及Spring Boot了,本文將分別對Spring,Spring MVC以及Spring Boot做總體概述,并分析闡述它們各自想要解決的問題,以便初學(xué)者能更好的了解Spring及相關(guān)概念

本篇結(jié)構(gòu)

本篇將大致分為下列四個部分

  • 什么是Spring?它解決了什么問題?
  • 什么是Spring MVC?它解決了什么問題?
  • 什么是Spring Boot?它解決了什么問題?
  • Spring,Spring MVC,Spring Boot 三者比較

什么是Spring?它解決了什么問題?

我們說到Spring,一般指代的是Spring Framework,它是一個開源的應(yīng)用程序框架,提供了一個簡易的開發(fā)方式,通過這種開發(fā)方式,將避免那些可能致使代碼變得繁雜混亂的大量的業(yè)務(wù)/工具對象,說的更通俗一點就是由框架來幫你管理這些對象,包括它的創(chuàng)建,銷毀等,比如基于Spring的項目里經(jīng)常能看到的Bean,它代表的就是由Spring管轄的對象。

而在被管理對象與業(yè)務(wù)邏輯之間,Spring通過IOC(控制反轉(zhuǎn))架起使用的橋梁,IOC也可以看做Spring最核心最重要的思想,通過IOC能帶來什么好處呢?首先來看一個實際開發(fā)中的典型應(yīng)用場景,假設(shè)我們有一個基于MVC分層結(jié)構(gòu)的應(yīng)用,通過controller層對外提供接口,而通過service層提供具體的實現(xiàn),在service層中有一個WelcomeService服務(wù)接口,一般情況下都是通過WelcomeService service = new WelcomeServiceImpl();創(chuàng)建實例并進(jìn)行調(diào)用:

public class WelcomeController {
    private WelcomeService service = new WelcomeServiceImpl();

    @RequestMapping("/welcome")
    public String welcome() {
    return service.retrieveWelcomeMessage();
    }
}

調(diào)用后發(fā)現(xiàn)一切正常,此時,功能提交,需要進(jìn)行測試,而由于實際應(yīng)用環(huán)境與測試環(huán)境有所區(qū)別,需要替換WelcomeServiceImpl為一個MockWelcomeServiceImpl,以方便測試,怎么辦?沒有其他辦法,只有改代碼:

public class WelcomeController {
    private WelcomeService service = new MockWelcomeServiceImpl();

    ...
}

測試OK后再將代碼改回去,這種方式太過于繁瑣,且對代碼的侵入性很強(qiáng);
下面看通過Spring的IOC如何實現(xiàn),首先將WelcomeService交由Spring管理:

<bean name="WelcomeService" class="XXX.XXX.XXX.service.impl.WelcomeServiceImpl"/>

然后在業(yè)務(wù)代碼處通過Spring IOC拿到具體對象:

public class WelcomeController {
    @Autowired
    private WelcomeService service;

    @RequestMapping("/welcome")
    public String welcome() {
        return service.retrieveWelcomeMessage();
    }
}

測試的時候,只需要更改配置文件,將WelcomeService對應(yīng)的實現(xiàn)改為MockWelcomeServiceImpl即可:

<bean name="WelcomeService" class="XXX.XXX.XXX.service.impl.MockWelcomeServiceImpl"/>

這種方式對業(yè)務(wù)代碼沒有任何侵入,它有效的實現(xiàn)松耦合,大家都知道緊耦合的代碼是業(yè)務(wù)發(fā)展的噩夢;同時,Spring IOC提供的遠(yuǎn)不止這些,如通過單例減少創(chuàng)建無用的對象,通過延遲加載優(yōu)化初始化成本等

當(dāng)然,Spring 的核心功能遠(yuǎn)不知這些,如:

  • Spring AOP
  • Spring JDBC
  • Spring MVC
  • Spring ORM
  • Spring JMS
  • Spring Test

其實不通過Spring框架依然可以實現(xiàn)這些功能特定,但是Spring 提供了更優(yōu)雅的抽象接口以方便對這些功能的組裝,同時又給予每個具體實現(xiàn)以靈活的配置;另外,基于Spring,你可以方便的與其他框架進(jìn)行集成,如hibernateibatis等,Spring官方的原則是絕不重復(fù)造輪子,有好的解決方案只需要通過Spring進(jìn)行集成即可。縱覽Spring的結(jié)構(gòu),你會發(fā)現(xiàn)Spring Framework 本身并未提供太多具體的功能,它主要專注于讓你的項目代碼組織更加優(yōu)雅,使其具有極好的靈活性和擴(kuò)展性,同時又能通過Spring集成業(yè)界優(yōu)秀的解決方案,想了解Spring的核心實現(xiàn)機(jī)制可參考tiny spring 項目

什么是Spring MVC?它解決了什么問題?

Spring MVC是Spring的一部分,Spring 出來以后,大家覺得很好用,于是按照這種模式設(shè)計了一個 MVC框架(一些用Spring 解耦的組件),主要用于開發(fā)WEB應(yīng)用和網(wǎng)絡(luò)接口,它是Spring的一個模塊,通過Dispatcher Servlet, ModelAndView 和 View Resolver,讓應(yīng)用開發(fā)變得很容易,一個典型的Spring MVC應(yīng)用開發(fā)分為下面幾步:
首先通過配置文件聲明Dispatcher Servlet:

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>com.qgd.oms.web.common.mvc.OmsDispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

通過配置文件聲明servlet詳情,如MVC resource,data source,bean等

    <mvc:resources mapping="/css/**/*" location="/static/css/" cache-period="21600"/>
    <mvc:resources mapping="/js/**/*" location="/static/js/" cache-period="21600"/>
    <mvc:resources mapping="/views/**/*.html" location="/static/views/" cache-period="21600"/>
    <mvc:resources mapping="/fonts/**/*" location="/static/fonts/"/>
    <mvc:resources mapping="/ueditor/**/*" location="/static/js/lib/ueditor/"/>
    <mvc:resources mapping="/img/**/*" location="/static/img/"/>

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="validationQuery" value="${jdbc.validationQuery}"/>
        <property name="maxTotal" value="10"/>
        <property name="minIdle" value="5"/>
        <property name="maxIdle" value="10"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="true"/>
        <property name="poolPreparedStatements" value="true"/>
        <property name="maxOpenPreparedStatements" value="50"/>
    </bean>

    <bean id="configService" class="com.qgd.oms.web.common.service.ConfigService">
        <property name="configStore">
            <bean class="com.qgd.oms.web.common.service.impl.DbConfigStore">
                <property name="dataSource" ref="dataSource"/>
                    <property name="taskScheduler" ref="defaultScheduler"/>
                <property name="refreshInterval" value="30000"/>
            </bean>
        </property>
    </bean>

若需添加其它功能,如security,則需添加對應(yīng)配置:

    <http pattern="/css/**/*" security="none"/>
    <http pattern="/js/**/*" security="none"/>
    <http pattern="/views/**/*.html" security="none"/>
    <http pattern="/fonts/**/*" security="none"/>
    <http pattern="/ueditor/**/*" security="none"/>
    <http pattern="/img/**/*" security="none"/>

    <http use-expressions="true" entry-point-ref="omsAuthenticationEntryPoint">
        <logout logout-url="/omsmc/authentication/logout/*" success-handler-ref="omsLogoutSuccessHandler"></logout>
        <intercept-url pattern='/omsmc/authentication/login*' access="permitAll" />
        <intercept-url pattern='/ms/**/*' access="permitAll" />
        <intercept-url pattern='/**' access="authenticated" />
        <!--<security:form-login />-->
        <custom-filter ref="omsUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER" />
        <remember-me services-ref="omsRememberMeServices" key="yfboms"/>
        <csrf disabled="true"/>
    </http>

增加業(yè)務(wù)代碼,如controller,service,model等,最后生成war包,通過容器進(jìn)行啟動

什么是Spring Boot?它解決了什么問題?

初期的Spring通過代碼加配置的形式為項目提供了良好的靈活性和擴(kuò)展性,但隨著Spring越來越龐大,其配置文件也越來越繁瑣,太多復(fù)雜的xml文件也一直是Spring被人詬病的地方,特別是近些年其他簡潔的WEB方案層出不窮,如基于Python或Node.Js,幾行代碼就能實現(xiàn)一個WEB服務(wù)器,對比起來,大家漸漸覺得Spring那一套太過繁瑣,此時,Spring社區(qū)推出了Spring Boot,它的目的在于實現(xiàn)自動配置,降低項目搭建的復(fù)雜度,如需要搭建一個接口服務(wù),通過Spring Boot,幾行代碼即可實現(xiàn),請看代碼示例:

//引入spring-boot-starter-web依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
//聲明Spring Boot應(yīng)用,直接寫業(yè)務(wù)邏輯即可
@Controller
@SpringBootApplication
public class MockServerApplication {
    @RequestMapping("/hi")
    @ResponseBody
    String home() {
        return "how are you!";
    }

    public static void main(String[] args) {
        SpringApplication.run(MockServerApplication.class, args);
    }
}

你甚至都不用額外的WEB容器,直接生成jar包執(zhí)行即可,因為spring-boot-starter-web模塊中包含有一個內(nèi)置tomcat,可以直接提供容器使用;基于Spring Boot,不是說原來的配置沒有了,而是Spring Boot有一套默認(rèn)配置,我們可以把它看做比較通用的約定,而Spring Boot遵循的也是約定優(yōu)于配置原則,同時,如果你需要使用到Spring以往提供的各種復(fù)雜但功能強(qiáng)大的配置功能,Spring Boot一樣支持

在Spring Boot中,你會發(fā)現(xiàn)你引入的所有包都是starter形式,如:

  • spring-boot-starter-web-services,針對SOAP Web Services
  • spring-boot-starter-web,針對Web應(yīng)用與網(wǎng)絡(luò)接口
  • spring-boot-starter-jdbc,針對JDBC
  • spring-boot-starter-data-jpa,基于hibernate的持久層框架
  • spring-boot-starter-cache,針對緩存支持
  • 等等

Spring Boot對starter的解釋如下:

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go

這句話的譯意為:

Starters是一系列極其方便的依賴描述,通過在你的項目中包含這些starter,你可以一站式獲得你所需要的服務(wù),而無需像以往那樣copy各種示例配置及代碼,然后調(diào)試,真正做到開箱即用;比如你想使用Spring JPA進(jìn)行數(shù)據(jù)操作,只需要在你的項目依賴中引入spring-boot-starter-data-jpa即可

Spring,Spring MVC,Spring Boot 三者比較

其實寫到這里,很多讀者應(yīng)該已經(jīng)清楚,這三者專注的領(lǐng)域不同,解決的問題也不一樣;總的來說,Spring 就像一個大家族,有眾多衍生產(chǎn)品例如 Boot,Security,JPA等等。但他們的基礎(chǔ)都是Spring 的 IOC 和 AOP,IOC提供了依賴注入的容器,而AOP解決了面向切面的編程,然后在此兩者的基礎(chǔ)上實現(xiàn)了其他衍生產(chǎn)品的高級功能;Spring MVC是基于 Servlet 的一個 MVC 框架,主要解決 WEB 開發(fā)的問題,因為 Spring 的配置非常復(fù)雜,各種xml,properties處理起來比較繁瑣。于是為了簡化開發(fā)者的使用,Spring社區(qū)創(chuàng)造性地推出了Spring Boot,它遵循約定優(yōu)于配置,極大降低了Spring使用門檻,但又不失Spring原本靈活強(qiáng)大的功能,下面用一張圖來描述三者的關(guān)系:


Spring.png

最后一句話總結(jié):Spring MVC和Spring Boot都屬于Spring,Spring MVC 是基于Spring的一個 MVC 框架,而Spring Boot 是基于Spring的一套快速開發(fā)整合包

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,755評論 2 371

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