要了解Spring Boot的發(fā)展背景,還得從2004年Spring Framework1.0版本發(fā)布開始說起,不過大家都是從開始學(xué)習(xí)Java就使用Spring Framework了,所以就不做過多展開。
隨著使用Spring Framework進(jìn)行開發(fā)的企業(yè)和個人越來越多,Spring 也慢慢從一個單一簡潔的小框架編程了一個大而全的開源軟件,Spring Framework的邊界不斷進(jìn)行擴張,到了現(xiàn)在Spring 幾乎可以做任何事情。目前市面上絕大部分的開源組件和中間件,都有Spring對應(yīng)組件的支持,
你們?nèi)绻リP(guān)注Spring目前的官網(wǎng),你會發(fā)現(xiàn)他的slogan是:Spring makes Java Simple。它讓Java的開發(fā)變得更加簡單。
雖然Spring的組件代碼是輕量級的,但是它的配置卻是重量級的,Spring 每集成一個開源軟件,就需要增加一些基礎(chǔ)配置,慢慢的隨著我們開發(fā)的項目越來越龐大,往往需要集成很多開源軟件,因此后期使用 Spirng 開發(fā)大型項目需要引入很多配置文件,太多的配置非常難以理解,并容易配置出錯,這個給開發(fā)人員帶來了不少的負(fù)擔(dān)。
大家想象一個場景,就是假如你需要用spring開發(fā)一個簡單的Hello World Web應(yīng)用程序,應(yīng)該要做哪些動作呢?
- 創(chuàng)建一個項目結(jié)構(gòu),必然包含依賴Maven或者Gradle的構(gòu)建文件。
- 至少需要添加spring mvc和servlet api的依賴
- 一個web.xml,聲明spring的DispatcherServlet
- 一個啟用了Spring MVC的spring 配置
- 一個控制器類,“以HelloWord”為響應(yīng)的http請求
- 一個用于部署應(yīng)用程序的web應(yīng)用服務(wù)器,比如Tomcat
在整個過程中,我們發(fā)現(xiàn)只有一個東西和Hello Word功能相關(guān),那就是控制器(controller),剩下的都是Spring 開發(fā)的Web應(yīng)用程序必須要的通用模版,既然所有Spring Web應(yīng)用程序都要用到他們,那為什么還要你來提供這些東西呢?
所以,直到2012年10月份,一個叫Mike Youngstrom(揚斯特羅姆)在Spring Jira中創(chuàng)建了一個功能請求,要求在Spring Framework中支持無容器Web應(yīng)用程序體系結(jié)構(gòu),他談到了在主容器引導(dǎo) spring 容器內(nèi)配置 Web 容器服務(wù)。
https://jira.spring.io/browse/SPR-9888
I think that Springs web application architecture can be significantly simplified if it were to provided tools and a reference architecture that leveraged the Spring component and configuration model from top to bottom. Embedding and unifying the configuration of those common web container services within a Spring Container bootstrapped from a simple main() method.我認(rèn)為,如果要提供從上到下充分利用Spring組件和配置模型的工具和參考體系結(jié)構(gòu),則可以大大簡化Spring的Web應(yīng)用程序體系結(jié)構(gòu)。在通過簡單main()方法引導(dǎo)的Spring容器中嵌入和統(tǒng)一那些通用Web容器服務(wù)的配置。
而且Spring 開發(fā)團(tuán)隊也意識到了這些問題,急需要一套軟件來解決這個問題,而這個時候微服務(wù)的概念也慢慢的起來,快速開發(fā)微小獨立的應(yīng)用也變得很急迫。
而Spring恰好處在這樣一個交叉點上,所以順勢而為在2013年初的時候,開始投入Spring Boot項目的研發(fā),直到2014年4月,Spring Boot1.0版本發(fā)布。從那以后,Spring Boot開啟了一些列的迭代和升級的過程。
經(jīng)過7年時間的發(fā)展,到目前為止,Spring Boot最新穩(wěn)定版為2.6.0版本。
Spring Boot的發(fā)展
Spring Boot剛出生的時候,引起了很多開源社區(qū)的關(guān)注,并且也有個人和企業(yè)開始嘗試使用Spring Boot。 其實直到2016年,Spring Boot才真正在國內(nèi)被使用起來。我之前在挖財?shù)臅r候,2015年公司就開始采用Spring Boot來構(gòu)建基于Dubbo的微服務(wù)架構(gòu)。到現(xiàn)在,Spring Boot幾乎是所有公司的第一選擇。
Build Anything
Spring Boot被官方定位為“BUILD ANYTHING”,Spring Boot官方的概述是這么描述Spring Boot的。
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".// 通過Spring Boot可以輕松的創(chuàng)建獨立的、生產(chǎn)級別的基于Spring 生態(tài)下的應(yīng)用,你只需要運行即可。We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.//對于Spring平臺和第三方庫,我們提供了一個固化的視圖,這個視圖可以讓我們在構(gòu)建應(yīng)用是減少很多麻煩。大部分spring boot應(yīng)用只需要最小的Spring 配置即可。
如果大家不習(xí)慣看英文文檔,可能理解起來比較復(fù)雜,翻譯成人話就是:Spring Boot能夠幫助使用Spring Framework生態(tài)的開發(fā)者快速高效的構(gòu)建一個基于Spring以及spring 生態(tài)體系的應(yīng)用。
為了讓大家對這句話的理解更加深刻,我們來做兩個小實驗,一個是基于傳統(tǒng)的Spring MVC框架構(gòu)建一個項目、另一種是使用Spring Boot。
Spring MVC With Spring Boot
通過Spring MVC項目搭建過程來對比Spring Boot的差異和優(yōu)勢。
Spring MVC項目搭建過程
創(chuàng)建一個maven-webapp項目
添加jar包依賴
org.springframework spring-beans 5.2.5.RELEASE commons-logging commons-logging 1.2 spring-contextspring-context-supportspring-corespring-expressionspring-webspring-webmvc
修改web.xml文件
contextConfigLocation classpath:applicationContext.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.util.IntrospectorCleanupListener springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:dispatcher-servlet.xml springmvc / 在resources目錄下添加dispatcher-servlet.xml文件
創(chuàng)建一個Controller
@Controllerpublic class HelloController { @RequestMapping(method = RequestMethod.GET,path = "/index") public String index(Model model){ model.addAttribute("key","Hello Gupao"); return "index"; }}
修改默認(rèn)的index.jsp,設(shè)置el表達(dá)式的解析
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isELIgnored="false" %>${key}
- 運行項目
Spring Boot搭建過程
直接基于start.spring.io這個腳手架搭建即可。
思考和總結(jié)
咱們再回到最開始Spring Boot的定義部分,Spring Boot能夠幫助使用Spring Framework生態(tài)的開發(fā)者快速高效的構(gòu)建一個基于Spring以及spring 生態(tài)體系的應(yīng)用。
再對比兩種構(gòu)建過程,似乎也能夠理解Spring Boot的作用了吧。當(dāng)然它的作用不僅于此,后續(xù)會逐步揭開它的真實面目。
通過上面這個案例我們發(fā)現(xiàn),如果沒有spring boot,要去構(gòu)建一個Spring MVC的web應(yīng)用,需要做的事情很多
- 引入jar包
- 修改web.xml,添加監(jiān)聽和攔截
- 創(chuàng)建spring mvc核心配置文件dispatcher-servlet.xml
- 創(chuàng)建controller
- 部署到tomcat
這個過程如果不熟悉,很可能需要1~2個小時,如果是新手,可能需要更長時間。但是spring boot,不管是新手還是老手,都能夠分分鐘解決問題。
理解約定優(yōu)于配置
我們知道,Spring Boot是約定由于配置理念下的產(chǎn)物,那么什么是約定由于配置呢?
約定優(yōu)于配置是一種軟件設(shè)計的范式,主要是為了減少軟件開發(fā)人員需做決定的數(shù)量,獲得簡單的好處,而又不失靈活性。
簡單來說,就是你所使用的工具默認(rèn)會提供一種約定,如果這個約定和你的期待相符合,就可以省略那些基礎(chǔ)的配置,否則,你就需要通過相關(guān)配置來達(dá)到你所期待的方式。
約定優(yōu)于配置有很多地方體現(xiàn),舉個例子,比如交通信號燈,紅燈停、綠燈行,這個是一個交通規(guī)范。你可以在紅燈的時候不停,因為此時沒有一個障礙物阻礙你。但是如果大家都按照這個約定來執(zhí)行,那么不管是交通的順暢度還是安全性都比較好。
而相對于技術(shù)層面來說,約定有很多地方體現(xiàn),比如一個公司,會有專門的文檔格式、代碼提交規(guī)范、接口命名規(guī)范、數(shù)據(jù)庫規(guī)范等等。這些規(guī)定的意義都是讓整個項目的可讀性和可維護(hù)性更強。
Spring Boot Web應(yīng)用中約定優(yōu)于配置的體現(xiàn)
那么在前面的案例中,我們可以思考一下,Spring Boot為什么能夠把原本繁瑣又麻煩的工作省略掉呢? 實際上這些工作并不是真正意義上省略了,只是Spring Boot幫我們默認(rèn)實現(xiàn)了。
而這個時候我們反過來思考一下,Spring Boot Web應(yīng)用中,相對Spring MVC框架的構(gòu)建而言,它的約定由于配置體現(xiàn)在哪些方面呢?
Spring Boot的項目結(jié)構(gòu)約定,Spring Boot默認(rèn)采用Maven的目錄結(jié)構(gòu),其中
src.main.java 存放源代碼文件
src.main.resource 存放資源文件
src.test.java 測試代碼
src.test.resource 測試資源文件
target 編譯后的class文件和jar文件
內(nèi)置了嵌入式的Web容器,在Spring 2.2.6版本的官方文檔中3.9章節(jié)中,有說明Spring Boot支持四種嵌入式的Web容器
Tomcat
Jetty
Undertow
Reactor
Spring Boot默認(rèn)提供了兩種配置文件,一種是application.properties、另一種是application.yml。Spring Boot默認(rèn)會從該配置文件中去解析配置進(jìn)行加載。
- Spring Boot通過starter依賴,來減少第三方j(luò)ar的依賴。
這些就是Spring Boot能夠方便快捷的構(gòu)建一個Web應(yīng)用的秘密。當(dāng)然Spring Boot的約定優(yōu)于配置還不僅體現(xiàn)在這些地方,在后續(xù)的分析中還會看到Spring Boot中約定優(yōu)于配置的體現(xiàn)。
Spring Boot整合Mybatis
實際上Spring Boot的本質(zhì)就是Spring,如果一定要從技術(shù)發(fā)展的過程中找到一些相似的對比的話,你們可以對比一下Jsp/Servlet和Spring MVC, 兩者都可以用來開發(fā)Web項目,但是在使用上,Spring MVC的使用會更加簡單。
而Spring Boot和Spring 就相當(dāng)于當(dāng)年的JSP/Servlet和Spring MVC的關(guān)系。所以它本身并沒有所謂新的技術(shù),接下來,我?guī)е蠹襾硗ㄟ^Spring Boot整合Mybatis實現(xiàn)數(shù)據(jù)的基本操作的案例,來繼續(xù)認(rèn)識一下Spring Boot。
創(chuàng)建Spring Boot 應(yīng)用
創(chuàng)建一個Web項目
引入項目中需要的starter依賴
mysql mysql-connector-java org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2 org.springframework.boot spring-boot-starter-thymeleaf
創(chuàng)建數(shù)據(jù)庫表
DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `address` varchar(80) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
配置數(shù)據(jù)庫連接
spring: datasource: url: jdbc:mysql://192.168.13.106:3306/test_springboot username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
開發(fā)數(shù)據(jù)庫訪問層
創(chuàng)建實體對象
public class User { private int id; private String name; private String address;}
創(chuàng)建Mapper
//@Repository可以支持在你的持久層作為一個標(biāo)記,可以去自動處理數(shù)據(jù)庫操作產(chǎn)生的異常@Repository@Mapperpublic interface UserMapper { User findById(int id); List list(); int insert(User user); int delete(int id); int update(User user);}
編寫mapper文件
在resource文件目錄下創(chuàng)建UserMapper.xml文件,內(nèi)容如下
insert into t_user(name,address) values(#{name,jdbcType=VARCHAR},#{address,jdbcType=VARCHAR}) delete from t_user where id=#{id} update t_user set name=#{name,jdbcType=VARCHAR},address=#{address,jdbcType=VARCHAR} where id=#{id,jdbcType=INTEGER}
定義service及實現(xiàn)
public interface IUserService { User findById(int id); List list(); int insert(User user); int delete(int id); int update(User user);}@Servicepublic class UserServiceImpl implements IUserService { @Autowired private UserMapper userMapper;}
創(chuàng)建Controller
@RestControllerpublic class Controller { @Autowired private IUserService userService; @GetMapping("/user/{id}") public User user(@PathVariable("id") int id){ return userService.findById(id); } @GetMapping("/users") public List users(){ return userService.list(); } @PostMapping("/user") public String insertUser(User user){ int row=userService.insert(user); return row>0?"SUCCESS":"FAILED"; } @PutMapping("/user") public String updateUser(User user){ int row=userService.update(user); return row>0?"SUCCESS":"FAILED"; } @DeleteMapping("/user/{id}") public String deleteUser(@PathVariable("id") int id){ return userService.delete(id)>0?"SUCCESS":"FAILED"; }}
修改配置
在Spring 的Main方法上增加以下注解,用來掃描Mybatis的Mapper文件
@MapperScan("com.example.demo.mapper")
配置Mapper配置文件的地址,在application.yml中
mybatis:mapper-locations: classpath:*Mapper.xml
id int,
name varchar(20),
address varchar(20)
)
項目打包
- mvn -Dmaven.test.skip -U clean install
- java -jar xxx.jar
簡單總結(jié)
這個代碼,我想,大家應(yīng)該寫過無數(shù)遍了,而在基于Spring Boot集成Mybatis這個案例中,核心的業(yè)務(wù)邏輯并沒有減少,它只減少了一些繁瑣的配置,使得我們更聚焦在業(yè)務(wù)開發(fā)層面。
簡單來說,基于Spring Boot的項目中,我們只需要寫Controlelr、Service、Dao即可。甚至很多情況下我們dao都不需要管,比如使用mybatis-plus這個插件,就可以省去很多固定的dao層邏輯。
所以實際上,Spring Boot并沒有新鮮的東西,因此你看到市面上大部分講spring boot的書,這些書我?guī)缀醵伎催^,基本上都是講解Spring Boot的應(yīng)用,以及Spring Boot的一些特性分析。因為一旦你想講Spring Boot的原理,就必然會回歸到Spring這塊的內(nèi)容上。比如小馬哥的Spring Boot編程思想著本書,大篇幅的都是在講Spring Framework。因為Spring Boot的內(nèi)核還是Spring Framework。
Spring Boot與微服務(wù)
接下來,給大家講講spring boot與微服務(wù)這塊的內(nèi)容。
什么是Spring Cloud
首先,我們要簡單了解一下什么是微服務(wù),按照我的理解來說,微服務(wù)就是微粒度的服務(wù),它是面向服務(wù)架構(gòu)(SOA)的進(jìn)一步優(yōu)化。如果大家不是很好理解,翻譯成白話就是
一個業(yè)務(wù)系統(tǒng),原本是在一個獨立的war包中?,F(xiàn)在為了更好的維護(hù)和提高性能,把這個war包按照業(yè)務(wù)緯度拆分成了一個個獨立的業(yè)務(wù)子系統(tǒng),每個子系統(tǒng)提供該業(yè)務(wù)領(lǐng)域相關(guān)的功能,并暴露API接口。
這些服務(wù)彼此之間進(jìn)行數(shù)據(jù)交換和通信來實現(xiàn)整個產(chǎn)品的功能。
而這些業(yè)務(wù)子系統(tǒng),實際上代表的就是一個服務(wù),那么所謂的微服務(wù),說的是這個服務(wù)的粒度。至于服務(wù)的粒度什么樣才叫微,其實沒有一個固定的衡量標(biāo)準(zhǔn)。更多的還是在每個公司具體的業(yè)務(wù)粒度的把控上。
微服務(wù)化遇到的問題
在為服務(wù)化之后,會面臨很多的問題,比如服務(wù)注冊、服務(wù)路由、負(fù)載均衡、服務(wù)監(jiān)控等等。這些問題都需要有相應(yīng)的技術(shù)來解決,這個時候,Spring Cloud就出現(xiàn)了。
簡單來說,Spring Cloud 提供了一些可以讓開發(fā)者快速構(gòu)建微服務(wù)應(yīng)用的工具,比如配置管理、服務(wù)發(fā)現(xiàn)、熔斷、智能路由等,這些服務(wù)可以在任何分布式環(huán)境下很好地工作。Spring Cloud 主要
致力于解決如下問題:
- Distributed/versioned configuration,分布式及版本化配置。
- Service registration and discovery,服務(wù)注冊與發(fā)現(xiàn)。
- Routing,服務(wù)路由。
- Service-to-service calls,服務(wù)調(diào)用。
- Load balancing,負(fù)載均衡。
- Circuit Breakers,斷路器。
- Global locks,全局鎖。
- Leadership election and cluster state,Leader 選舉及集群狀態(tài)。
- Distributed messaging,分布式消息。
需要注意的是,Spring Cloud 并不是 Spring 團(tuán)隊全新研發(fā)的框架,它只是把一些比較優(yōu)秀的解決微服務(wù)架構(gòu)中常見問題的開源框架基于 Spring Cloud 規(guī)范進(jìn)行了整合,通過 Spring Boot 這個
框架進(jìn)行再次封裝后屏蔽掉了復(fù)雜的配置,給開發(fā)者提供良好的開箱即用的微服務(wù)開發(fā)體驗。不難看出,Spring Cloud 其實就是一套規(guī)范,而 Spring Cloud Netflix、Spring Cloud Consul、Spring CloudAlibaba 才是 Spring Cloud 規(guī)范的實現(xiàn)。
為什么Spring Cloud是基于Spring Boot
那為什么Spring Cloud會采用Spring Boot來作為基礎(chǔ)框架呢?原因很簡單
- Spring Cloud它是關(guān)注服務(wù)治理領(lǐng)域的解決方案,而服務(wù)治理是依托于服務(wù)架構(gòu)之上,所以它仍然需要一個承載框架
- Spring Boot 可以簡單認(rèn)為它是一套快速配置Spring應(yīng)用的腳手架,它可以快速開發(fā)單個微服務(wù)
在微服務(wù)架構(gòu)下,微服務(wù)節(jié)點越來越多,需要一套成熟高效的腳手架,而Spring Boot正好可以滿足這樣的需求,如下圖所示。
Spring Boot的四大核心機制
如果一定要基于Spring Boot的特性去說,那么只能去說Spring Boot的四大核心機制,分別是@EnableAutoConfiguration 、 Starter開箱即用組件、Actuator應(yīng)用監(jiān)控、Spring Boot CLI 命令行工具。
EnableAutoConfiguration
Starter
告訴Spring Boot需要什么功能,它就能引入需要的庫。
Actuator
讓你能夠深入運行中的Spring Boot應(yīng)用程序
Spring Boot CLI
Spring Boot CLI 為Spring Cloud 提供了Spring Boot 命令行功能。我們可以通過編寫groovy腳本來運行Spring Cloud 組件應(yīng)用程序。步驟如下、
下載spring-boot-cli
Spring Boot CLI:https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.2.6.RELEASE/spring-boot-cli-2.2.6.RELEASE-bin.zip
配置環(huán)境變量
在控制臺
spring --version
查看CLI版本使用CLI運行應(yīng)用。我們可以使用run命令編譯和運行Groovy源代碼。Spring Boot CLI中包含所有運行Groovy所需要的依賴。
創(chuàng)建一個
hello.groovy
文件@RestControllerclass HelloController {@GetMapping("/hello")String hello(){ return "Hello World";}}
在控制臺執(zhí)行
spring run hello.groovy
,如果需要傳遞參數(shù),比如端口,和JVM參數(shù)類似spring run hello.groovy -- --server.port=9000
Spring Boot的四大核心特性
EnableAutoConfiguration
Starter
Actuator
Spring Boot CLI
Spring Boot CLI 為Spring Cloud 提供了Spring Boot 命令行功能。我們可以通過編寫groovy腳本來運行Spring Cloud 組件應(yīng)用程序。步驟如下、
- 下載spring-boot-cli
Spring Boot CLI:https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.2.6.RELEASE/spring-boot-cli-2.2.6.RELEASE-bin.zip
配置環(huán)境變量
在控制臺
spring --version
查看CLI版本使用CLI運行應(yīng)用。我們可以使用run命令編譯和運行Groovy源代碼。Spring Boot CLI中包含所有運行Groovy所需要的依賴。
- 創(chuàng)建一個
hello.groovy
文件
@RestControllerclass HelloController { @GetMapping("/hello") String hello(){ return "Hello World"; }}
- 在控制臺執(zhí)行
spring run hello.groovy
,如果需要傳遞參數(shù),比如端口,和JVM參數(shù)類似
spring run hello.groovy -- --server.port=9000