(第二講)Spring&Spring MVC&Spring Boot三者之間的區(qū)別與聯(lián)系

Spring Framework的誕生讓開發(fā)人員的工作從石器時(shí)代跨域到了工業(yè)時(shí)代,你是否還能記起手?jǐn)]Servlet和JDBC的歲月?,你是否還對(duì)Struts1以及Struts2莫名其妙的404錯(cuò)誤記憶猶新?從2004年3月Spring 1.0發(fā)布到至今,Spring的發(fā)展已經(jīng)走過了15個(gè)年頭,其創(chuàng)造的價(jià)值讓人矚目。今天,帶著這樣一個(gè)背景來(lái)梳理一下Spring Framework,Spring MVC和Spring Boot三者之間的區(qū)別。

我們使用Spring家族的系列產(chǎn)品這么長(zhǎng)時(shí)間,不禁會(huì)問這樣幾個(gè)問題:Spring Framework是什么?Spring MVC是什么?Spring Boot又是什么?它們被設(shè)計(jì)出來(lái)的目的是什么?

你需要了解的知識(shí)

在接下來(lái)的內(nèi)容中,將梳理這樣幾個(gè)知識(shí)點(diǎn):

  • Spring Framework基本概述
  • Spring Framework主要解決的問題是什么?
  • Spring MVC基本概述
  • Spring MVC主要解決的問題是什么?
  • Spring Boot主要解決的問題是什么?
  • Spring,Spring MVC和Spring Boot三者之間的區(qū)別是什么?

Spring Framework 解決了哪些核心問題?

當(dāng)你仔細(xì)思考這個(gè)問題的時(shí)候你會(huì)發(fā)現(xiàn),很多地方它都有滲透到,貌似一個(gè)Spring就可以撐起開發(fā)的半邊天,以至于很難一下子回答這個(gè)問題。那Spring Framework到底解決了哪些核心問題?

Spring Framework最重要也是最核心的特性是依賴注入。所有的Spring模塊的核心就是DI(依賴注入)或者IoC(控制反轉(zhuǎn))。

依賴注入或控制反轉(zhuǎn)是Spring Framework最大的特性,當(dāng)我們正確使用DI(依賴注入)或IoC時(shí),可以開發(fā)出一個(gè)高內(nèi)聚低耦合的應(yīng)用程序,而這一一個(gè)低耦合的應(yīng)用程序可以輕松的對(duì)其實(shí)施單元測(cè)試。這就是Spring Framework解決的最核心的問題。

無(wú)依賴注入

請(qǐng)考慮這一一個(gè)案例:UserAction依賴于UserService來(lái)獲取用戶信息,在沒有依賴注入的情況下,我們需要手動(dòng)在UserAction中實(shí)例化一個(gè)UserService對(duì)象,這樣的手工作業(yè)意味著UserAction和UserService必須精密的聯(lián)系在一起,才能正常工作。如果一個(gè)Action需要多個(gè)Service提供服務(wù),那實(shí)例化這些Service將是一個(gè)繁重的工作。下面我們給出一個(gè)不使用依賴注入的代碼片段加以說明:

UserService.java

public interface UserService{
    User profile();
}

UserServiceImpl.java

public class UserServiceImpl implements UserService{
    @Override
    User profile(){
        // TODO
    }
}

UserAction.java

@RestController
public class UserAction{
    
    private UserService userService = new UserServiceImpl();
    // other services...
    
    @GetMapping("/profile")
    public User profile(){
        return userService.profile();
    }
}

引入依賴注入

引入依賴注入將會(huì)使整個(gè)代碼看起來(lái)很清爽。為了能夠開發(fā)出高內(nèi)聚低耦合的應(yīng)用程序,Spring Framework為我們做了大量的準(zhǔn)備工作。下面我們使用兩個(gè)簡(jiǎn)單的注解@Component@Autowired來(lái)實(shí)現(xiàn)依賴注入。

  • @Component : 該注解將會(huì)告訴Spring Framework,被此注解標(biāo)注的類需要納入到Bean管理器中。
  • @Autowired : 告訴Spring Framework需要找到一與其類型匹配的對(duì)象,并將其自動(dòng)引入到所需要的類中。

