本文是 Spring Boot 基礎知識複習手冊,總共 2w 字,可以先收藏、轉發。有需要的時候查閱,本文設計的知識包括:配置常用注解、Spring Boot 自動配置、配置原理、如何修改預設配置、靜态資源處理、Rest映射、Spring Boot 常用注解、檔案上傳、攔截器、錯誤處理、資料層整合:MyBatis、JDBC、Druid、Redis等等。
01
配置注解
@Configuration & @Bean
Spring Boot不同于傳統的Spring,它不提倡使用配置檔案,而是使用配置類來代替配置檔案,是以該注解就是用于将一個類指定為配置類:
在配置類中使用方法對元件進行注冊,它的效果等價于:
需要注意的是 Spring Boot 預設會以方法名作為元件的id,也可以在 @Bean() 中指定value值作為元件的id。
@Import
在Spring中,我們可以使用@Component、@Controller、@Service、@Repository注解進行元件的注冊,而對于一些第三方的類,我們無法在類上添加這些注解,為此,我們可以使用@Import注解将其注冊到容器中。
通過@Import注解注冊的元件,其id為全類名。
@Conditional
該注解為條件裝配注解,大量運用于SpringBoot底層,由該注解衍生出來的注解非常多:

這裡以@ConditionalOnBean和@ConditionalOnMissingBean舉例。其中@ConditionalOnBean注解的作用是判斷目前容器中是否擁有指定的Bean,若有才生效,比如:
若如此,則SpringBoot在注冊User對象之前,會先判斷容器中是否已經有id為 dog 的對象,若有才建立,否則不建立。@ConditionalOnBean注解共有三種方式判斷容器中是否已經存在指定的對象,除了可以判斷元件的id外,也能夠通過判斷元件的全類名:
還可以通過判斷元件的類型:
尤其需要注意的是,因為代碼是從上至下依次執行的,是以在注冊元件時的順序要特别注意,比如:
在這段程式中,SpringBoot會先注冊User對象,而此時Dog對象還沒有被注冊,是以會導緻User對象無法注冊。
而@ConditionalOnMissingBean注解的作用與@ConditionalOnBean注解正好相反,它會判斷目前容器中是否不存在指定的Bean,若不存在則生效,否則不生效。
這些注解除了能夠标注在方法上,還能作用于類上,當被标注在類上時,若條件成立,則配置類的所有注冊方法生效;若條件不成立,則配置類的所有注冊方法均不成立。
@ImportResource
該注解用于導入資源,比如現在有一個Spring的配置檔案:
若是想将其轉化為配置類,代碼少一點倒還好說,當配置檔案中注冊的Bean非常多時,采用人工的方式顯然不是一個好的辦法,為此,SpringBoot提供了@ImportResource注解,該注解可以将Spring的配置檔案直接導入到容器中,自動完成元件注冊。
@ConfigurationProperties
該注解用于配置綁定,也大量運用于SpringBoot底層。首先在配置檔案中編寫兩個鍵值:
然後使用該注解将其綁定到User類上:
但結果卻有些出乎意料:
這是因為我們将字首 prefix 指定為了user,而user可能和我們的系統配置産生了重複,是以導緻了這個問題,此時我們隻需将字首修改一下即可:
字首修改了,配置檔案的内容也需要做相應的修改:
需要注意的是,若是想實作配置綁定,就必須要将這個待綁定的類注冊到容器中,比如使用@Component注解,當然,SpringBoot也提供了一個注解與其配套使用,它就是:@EnableConfigurationProperties 。
該注解必須标注在配置類上:
作用是開啟指定類的配置綁定功能,它的底層其實也是通過@Import注解實作的,此時User類就無需将其注冊到容器中:
Spring Boot 會自動将屬性值綁定到 User 類,并将其注冊到容器中。Spring Boot 相關的技術文章我整理成了 PDF,關注微信公衆号「Java後端」回複「666」下載下傳這一本技術棧手冊。
02
自動配置原理
有了前面的注解基礎之後,我們就能夠更深入地了解Spring Boot的自動配置原理,自動配置正是建立在這些強大的注解之上的。
我們首先觀察一下主啟動類上的注解:
翻閱源碼可以得知,@SpringBootApplication注解其實是由三個注解組成的:
其中@SpringBootConfiguration底層是@Configuration注解,它表示主啟動類是一個配置類;而@ComponentScan是掃描注解,它預設掃描的是主啟動類目前包及其子包下的元件;最關鍵的就是@EnableAutoConfiguration注解了,該注解便實作了自動配置。
檢視@EnableAutoConfiguration注解的源碼,又會發現它是由兩個注解組合而成的:
我們繼續檢視@AutoConfigurationPackage注解的源碼:
@Import注解我們非常熟悉,它是用來導入一個元件的,然而它比較特殊:
這裡的 Registrar 元件中有兩個方法,它是用來導入一系列元件的,而該注解又被間接标注在了啟動類上,是以它會将主啟動類所在包及其子包下的所有元件均注冊到容器中。
接下來我們繼續看@EnableAutoConfiguration的第二個合成注解:@Import({AutoConfigurationImportSelector.class}) 該注解也向容器中注冊了一個元件,翻閱該元件的源碼:
這個方法是用來選擇導入哪些元件的,該方法又調用了getAutoConfigurationEntry()方法得到需要導入的元件,是以我們檢視該方法:
在getCandidateConfigurations()方法處打一個斷點,通過debug運作後我們可以發現,configurations集合中就已經得到了127個自動配置類:
那麼這些類究竟從何而來呢?我們需要探究一下getCandidateConfigurations()方法做了什麼操作,它其實是調用了loadFactoryNames()方法:
最終調用的是loadSpringFactories()方法來得到一個Map集合:
可以看到,它其實是從 META-INF/spring.factories 檔案中擷取的元件,我們可以看看導入的依賴中:
在spring-boot-autoconfigure-2.3.7.RELEASE.jar的META-INF目錄下就有一個spring.factories檔案,打開看看檔案内容:
檔案裡的内容其實就是在最開始需要注冊的元件,這些元件都是一些配置類,隻要項目一啟動,Spring Boot就會将這些配置類全部注冊到容器中。
按需開啟自動配置
雖然配置類會被 Spring Boot 自動注冊到容器中,但并不是每個配置類都會預設生效,SpringBoot會根據目前的場景按需開啟自動配置。比如Thymeleaf模闆引擎的自動配置類:
@ConditionalOnClass注解的作用是檢查目前項目是否有指定的.class檔案,若有則生效;否則不生效。因為我們并未引入Thymeleaf的依賴,導緻TemplateMode.class和SpringTemplatengine.class都是不存在的,是以ThymeleafAutoCinfiguration并不會生效。
修改預設配置
既然SpringBoot幫助我們進行了大量的自動配置,那麼對于特殊的一些應用場景,我們該如何修改它的預設配置呢?如果你不了解SpringBoot的配置原理,那麼當你需要修改預設配置時,你肯定是束手無策的。我們可以找到SpringMVC的預設配置,看看SpringBoot是如何幫我們進行配置的:
@EnableConfigurationPropertie(WebMvcProperties.class)注解在之前也有介紹,它是用來開啟指定類的配置綁定的,是以我們來看看WebMvcProperties類:
配置綁定的字首時spring.mvc,是以我們若是想修改SpringBoot的預設配置,則必須要将字首寫為spring.mvc,至于我們可以修改哪些配置,隻需要檢視該類中有哪些成員變量即可,比如:
在WebMvcProperties類中有這樣一個内部類,内部類中有prefix和suffix兩個成員變量,它們是分别用來設定視圖的字首和字尾的,是以我們若想進行配置,則需要在配置檔案中這樣編寫:
傳統的Spring開發Web需要編寫大量的配置,而使用SpringBoot将免去編寫配置的操作,直接面向業務邏輯開發,一起來看看該如何使用SpringBoot進行Web開發吧!
03
Web開發
靜态資源處理
Spring Boot預設設定了幾個靜态資源目錄:
/static
/public
/resources
/META-INF/resources
這幾個目錄需要建立在類路徑下,若如此做,則放置在這些目錄下的靜态資源可以被直接通路到。
也可以通過配置來設定資源的通路字首:
此時若想通路靜态資源,就必須添加res字首才行。
我們還可以修改Spring Boot的預設資源路徑,隻需添加配置:
若如此做,則我們隻能将靜态資源放在myImg目錄下,之前的所有靜态資源目錄都将失效。
歡迎頁
Spring Boot提供了兩種方式來實作歡迎頁,第一種便是在資源目錄放置歡迎頁:
通路結果:
第二種方式是通過Controller處理/index請求:
Spring Boot也提供了自動設定網站圖示的方式,隻需要将名為 favicon.ico 的圖檔放在靜态資源目錄下即可:
Rest映射
在Spring Boot中,預設已經注冊了HiddenHttpMethodFilter,是以可以直接編寫Rest風格的url,隻需在表單中添加一個_method屬性的請求域即可:
編寫Controller處理請求:
最後需要在配置檔案中開啟對Rest的支援:
04
常用參數及注解
下面介紹Web開發中的一些常用參數和注解。
該注解用于擷取路徑變量,比如:
此時若請求url為http://localhost:8080/user/2,則擷取到id值為2。
該注解用于擷取請求頭,比如:
它還能夠通過一個Map集合擷取所有的請求頭資訊:
該注解用于擷取請求參數,比如:
此時若請求url為http://localhost:8080/param?name=zhangsan&age=20,則得到值 zhangsan:20 。
該注解用于擷取Cookie值,比如:
它還可以通過Cookie鍵名擷取一個Cookie對象:
該注解用于擷取擷取請求體的值,比如:
既然是擷取請求體的值,那麼隻有Post請求才有請求體,是以編寫一個表單:
通過該表單送出資料後,得到 username=admin&password=123 。
該注解用于擷取request域的資料,比如:
通過鍵名即可擷取request域中的資料。
該注解用于擷取矩陣變量,比如:
對于該注解的使用,需要注意幾點,首先矩陣變量是綁定在路徑中的,是以請求映射中一定要攜帶一個${path};其次在SpringBoot中預設禁用掉了矩陣變量的功能,是以我們還需要手動去開啟該功能:
此時通路請求url:http://localhost:8080/matrix/test;name=zhangsan;age=20, 得到結果:test---zhangsan:20 。
05
攔截器
一個完善的Web應用一定要考慮安全問題,比如,隻有登入上系統的使用者才能檢視系統内的資源,或者隻有具備相關權限,才能通路對應的資源,為此,我們需要學習一下攔截器,通過攔截器我們就能夠實作這些安全認證。
這裡以登入檢查為例:
編寫好攔截器後需要将其配置到容器中:
需要指定該攔截器需要攔截哪些資源,需要放行哪些資源,這樣一個簡單的登入校驗就完成了。
06
檔案上傳
Spring Boot中該如何實作檔案上傳呢?現有如下的一個表單:
通過@RequestPart注解即可将上傳的檔案封裝到MultipartFile中,通過該對象便可以擷取到檔案的所有資訊。輸出結果:
若是上傳多個檔案,則先修改表單資訊:
在檔案框位置添加multiple屬性即可支援多檔案上傳,然後修改控制器代碼:
若是需要将上傳的檔案儲存到伺服器,則可以如此做:
因為Spring Boot預設的檔案上傳大小限制為1MB,是以隻要檔案稍微大了一點就會上傳失敗,為此,可以修改SpringBoot的預設配置:
07
錯誤處理
預設情況下,SpringBoot應用出現了異常或錯誤會自動跳轉至/error頁面,也就是這個熟悉的頁面:
然而一般情況下,我們都不會選擇出異常時顯示這個頁面,而是想要顯示我們自己定制的頁面,為此,我們可以在/static或/templates目錄下建立一個error目錄,并在/error目錄下放置命名為4xx、5xx的頁面,SpringBoot會自動幫助我們解析。
此時當出現5xx的異常時,SpringBoot會自動跳轉至5xx.html頁面,當然你也可以對每個狀态碼都做一個頁面進行對應,比如放置500.html、501.html、502.html檔案,當伺服器出現對應的異常時,就會跳轉至對應的頁面。
08
資料層
下面, 我們将探究SpringBoot與資料通路層架構的整合與使用。Spring Boot 與其他第三方中間件整合的技術文章也釋出過,我整理成了 PDF,關注微信公衆号「Java後端」回複「666」下載下傳這一本技術棧手冊。
若想使用原生的JDBC進行開發,SpringBoot已經為我們配置好了JDBC的相關資訊,隻需要引入依賴:
Spring Boot 底層自動配置了HikariDataSource資料源,是以我們隻需指定資料源的位址、使用者名和密碼即可:
因為SpringBoot已經自動配置好了JdbcTemplate,是以我們直接使用就可以了:
若是不想使用Spring Boot底層的資料源,我們也可以修改預設配置,以Druid資料源為例,首先引入依賴:
并對Druid進行配置:
此時通路http://localhost:8080/druid,将會來到Druid的監控頁:
接下來我們将整合MyBatis架構,并介紹它的簡單使用。首先引入依賴:
然後編寫Mapper接口:
編寫Mappe配置檔案:
最後配置一下MyBatis:
這樣就可以使用MyBatis了:
若是想要整合Redis,也非常地簡單,首先引入依賴:
然後進行配置:
隻需要配置Redis的主機位址就可以操作Redis了,操作步驟如下:
若是想使用Jedis操作Redis,則需要導入Jedis的依賴:
并配置: