Spring Framework的誕生讓開發人員的工做從石器時代跨域到了工業時代,你是否還能記起手擼Servlet和JDBC的歲月?,你是否還對Struts1以及Struts2莫名其妙的404錯誤記憶猶新?從2004年3月Spring 1.0發佈到至今,Spring的發展已經走過了15個年頭,其創造的價值讓人矚目。今天,帶着這樣一個背景來梳理一下Spring Framework,Spring MVC和Spring Boot三者之間的區別。html
咱們使用Spring家族的系列產品這麼長時間,不由會問這樣幾個問題:Spring Framework是什麼?Spring MVC是什麼?Spring Boot又是什麼?它們被設計出來的目的是什麼?java
在接下來的內容中,將梳理這樣幾個知識點:web
當你仔細思考這個問題的時候你會發現,不少地方它都有滲透到,貌似一個Spring就能夠撐起開發的半邊天,以致於很難一會兒回答這個問題。那Spring Framework到底解決了哪些核心問題?spring
Spring Framework最重要也是最核心的特性是依賴注入。全部的Spring模塊的核心就是DI(依賴注入)或者IoC(控制反轉)。數據庫
依賴注入或控制反轉是Spring Framework最大的特性,當咱們正確使用DI(依賴注入)或IoC時,能夠開發出一個高內聚低耦合的應用程序,而這一一個低耦合的應用程序能夠輕鬆的對其實施單元測試。這就是Spring Framework解決的最核心的問題。設計模式
請考慮這一一個案例:UserAction依賴於UserService來獲取用戶信息,在沒有依賴注入的狀況下,咱們須要手動在UserAction中實例化一個UserService對象,這樣的手工做業意味着UserAction和UserService必須精密的聯繫在一塊兒,才能正常工做。若是一個Action須要多個Service提供服務,那實例化這些Service將是一個繁重的工做。下面咱們給出一個不使用依賴注入的代碼片斷加以說明:跨域
UserService.javatomcat
public interface UserService{
User profile();
}
複製代碼
UserServiceImpl.javaspringboot
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();
}
}
複製代碼
引入依賴注入將會使整個代碼看起來很清爽。爲了可以開發出高內聚低耦合的應用程序,Spring Framework爲咱們作了大量的準備工做。下面咱們使用兩個簡單的註解**@Component和@Autowired**來實現依賴注入。
在接下來的示例代碼中,咱們會看到Spring Framework將爲UserService建立一個Bean對象,並將其自動引入到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();
}
}
複製代碼
對比上下兩部分的代碼,你是否發現了他們之間的區別?Action所依賴的Service的初始化工做所有交由Spring Framework來管理,咱們只須要在適當的地方向Spring Framework索取想要服務便可。這就比如當我想要吃薯片的時候,我不須要本身親自種土豆,施肥,收穫...清洗,切片...一直到最後炸土豆片,想一想都以爲累,而更簡單的方法是直接去超市購買本身想要的薯片便可。
Spring Framework的依賴注入是核心中的核心,在依賴注入核心特性的基礎上,Spring Framework還衍生出了不少的高級模塊:
對於這些新的高級模塊,可能會產生這一一個問題:它們是不是一個全新的功能?答案是否認的,在不使用Spring Framework的狀況下,咱們依然可以使用JDBC鏈接數據庫,依然可以對視圖和數據模型進行控制,依然可以使用第三方的ORM框架。那Spring Framework幹了什麼?Spring Framework站在巨人的肩膀上,對這些原生的模塊進行了抽象,而抽象能夠帶來這樣一些好處:
這樣的好處是顯而易見的,好比與傳統的JDBC相比,使用JDBCTemplate操做數據庫,首先是代碼量小了,其次是咱們不須要再面對恐怖的try-catch。
Spring Framework還具有另一個重要特性,那就是可以快速的與其餘三方框架進行整合。與其本身造輪子,還不如想辦法將好的輪子整合在一塊兒,我想這句話應該能夠用來概況Spring Framework這一特性。Spring Framework對於整合其餘的框架,給出了不錯的解決方案,下面將列舉一些常見的方案:
Spring MVC提供了構建Web應用程序的全功能MVC模塊,實現了Web MVC設計模式以及請求驅動類型的輕量級Web框架,即採用了MVC架構模式的思想,將Web層進行職責解耦。基於請求驅動指的是使用請求-響應模型,視圖與數據模型分離,以簡化Web應用的開發。
使用Spring MVC提供的Dispatcher Servlet,ModelAndView和ViewResolver等功能,能夠輕鬆的開發出一個Web應用程序。
咱們都知道,使用Spring Framework來開發應用程序,須要進行大量的配置工做以及依賴包的管理,工做繁重並且極易出現配置錯誤,尤其明顯的是依賴包之間的版本衝突問題。
舉一個簡單的案例,當咱們使用Spring MVC來開發Web應用程序時,咱們大體須要經歷這樣幾個步驟:
下面給出了一個小範圍的舉例:
...
<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/"/>
...
複製代碼
此外,咱們還須要配置先關的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>
複製代碼
若是咱們的應用程序還須要連接數據,則還須要配置數據源,實體對象管理器,事務管理器等衆多配置:
<bean id="datasource" class="">
...
</bean>
<bean id="entityManagerFactory" class="">
...
</bean>
<bean id="transactionManager" class="">
...
</bean>
...
複製代碼
面對衆多的配置文件,咱們須要花費大量的時間去處理,這時你可能會問,我爲何要花費那麼多的時間去管理Spring的配置工做?不是應該專一於應用自己的業務邏輯嗎?如今,有了Spring Boot,這些煩心事就不須要你去操心了。
我爲何會把Spring Boot的自動化配置能力放在第一位,由於它極大的下降了咱們使用Spring Framework所付出的成本。這是Spring Boot的自動化配置是一個最具價值的解決方案。
這難道不值得咱們拍案叫好嗎?若是你想要開發一個Web應用程序,你須要作的事情就是將Spring Boot Web包引入到項目的類路徑下,Spring Boot就能夠幫你解決後續的大多數配置工做。
當Spring Boot檢測到有新的依賴包添加到類路徑上,Spring Boot會採用默認的配置對新的依賴包進行設置,若是咱們想本身配置依賴包時,只須要手動覆蓋默認的配置項便可。
- Spring Boot掃描類路徑上可用的框架信息
- 獲取應用程序現有的配置信息
- 若是應用程序沒有提供框架的配置信息,Spring Boot將採用默認的配置來配置框架,這就是Spring Boot的自動配置特性(Auto Configuration)
在傳統模式的開發過程當中,咱們須要反覆的確認應用程序所須要的第三方JAR包,以及這些JAR的版本和依賴關係。例如,如今咱們打算開發一款Web應用程序,應用程序大概須要以下的一些依賴包:Spring MVC,Jackson Databind(用於數據綁定),Hibernate-Validator(用於服務端的數據校驗)和Log4j(用於日誌記錄)。如今,咱們須要去下載對應的jar包到應用程序中,而且還須要處理依賴包之間版本衝突的問題。
<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>
複製代碼
這不是一件簡單的事情,特別是發生版本衝突的時候,讓應用程序可以正常運行起來就須要花費必定的時間。
Spring Boot Starter是一組用於管理依賴關係的描述符,經過這些描述符,咱們能夠在應用程序中輕鬆的管理依賴包,你能夠以開箱即用的方式獲取想要的依賴包,而無需去Maven倉庫總檢索對應的依賴,並將依賴配置複製粘貼到應用程序的pom文件中。例如,若是你想要使用Spring和JPA進行數據庫訪問,只須要在pom中添加spring-boot-starter-data-jpa依賴項就能夠。
如今,若是咱們想要開發一個Web應用程序,使用Spring Boot Starter Web依賴會是一個不錯的選擇。咱們能夠經過使用Spring INitializr快速構建一個Web應用程序,並將Spring Boot Starter Web添加到項目中。此時咱們的pom文件只須要不多的配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
複製代碼
Spring Boot Starter Web會爲咱們預裝以下的一些依賴:
對於開發人員而言,咱們不須要去擔憂這些依賴項的管理工做以及解決他們之間的兼容性問題,Spring Boot已經幫咱們解決了。
Spring Boot的核心目標在於快速實現生產就緒的應用程序,這將包含這樣幾個部分:
經過上述的梳理,咱們能夠看到,Spring Framework是一個提供了DI(依賴注入)和IoC(控制反轉)的開發框架,使用Spring Framework能夠幫助咱們開發出高內聚,低耦合的應用程序,Spring MVC是在Spring Framework基礎上發展出來的基於MVC模式的全功能Web開發框架,實現了Model,View和Controller之間的職責解耦;Spring Boot爲咱們提供了一個可以快速使用Spring Framework的優秀解決方案,經過最小化的配置,咱們就可使用Spring Framework,嚴格意義上講,Spring Boot並非某種框架,它只是爲開發人員提供了一個更好的更方便的使用Spring Framework的解決方案。
做者:譚朝紅