在接下來(lái)的示例代碼中,我們會(huì)看到Spring Framework將為UserService創(chuàng)建一個(gè)Bean對(duì)象,并將其自動(dòng)引入到UserAction中。

UserService.java

public interface UserService{
    User profile();
}

UserServiceImpl.java

@Component
public class UserServiceImpl implements UserService{
    @Override
    User profile(){
        // TODO
    }
}

UserAction.java

@RestController
public class UserAction{
    @Autowired
    private UserService userService;
    // other services...
    
    @GetMapping("/profile")
    public User profile(){
        return userService.profile();
    }
}

對(duì)比上下兩部分的代碼,你是否發(fā)現(xiàn)了他們之間的區(qū)別?Action所依賴的Service的初始化工作全部交由Spring Framework來(lái)管理,我們只需要在適當(dāng)?shù)牡胤较騍pring Framework索取想要服務(wù)即可。這就好比當(dāng)我想要吃薯片的時(shí)候,我不需要自己親自種土豆,施肥,收獲...清洗,切片...一直到最后炸土豆片,想想都覺得累,而更簡(jiǎn)單的方法是直接去超市購(gòu)買自己想要的薯片即可。

Spring Framework還有其他的核心特性嗎?

#1:衍生的特性

Spring Framework的依賴注入是核心中的核心,在依賴注入核心特性的基礎(chǔ)上,Spring Framework還衍生出了很多的高級(jí)模塊:

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

對(duì)于這些新的高級(jí)模塊,可能會(huì)產(chǎn)生這一一個(gè)問題:它們是否是一個(gè)全新的功能?答案是否定的,在不使用Spring Framework的情況下,我們依然能夠使用JDBC連接數(shù)據(jù)庫(kù),依然能夠?qū)σ晥D和數(shù)據(jù)模型進(jìn)行控制,依然能夠使用第三方的ORM框架。那Spring Framework干了什么?Spring Framework站在巨人的肩膀上,對(duì)這些原生的模塊進(jìn)行了抽象,而抽象可以帶來(lái)這樣一些好處:

  • 減少了應(yīng)用中模板代碼的數(shù)量
  • 降低了原生框架的技術(shù)門檻
  • 基于依賴注入特性,實(shí)現(xiàn)了代碼的解耦,真正的高內(nèi)聚、低耦合
  • 更細(xì)粒度的單元測(cè)試

這樣的好處是顯而易見的,比如與傳統(tǒng)的JDBC相比,使用JDBCTemplate操作數(shù)據(jù)庫(kù),首先是代碼量小了,其次是我們不需要再面對(duì)恐怖的try-catch。

#2:優(yōu)秀的集成能力

Spring Framework還具備另外一個(gè)重要特性,那就是能夠快速的與其他三方框架進(jìn)行整合。與其自己造輪子,還不如想辦法將好的輪子整合在一起,我想這句話應(yīng)該可以用來(lái)概況Spring Framework這一特性。Spring Framework對(duì)于整合其他的框架,給出了不錯(cuò)的解決方案,下面將列舉一些常見的方案:

  • 與Hibernate ORM框架整合
  • 與MyBatis 對(duì)象映射框架整合
  • 與Junit單元測(cè)試框架整合
  • 與Log4J日志記錄框架整合

Spring MVC是什么?

Spring MVC提供了構(gòu)建Web應(yīng)用程序的全功能MVC模塊,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式以及請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即采用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡?qǐng)求驅(qū)動(dòng)指的是使用請(qǐng)求-響應(yīng)模型,視圖與數(shù)據(jù)模型分離,以簡(jiǎn)化Web應(yīng)用的開發(fā)。

使用Spring MVC提供的Dispatcher Servlet,ModelAndView和ViewResolver等功能,可以輕松的開發(fā)出一個(gè)Web應(yīng)用程序。

