其實我接觸 Spring Boot 的時間並不長,因此還算一個初學者,這篇文章也算是我對 Spring Boot 學習以及使用過程當中的覆盤,若是文章出現描述錯誤或表達不清晰的地方,歡迎你們在評論區留言互動。php
沒想到 Spring Boot 這兩年居然普及的這麼快, 兩年前剛畢業的時候,由於待的是二線城市的小公司,公司的技術棧並不追求新穎,而是追求穩定、能用就行的理念,因此項目上就一直使用傳統的 SSM、SSH。java
當搭建後端框架時,須要手動添加 Maven 配置、各類 XML 配置,反正就是一個項目建立就要配置一遍,從我兩年前寫的這篇 SSM框架搭建,就能夠看出該過程是有多麼的繁瑣,甚至有時候由於配置錯誤以至於一上午就又能夠愉快的划水了...mysql
而項目部署時也是頭大,首先須要安裝 Tomcat,而後將項目編譯打包成 war 包,再將 war 包放在 Tomcat 的 webapp 目錄下部署運行,這個過程就以爲很不方便...web
彙總一下構建一個傳統項目須要的步驟:面試
由於如上種種問題,當一接觸到 Spring Boot 後就被它簡單的操做吸引了...redis
真羨慕如今的小夥伴,一上來就是用的 Spring Boot 了~ 不用再像我那會同樣。spring
Spring Boot 的出現大大簡化了傳統 Web 框架的搭建過程,提升了開發效率,Spring Boot 總結後有如下幾個特色:sql
這幾個特色基本上也是面試 Spring Boot 時常問的,也正是由於這幾個特色讓以前繁瑣的搭建過程變的簡單。數據庫
咱們都知道,特色並非解決問題的關鍵,因此咱們要了解,Spring Boot 究竟是如何解決問題的。apache
以前咱們使用 XML 方式時,有至關大的部分就是對 Bean 進行初始化並配置,好比下面這一段就是配置數據庫鏈接信息:
<!-- 配置 數據源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.211.55.4:3306/test" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
而使用 Spring Boot 後,會根據某些約定的規則對全部配置的 Bean 進行初始化,也就是約定優於配置,而後有的小夥伴就會問,那麼什麼是約定優於配置呢?
約定優於配置能夠這樣理解:
舉例說明:
不符合規定的部分:例如,若是模型中有個名爲 User 的類,那麼數據庫中對應的表就會默認命名爲 user。只有在偏離這一約定時,例如將該表命名爲 「user_info」,才需寫有關這個名字的配置。
規定默認配置的地方:
是否對這個 yml 或者 properties 文件中配置了信息就實現了配置有點好奇?
咱們仍是以數據庫鏈接信息爲例:在 Spring Boot 中有一個 DataSourceAutoConfiguration 配置類,這個類會自動查找 application.yml 或者 properties 文件裏的 spring.datasource.* 路徑,而後相關屬性會自動配置到數據源中。這個過程就屬於約定大於配置,若是感興趣的小夥伴能夠進入這個類看看。
Spring Boot 應用程序能夠不用部署到外部容器中,好比 Tomcat。Spring Boot 應用能夠直接經過 Maven 命令將項目編譯成可執行的 jar 包,經過 java -jar 命令啓動便可,很是方便。
怎麼不須要 Servlet 容器就啓動起來了呢?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
只要加上這個依賴,Spring Boot 就幫咱們默認內嵌了 Tomcat,固然一樣也支持修改,好比可使用 jetty(見標籤7修改默認內置的Tomcat容器)。
內嵌就內嵌了吧,簡單看一下 Tomcat 在 Spring Boot 中是如何啓動的。`
應用監控是項目部署中必不可少的環節,之前咱們怎麼知道系統實際運行的狀況呢?
須要咱們人爲的進行運維監控,好比對 cpu、內存、數據庫鏈接等監控。若是是對系統接口,那麼可能會單獨寫個測試接口來判斷當前應用的健康程度,固然,大部分狀況接口只要返回200就認爲當前應用是健康的。
可是這種狀況會存在很大的問題,首先前者會浪費人力資源,後者則由於固定接口形式沒法真正意義上判斷應用的健康狀態。
而 Spring Boot 中提供了一個用於監控和管理自身應用信息的模塊—Actuator,經過 Actuator,能夠實現對程序內部運行狀況進行監控,好比 Bean 加載狀況、環境變量、日誌信息、線程信息等。固然也能夠自定義跟業務相關的監控,經過 Actuator 的端點信息進行暴露。這個有點 DevOps 的意思。
如何集成到 Spring Boot 中呢?
只須要在 pom.xml 中添加以下依賴便可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
應用啓動則直接能夠訪問:
application配置文件中可配置的參數:
management:
endpoints:
web:
# actuator的訪問路徑,替換默認/actuator
base-path: /monitor
# 設置是否暴露端點 默認只有health和info可見
exposure:
# include: env # 方式1: 暴露端點env,配置多個以,隔開
include: "*" # 方式2: 包括全部端點,注意須要添加引號
# 排除端點,若是不排除則只須要訪問該應用的/shutdown 端點就能實現關閉該應用的遠程操做
exclude: shutdown
server:
port: 8888 #新開監控端口,不和應用用同一個端口,
endpoint:
health:
show-details: always # 顯示db、redis、rabbti鏈接狀況等
shutdown:
enabled: true #默認狀況下,除shutdown之外的全部端點均已啓用。手動開啓
按照如上配置則訪問路徑爲:http://localhost:8888/monitor
咱們能夠看到有不少節點(圖中省略),這些結點被稱做 端點,以下是這些端點的描述:
ID | 描述 | 默認啓用 | 默認公開 |
---|---|---|---|
auditevents |
公開當前應用程序的審計事件信息 | Yes | No |
beans |
顯示應用程序中全部Spring bean的完整列表 | Yes | No |
conditions |
顯示在配置和自動配置類上評估的條件以及它們是否匹配的緣由 | Yes | No |
configprops |
顯示全部@ConfigurationProperties 對照的列表 |
Yes | No |
env |
從Spring的ConfigurableEnvironment 中公開屬性 |
Yes | No |
flyway |
顯示已應用的任何Flyway數據庫遷移 | Yes | No |
health |
顯示應用程序健康信息 | Yes | Yes |
httptrace |
顯示HTTP跟蹤信息(默認狀況下,最後100個HTTP請求-響應交互) | Yes | No |
info |
顯示任意應用程序信息 | Yes | Yes |
loggers |
顯示和修改應用程序中記錄器的配置 | Yes | No |
liquibase |
顯示已應用的任何Liquibase數據庫遷移 | Yes | No |
metrics |
顯示當前應用程序的「指標」信息 | Yes | No |
mappings |
顯示全部@RequestMapping 路徑對照的列表 |
Yes | No |
scheduledtasks |
顯示應用程序中調度的任務 | Yes | No |
sessions |
容許從Spring Session支持的會話存儲中檢索和刪除用戶會話 | Yes | No |
shutdown |
讓應用程序優雅地關閉 | No | No |
threaddump |
執行線程轉儲 | Yes | No |
如上所知,若是想顯示應用程序健康信息,那麼就訪問 health 端點,即:
http://127.0.0.1:8888/monitor/health
其餘的你們能夠自行嘗試看一下,額外須要注意的是 shutdown 端點,項目中必定要排除,不然只須要訪問該應用的 /shutdown 端點就能實現該應用的遠程關閉操做,十分危險。
這就完了?
顯然不是,上邊這樣直接訪問端點,而後返回 JSON 數據,顯然很不直觀,畢竟如今很流行可視化嘛~ 咳咳。
因此這時候咱們能夠經過 Spring Boot Admin 來對 actuator 返回的這些數據進行整理。
關於 Spring Boot Admin 的介紹:
Spring Boot Admin 是用於管理和監控 Spring Boot 應用程序運行狀態的。在 Spring Boot 項目中能夠經過集成 Spring Boot Admin Client 向 Spring Boot Admin Server 進行註冊(經過 HTTP),這樣咱們就能夠在 Spring Boot Admin Server 統一管理 Spring Boot 應用。可視化是端點之上的 Vue 項目。
提供功能以下:
使用 Spring Boot Admin 也是很是的簡單,直接添加以下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.3.0</version>
</dependency>
配置文件以下:
spring:
boot:
admin:
# 修改上下文路徑
context-path: /admin
client:
url: http://127.0.0.1:${server.port}/admin
再在啓動類上加上 @EnableAdminServer 註解,齊活,完事。
經過如上界面,咱們能夠清楚的看到應用的名稱和 IP 端口信息,應用名稱是默認的,也能夠在配置文件中經過 spring.application.name 來自定義名稱。
咱們還能夠點擊服務信息進去查看詳情,左邊是對應的功能菜單,右邊是數據展現的頁面。詳情中有健康信息、線程信息、JVM 內存等信息,都經過圖形的方式展現,一目瞭然。
經過左側功能菜單能夠看到還有 日誌、JVM、緩存 等管理功能,你們能夠點點看看。
關於 Spring Boot Starter 相信你們必定不陌生,不少第三方工具的引入都是涉及到 Starter 包,Starter 包能夠說是 Spring Boot 中的核心功能,Starter 的出現,簡化了 Spring 不少工做。不懂就問環節:什麼是 Starter?`
總之,Starter 包簡化框架集成難度,將 Bean 的自動裝配邏輯封裝在 Starter 包內部,同時也簡化了 Maven Jar 包的依賴,對框架的集成只須要加入一個 Starter 包的配置,下降了煩瑣配置的出錯概率。
以下是 Spring Boot 提供的開箱即用 Starter 包:
starter | desc |
---|---|
spring-boot-starter-web |
用於快速構建Web,包含 RESTful 風格框架、SpringMVC和默認的嵌入式容器Tomcat |
spring-boot-starter-test |
用於測試 |
spring-boot-starter-data-jpa |
帶有Hibermate的Spring Data JPA,用於操做數據庫。 |
spring-boot-starter-jdbc |
傳統的JDBC支持 |
spring-boot-starter-thymeleaf |
支持Thymeleaf模板 |
spring-boot-starter-mail |
支持Java Mail、Spring Email 發送郵件 |
spring-boot-starter-integration |
Spring框架建立的一個API,面向企業應用集成(EAI) |
spring-boot-starter-mobile |
SpringMVC的擴展,用來簡化手機上的Web應用程序開發 |
spring-boot-starter-data-redis |
快速整合並操做 Redis:經過Spring Data Redis、Redis Client使用Redis |
spring-boot-starter-validation |
Bean Validation是一個數據驗證的規範,Hibernate Validator是一個數據驗證框架 |
spring-boot-starter-websocket |
相對於非持久的協議HTTP,Websocket 是一個持久化的協議 |
spring-boot-starter-web-services |
SOAP Web Services |
spring-boot-starter-hateoas |
爲服務添加HATEOAS功能 |
spring-boot-starter-security |
用Spring Security進行身份驗證和受權 |
spring-boot-starter-data-rest |
用Spring Data REST公佈簡單的REST服務 |
建立 Spring Boot 有兩種方式:
工具環境 IDEA,下文是基於 Spring Initializr 腳手架建立。
經過 IDEA 建立 Spring Boot 項目實在是太簡單了:
關於下一步以後,無非就是選擇建立項目的方式(Maven/Gradle),Spring Boot 版本(2.2.2.RELEASE),引入的依賴(Web/SQL/NoSQL/Security等),在這就不贅述了。
Spring Boot 項目打包無非就 「打 jar 包、打 war 包」 這兩種狀況,這二者的應用場景不一樣,各有優缺點。
jar 包部署優勢:
jar 包部署缺點:
war 包部署優勢:
war 包部署缺點:
至於最終選擇哪一個,本文不追究,畢竟都是要根據實際項目來講的。
以打 jar 包爲例:
首先須要在 pom.xml 文件中配置 spring-boot-maven-plugin 打包插件,也就是咱們一般看到的:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
這樣就能夠在 Tmerinal 控制檯經過 maven 命令進行打包了:mvn package
或者是能夠直接在 IDEA 右側的 Maven 標籤:
有小夥伴可能好奇,難道不須要設置 <packaging>jar</packaging>
嗎?
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<packaging>jar</packaging>
...
</project>
其實默認的 就是 jar 方式。
一般在實際開發中,每每涉及到好幾個環境,好比開發環境、本地環境、測試環境等等,一般不一樣環境下的配置信息是不同的「好比端口號?數據庫鏈接信息等」,由於咱們每次只能使用一個配置環境,若是頻繁的修改配置以達到效果,天然是麻煩的不行,且很容易出錯。
而在 Spring Boot 中,咱們能夠經過 spring.profiles.active 來激活對應的配置文件。
好比建立以下三個文件:
application.yml「主文件」
咱們想要使用 dev 開發環境,只須要在 application.yml 中使用 spring.profiles.active=dev 就能夠完成指定:
spring:
profiles:
active: dev
儘管Spring Boot內置了 Tomcat ,可是在高併發場景下的 Tomcat 相對來講比較弱。好比在相同的機器配置下,模擬相等的請求數,Undertow在性能和內存使用方面都是最優的。而且Undertow新版本默認使用持久鏈接,這將會進一步提升它的併發吞吐能力。因此,若是是高併發的業務系統,Undertow 是最佳選擇。
問題是怎麼替換?
由於 spring-boot-starter-web 中默認自帶的容器是 Tomcat,若是想要替換成 Undertow 也是很是簡單的。
首先須要排除 spring-boot-starter-web 包中的 Tomcat,而後單獨增長 undertow 容器的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除Tomcat依賴 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加 Undertow依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
之前讀取 spring 的配置文件,都是經過工具類類讀取,其實無非就是讀取 xml 文件,好比,經過 ClassPathXmlApplicationContext 加載到文件,而後再經過 上下文拿到 對應的Bean,再取參等。
而在 Spring Boot 中讀取配置文件有三種方式:
Environment
@Value
@ConfigurationProperties
咱們一一看看這三種方式:
application.yml 中的模擬數據:
niceyoo:
name: 張三
age: 24
Environment 用於管理當前的應用環境信息,定義了獲取 Profile 的方法,同時繼承了 PropertyResolver,PropertyResolver 提供了屬性訪問的相關方法。
也就是咱們可使用 Environment 的 getProperty() 方法讀取指定配置 Key 的內容。
代碼中體現:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private Environment environment;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
String name = environment.getProperty("niceyoo.name");
Integer age = Integer.valueOf(environment.getProperty("niceyoo.age"));
System.out.println(name+" " +age);
}
}
@Value 方式就簡單多了,直接在接收的屬性上加上該註解便可:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Value("niceyoo.name")
private String name;
@Value("niceyoo.age")
private Integer age;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
System.out.println(name+" " +age);
}
}
使用該註解能夠直接注入到實體類中,方便值的同一管理。
好比咱們建立一個 Model 實體類,定義 name、age 屬性,而後實現 get\set 方法,再在實體類上加上 @Configuration 和 @ConfigurationProperties(prefix="niceyoo") 註解,並指定前綴爲 niceyoo。
@Configuration
@ConfigurationProperties(prefix="niceyoo")
public class Model {
private String name;
private Integer age;
省略get、set方法
}
這樣就能夠將 niceyoo 下面的值直接對應到實體上了,其中加入 @Configuration 註解,咱們在使用時能夠直接經過 @Autowired 進行注入。
取值代碼:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private Model model;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
System.out.println(model.getName()+" " +model.getAge());
}
}
之前 Spring 主打輕量級應用框架,但隨着外界不斷地進行擴充,像是 Shiro、Security、MQ、Redis、ElasticSearch 等等等等, 總之就是 Spring 幾乎能夠作任何事了,可是相應的問題也來了。
Spring 每集成一個第三方軟件,就須要手動增長一些配置,隨着新軟件的加入,以致於須要引入愈來愈多的配置,且這些配置各玩各的,難以理解,難以管理,我記得我實習時的那家公司就是這樣,各類五花八門的配置文件,以致於常常配置出錯,而後解決配置相關的問題就須要很久。
工欲善其行,必先利其器。
Spring Boot 的出現能夠說真正的顛覆了之前傳統的 Web 項目,開發人員不再用配置繁瑣的 xml 文件了,簡直是解放了雙手,整個項目的配置文件也變得簡潔了。
正所謂簡潔並不意味着簡單,Spring Boot 只是將衆多複雜的功能進行了封裝,讓咱們在使用的時候足夠的簡單。
關於 Spring Boot 的知識點能夠說太多太多了,文中只是把本身能想到的幾點描述了出來。`