Spring Boot出現(xiàn)的原因是什么?

我們都知道,使用Spring Framework來(lái)開發(fā)應(yīng)用程序,需要進(jìn)行大量的配置工作以及依賴包的管理,工作繁重而且極易出現(xiàn)配置錯(cuò)誤,尤為明顯的是依賴包之間的版本沖突問題。

舉一個(gè)簡(jiǎn)單的案例,當(dāng)我們使用Spring MVC來(lái)開發(fā)Web應(yīng)用程序時(shí),我們大致需要經(jīng)歷這樣幾個(gè)步驟:

  • 1:配置組件掃描的包路徑

  • 2:配置對(duì)應(yīng)的Servlet程序

  • 3:配置視圖解析器

  • 4:配置頁(yè)面模板引擎(JSP、Freemarker等)

下面給出了一個(gè)小范圍的舉例:

...
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/pages</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>
<mvc:resources mapping="/static/**" location="/static/"/>
...

此外,我們還需要配置先關(guān)的Servlet處理程序,它們大致是這樣的:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/todo-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

如果我們的應(yīng)用程序還需要鏈接數(shù)據(jù),則還需要配置數(shù)據(jù)源,實(shí)體對(duì)象管理器,事務(wù)管理器等眾多配置:

<bean id="datasource" class="">
    ...
</bean>
<bean id="entityManagerFactory" class="">
    ...
</bean>
<bean id="transactionManager" class="">
    ...
</bean>
...

面對(duì)眾多的配置文件,我們需要花費(fèi)大量的時(shí)間去處理,這時(shí)你可能會(huì)問,我為什么要花費(fèi)那么多的時(shí)間去管理Spring的配置工作?不是應(yīng)該專注于應(yīng)用本身的業(yè)務(wù)邏輯嗎?現(xiàn)在,有了Spring Boot,這些煩心事就不需要你去操心了。

#1:Spring Boot的自動(dòng)化配置能力

我為什么會(huì)把Spring Boot的自動(dòng)化配置能力放在第一位,因?yàn)樗鼧O大的降低了我們使用Spring Framework所付出的成本。這是Spring Boot的自動(dòng)化配置是一個(gè)最具價(jià)值的解決方案。

這難道不值得我們拍案叫好嗎?如果你想要開發(fā)一個(gè)Web應(yīng)用程序,你需要做的事情就是將Spring Boot Web包引入到項(xiàng)目的類路徑下,Spring Boot就可以幫你解決后續(xù)的大多數(shù)配置工作。

  • 如果Hibernate的依賴被放到了類路徑上,Spring Boot會(huì)自動(dòng)配置數(shù)據(jù)源
  • 如果Spring MVC的依賴被放到了類路徑上,Spring Boot又會(huì)自動(dòng)配置Dispatcher Servlet

當(dāng)Spring Boot檢測(cè)到有新的依賴包添加到類路徑上,Spring Boot會(huì)采用默認(rèn)的配置對(duì)新的依賴包進(jìn)行設(shè)置,如果我們想自己配置依賴包時(shí),只需要手動(dòng)覆蓋默認(rèn)的配置項(xiàng)即可。

  1. Spring Boot掃描類路徑上可用的框架信息
  2. 獲取應(yīng)用程序現(xiàn)有的配置信息
  3. 如果應(yīng)用程序沒有提供框架的配置信息,Spring Boot將采用默認(rèn)的配置來(lái)配置框架,這就是Spring Boot的自動(dòng)配置特性(Auto Configuration)

#2:Spring Boot Starter項(xiàng)目

在傳統(tǒng)模式的開發(fā)過程中,我們需要反復(fù)的確認(rèn)應(yīng)用程序所需要的第三方JAR包,以及這些JAR的版本和依賴關(guān)系。例如,現(xiàn)在我們打算開發(fā)一款Web應(yīng)用程序,應(yīng)用程序大概需要如下的一些依賴包:Spring MVC,Jackson Databind(用于數(shù)據(jù)綁定),Hibernate-Validator(用于服務(wù)端的數(shù)據(jù)校驗(yàn))和Log4j(用于日志記錄)?,F(xiàn)在,我們需要去下載對(duì)應(yīng)的jar包到應(yīng)用程序中,并且還需要處理依賴包之間版本沖突的問題。

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>4.2.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.2.Final</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

這不是一件簡(jiǎn)單的事情,特別是發(fā)生版本沖突的時(shí)候,讓應(yīng)用程序能夠正常運(yùn)行起來(lái)就需要花費(fèi)一定的時(shí)間。

Spring Boot Starter是一組用于管理依賴關(guān)系的描述符,通過這些描述符,我們可以在應(yīng)用程序中輕松的管理依賴包,你可以以開箱即用的方式獲取想要的依賴包,而無(wú)需去Maven倉(cāng)庫(kù)總檢索對(duì)應(yīng)的依賴,并將依賴配置復(fù)制粘貼到應(yīng)用程序的pom文件中。例如,如果你想要使用Spring和JPA進(jìn)行數(shù)據(jù)庫(kù)訪問,只需要在pom中添加spring-boot-starter-data-jpa依賴項(xiàng)就可以。

現(xiàn)在,如果我們想要開發(fā)一個(gè)Web應(yīng)用程序,使用Spring Boot Starter Web依賴會(huì)是一個(gè)不錯(cuò)的選擇。我們可以通過使用Spring INitializr快速構(gòu)建一個(gè)Web應(yīng)用程序,并將Spring Boot Starter Web添加到項(xiàng)目中。此時(shí)我們的pom文件只需要很少的配置:

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

Spring Boot Starter Web會(huì)為我們預(yù)裝如下的一些依賴:

  • Spring : core,beans,context,aop
  • Web MVC : Spring MVC
  • Jackson : JSON Binding
  • Validation : Hibernate Validator,Validation API
  • Embedded Servlet Container: Tomcat
  • Logging : logback,slf4j

對(duì)于開發(fā)人員而言,我們不需要去擔(dān)心這些依賴項(xiàng)的管理工作以及解決他們之間的兼容性問題,Spring Boot已經(jīng)幫我們解決了。

Spring Boot的核心目標(biāo)

Spring Boot的核心目標(biāo)在于快速實(shí)現(xiàn)生產(chǎn)就緒的應(yīng)用程序,這將包含這樣幾個(gè)部分:

  • 執(zhí)行器 : 啟用高級(jí)監(jiān)控和跟蹤應(yīng)用程序功能
  • 嵌入式服務(wù)器:Spring Boot已經(jīng)內(nèi)置了多個(gè)Web服務(wù)器,如Undertow,jetty,tomcat,因此我們不需要再額外的配置服務(wù)器,就可以完成應(yīng)用程序的調(diào)試工作。
  • 默認(rèn)的異常處理機(jī)制
  • 開箱即用的依賴項(xiàng)管理機(jī)制
  • 自動(dòng)化配置

總結(jié)

通過上述的梳理,我們可以看到,Spring Framework是一個(gè)提供了DI(依賴注入)和IoC(控制反轉(zhuǎn))的開發(fā)框架,使用Spring Framework可以幫助我們開發(fā)出高內(nèi)聚,低耦合的應(yīng)用程序,Spring MVC是在Spring Framework基礎(chǔ)上發(fā)展出來(lái)的基于MVC模式的全功能Web開發(fā)框架,實(shí)現(xiàn)了Model,View和Controller之間的職責(zé)解耦;Spring Boot為我們提供了一個(gè)能夠快速使用Spring Framework的優(yōu)秀解決方案,通過最小化的配置,我們就可以使用Spring Framework,嚴(yán)格意義上講,Spring Boot并不是某種框架,它只是為開發(fā)人員提供了一個(gè)更好的更方便的使用Spring Framework的解決方案。

作者:譚朝紅
鏈接:(第二講)Spring&Spring MVC&Spring Boot三者之間的區(qū)別與聯(lián)系
來(lái)源:譚朝紅的技術(shù)分享博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容