該階段的學習可以配置設定兩部分:SpringBoot階段的學習以及微服務部分的學習。SpringBoot部分主要是幾個點,會進行項目的配置、編寫SpringBoot程式、整合Mybatis、整合資料源、整合安全架構、整合Swagger。微服務階段的學習主要是明白微服務的思想,以及會用Dubbo和ZooKeeper進行整合。我們後面還會學習SpringCloud,這是兩套不同的方式,是以這個階段的學習,不僅要會用,個人覺得一定要多看文檔資料,因為裡面涉及到的東西,不是簡單的幾行代碼就能夠說明的。願你學習完這一部分知識,對整個java階段的學習認識又上一個新的台階!!!
文章目錄
-
- 1、微服務概述
- 2、建立SpringBoot程式
-
- 2.1、建立SpringBoot程式
- 2.2、項目的要點
- 2.3、自動裝配原理
- 3、SpringBoot配置
-
- 3.1、yaml配置
- 3.2、使用yaml進行屬性注入
- 3.3、使用properties進行屬性注入
- 3.4、@ConfigurationProperties與@Value的對比
- 3.5、核心配置檔案的優先級
- 3.6、配置環境的切換
- 4、SpringBoot Web開發
-
- 4.1、靜态資源的導入問題
- 4.2、首頁的定制
- 4.3、Thymeleaf模闆引擎
- 4.4、裝配SpringMVC
- 5、整合JDBC
- 6、整合Druid資料源
-
- 6.1、配置資料源對應的資訊
- 6.2、編寫資料源的背景監控
- 6.3、配置Druid Web監控的filter過濾器
- 7、整合Mybatis
- 8、SpringSecurity
- 9、Shiro
- 10、Swagger
- 11、任務
-
- 11.1、異步任務
- 11.2、定時任務
- 11.3、郵件任務
- 12、分布式Dubbo + ZooKeeper + SpringBoot
-
- 12.1、分布式理論
- 12.2、RPC
- 12.3、Dubbo
- 12.4、ZooKeeper
- 12.5、安裝環境
- 12.6、集中整合
- 13、思維導圖
1、微服務概述
這個階段注意幾個問題就行了
- 微服務的概念是什麼?
- SpringBoot是幹嘛的?
- SpringBoot有哪些特點?
- 為什麼會有SpringBoot的出現?
2、建立SpringBoot程式
2.1、建立SpringBoot程式
建立方式主要有兩種:
- 在官網選擇一個SpringBoot項目,然後下載下傳到本地,再用編譯器打開
- 使用IDEA內建的SpringBoot(幫我們封裝了第一種方式)
2.2、項目的要點
1、我們建立的包名,應該和項目的啟動類保持一個等級。
2、pom.xml檔案中是目前我們項目的各種資訊
- pom.xml:部分插件,可以顯式的定義對應的依賴(及對應的啟動器)
- pom.xml的父項目為:spring-boot-starter-parent(配置了資源過濾器,及插件)
- pom.xml的父項目的父項目:spring-boot-dependencies(配置了很多的版本資訊和啟動器。當我們在pom.xml中配置依賴時,可以不用指定對應的版本資訊,因為這些版本都可以在這裡中找到)
3、SpringBoot是内嵌了Tomcat伺服器的,并且預設使用的是Tomcat,内嵌的還有Jetty和UnderTow伺服器。
4、我們可以直接使用maven打包的工具将項目打包成jar包存放在本地,在使用java -jar運作項目
5、我們可以在配置檔案中修改項目的相關資訊,比如最基礎的端口号
6、修改SpringBoot項目啟動的圖示,在核心配置檔案的同級目錄下建立一個banner.txt檔案,放入指定的樣式即可
2.3、自動裝配原理
目前自己還看不懂,等把SpringBoot玩轉了,再來慢慢學習原理
啟動器的概念:
在我們的pom.xml檔案中,包含了一個啟動器。它類似于我們SpringBoot的啟動場景,比如:spring-boot-starter-web,系統就會幫我們自動導入web環境相關的所有的依賴。此時SpringBoot會将所有的功能場景都變成一個個啟動器,我們要做的就是找到對應的啟動器就可以了。
主程式的概念:
我們會發現主程式中有@SpringBootApplication注解,它白哦是我們這是一個SpringBoot應用程式。觀察主方法的方法體我們可以得出,SpringApplication.run()是一個靜态方法,并且傳入的其中一個參數是主程式的反射模闆類。
SpringApplication類主要做了以下四件事情
- 推斷應用的類型是普通的項目還是Web項目
- 查找并加載所有可用初始化器 , 設定到initializers屬性中
- 找出所有的應用程式監聽器,設定到listeners屬性中
- 推斷并設定main方法的定義類,找到運作的主類
3、SpringBoot配置
3.1、yaml配置
"YAML Ain’t a Markup Language"也可以簡寫成yml
你可以将yaml了解成properties、xml同級的一種文法,用于配置程式的資訊。不過SpringBoot更推薦我們使用yaml,我想yaml一定是有它獨特的優勢,不然官方也不會這麼推薦了。
基本格式:把properties的 . 變成 :外加換行後的兩個空格(切記格式規範)
server:
port: 8081
3.2、使用yaml進行屬性注入
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@Component
//該注解用于綁定對應的對象名
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
person:
name: 默辨
age: 23
happy: true
birth: 2020/03/16
maps: {key1: value1,key2: value2}
lists:
- eat
- sleep
- play
dog:
name: 小黃
age: 11
yaml的進階用法補充:
person:
name: 默辨${random.uuid} # 随機uuid
age: ${random.int} # 随機int
happy: true
birth: 2020/03/16
maps: {key1: value1,key2: value2}
lists:
- eat
- sleep
- play
dog:
name: ${person.hello:other}_小黃 #如果有值就輸出,沒有就使用預設值,再拼接_阿黃
age: 11
3.3、使用properties進行屬性注入
注意修改properties檔案的字元編碼,不然會出現亂碼
與使用yaml屬性注入的方式不同,我們使用properties時,在實體類上使用注解注解,引入對應的配置資訊即可
@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
//該注解,可以用來綁定我們自定義的配置檔案(配置檔案中包含我們設定好的屬性)
@PropertySource(value = "classpath:cat.properties")
@Component
public class Cat {
@Value("${cat.name}") //可以從配置檔案中取值
private String name;
@Value("#{2*3}") // #{SPEL} Spring表達式
private int age;
}
3.4、@ConfigurationProperties與@Value的對比
我們在使用的properties配置檔案進行屬性的注入時,可以使用兩種方式:
- @ConfigurationProperties(pre = “對象名”)
- @PropertySource(value = “classpath:配置檔案名”) + @Value("${對象.屬性}")
我們可以發現這是将屬性配置檔案與我們的pojo類綁定的兩種不同方式。第一種直接綁定對象名,即可完成自動的屬性注入。後者為指向配置檔案名字,然後使用@Value進行輸入的單個綁定,綁定的方式是使用SpEL表達式(Spring的EL表達式)。
依據個人喜好進行選擇。
不過我推薦使用第一種方式。第一種方式支援松散綁定(資料庫的字段與pojo屬性之間的轉換形式),支援複雜資料類型的封裝,還支援JSR3030校驗(@Validated來校驗資料,如果資料異常則會統一抛出異常,友善異常中心統一處理)。看起來代碼比較清爽,個人感覺!!!
配置類和核心配置檔案是互相比對的,
自動裝配的原理的核心要領:
- SpringBoot啟動會加載大量的自動配置類
- 我們首先看我們需要的功能有沒有在Spring Boot預設寫好的自動配置類當中;
- 我們再看這個自動配置類中到底配置了哪些元件;(隻要我們要用的元件存在在其中,我們就不需要再手動配置了)
- 給容器中自動配置類添加元件的時候,會從配置類中擷取某些屬性。我們隻需要在核心配置檔案中指定這些屬性的值即可;
xxxxAutoConfigurartion:自動配置類,給容器中添加元件
xxxxProperties:封裝配置檔案中相關屬性;
補充JSR303校驗的異常參數:
@NotNull(message="名字不能為空")
private String userName;
@Max(value=120,message="年齡最大不能查過120")
private int age;
@Email(message="郵箱格式錯誤")
private String email;
空檢查
@Null 驗證對象是否為null
@NotNull 驗證對象是否不為null, 無法查檢長度為0的字元串
@NotBlank 檢查限制字元串是不是Null還有被Trim的長度是否大于0,隻對字元串,且會去掉前後空格.
@NotEmpty 檢查限制元素是否為NULL或者是EMPTY.
Booelan檢查
@AssertTrue 驗證 Boolean 對象是否為 true
@AssertFalse 驗證 Boolean 對象是否為 false
長度檢查
@Size(min=, max=) 驗證對象(Array,Collection,Map,String)長度是否在給定的範圍之内
@Length(min=, max=) string is between min and max included.
日期檢查
@Past 驗證 Date 和 Calendar 對象是否在目前時間之前
@Future 驗證 Date 和 Calendar 對象是否在目前時間之後
@Pattern 驗證 String 對象是否符合正規表達式的規則
.......等等
除此以外,我們還可以自定義一些資料校驗規則
3.5、核心配置檔案的優先級
目前我們知道的核心配置檔案隻有一個那就是application.propertiest或者application.yaml,我們後面還會學習到一種bootstarp.properties或bootstarp.yaml
我們通常建立的核心配置檔案位置一般都在resources檔案下。
其實他可以建立在四個不同的位置,逐級覆寫,位置分别時:
- 在項目下建立一個config檔案夾,裡面建立核心配置檔案
- 直接在項目下建立核心配置檔案
- 在resources資源路徑下建立一個config檔案夾,裡面建立核心配置檔案
- 在resources資源路徑下,建立核心配置檔案
我們總結一下這個通路順序就是:從項目最開始的位置開始,在項目名路徑下遇到config檔案夾,就去裡面看,如果沒有就在項目名路徑下尋找配置檔案。如果也沒有找到那就去resources目錄下,重複剛才的過程。
3.6、配置環境的切換
由于我們在自己本地編寫代碼的環境和後期的上線環境是有些許差異的,是以我們需要能夠靈活的切換,當然我們這裡是在本地進行切換,未來有可能是在遠端的git上進行環境的切換。
server:
port: 8081
#選擇要激活那個環境塊
spring:
profiles:
active: prod
---
server:
port: 8083
spring:
profiles: dev #配置環境的名稱
---
server:
port: 8084
spring:
profiles: prod #配置環境的名稱
4、SpringBoot Web開發
4.1、靜态資源的導入問題
靜态資源即css、img、js檔案
兩種方式引入:
- 使用webjars方式,引入對應的依賴
- 在resources目錄下建立檔案夾
即靜态資源可以存放的位置為:
- 建立的public檔案夾下
- 自帶的static檔案夾下
- 建立的resources檔案夾下
- 根目錄下的/**
外部通路的優先級:resources > static(預設) > public
4.2、首頁的定制
建立一個首頁,檔案命名為index.html,可以根據适當的需求,自行放在public、static、templates等目錄的其中一個下
4.3、Thymeleaf模闆引擎
了解Thymeleaf可以對比JSP,JSP也是一種模闆引擎,它将後端傳過來的資料,以相應的形式渲染到前端,繼而達到前端顯示後端的資料。那我們這裡的Thymeleaf也就是同樣的功能,SpringBoot推薦我們使用Thymeleaf,隻是我們目前還不知道它的具體文法,是以我們感覺比較陌生。
使用步驟:
- 引入對應的命名空間,xmlns:th=“http://www.thymeleaf.org” 防止報異常看着礙眼
- 引入對應的依賴(2個)
- 編寫controller控制器類
- 編寫對應的前端界面
- 測試
基本文法:
- th:each:周遊
- th:utext:不文本形式顯示
- th:text:以文本的形式顯示
<!--如果msg資訊中含有html标簽,我們就将它進行轉譯-->
<div th:utext="${msg}"></div>
<!--将msg以文本的形式進行列印輸出-->
<div th:text="${msg}"></div>
<!--循環周遊users,将周遊出來的每一個元素命名為user,然後再把user以文本的形式進行列印輸出-->
<div th:each="user:${users}" th:text="${user}"></div>
4.4、裝配SpringMVC
按理說,我們不裝配已經能夠達到測試效果了,那這個配置又是出來幹嘛的呢?
我們回想一下之前的SpringMVC階段的學習,我們除了編寫對應的視圖跳轉以外,還會編寫一些視圖解析器(SpringMVC的視圖解析器我們可以自定義)、攔截器、格式化顯示…
我們現在就可以通過裝配SpringMVC來實作這一切配置的自定義,具體能夠重寫的方法,我們隻需要實作
WebMvcConfigurer
接口即可檢視。如果我們不去自定義,那麼我們就會使用SpringBoot預設的方法體。
5、整合JDBC
SpringBoot預設的Jdbc模闆使用的資料源是HikariDataSource
整合JDBC步驟:
- 勾選對應的依賴(MySQL驅動、JDBC API、Web啟動器)
- 使用IDEA連接配接對應的資料庫
- 在配置檔案中配置對應的資料庫資訊
- 編寫對應的控制器類進行測試
- 我們也可以編寫對應的Test類列印檢視資料源相應的資訊
6、整合Druid資料源
6.1、配置資料源對應的資訊
Druid 是阿裡巴巴開源平台上一個資料庫連接配接池實作,結合了 C3P0、DBCP 等 DB 池的優點,同時加入了日志監控
按照我們之前的說法,很多東西SpringBoot都是幫我們自動配置好的,有一個預設的選項,比如資料源預設就是HikariDataSource,但是我們覺得它功能不夠強大,我們就像引入自己自定義的資料源,比如阿裡巴巴幫我們定義好的Druid資料源。那麼我們就又需要編寫一個配置類,用來配置資料源
使用步驟:
- 引入對應的maven依賴
- 編寫一個配置類(在config包下,并使用@Configuration注解)
- 如果我們想要按照自己的需求自定義資料源資訊,那麼我們也可以在核心配置檔案中對資料源進行相應的配置(使用@ConfigurationProperties()注解進行資訊綁定)
- 在測試類中進行測試,觀察資料源資訊
6.2、編寫資料源的背景監控
添加對應的配置即可完成監控界面,至于為什麼這麼配置,我也說不上來。那就了解成規範就是這樣配置吧,先記住!!!
通路路徑:http://localhost:8080/druid
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// 這些參數可以在 com.alibaba.druid.support.http.StatViewServlet
// 的父類 com.alibaba.druid.support.http.ResourceServlet 中找到
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin"); //背景管理界面的登入賬号
initParams.put("loginPassword", "123456"); //背景管理界面的登入密碼
//背景允許誰可以通路
//initParams.put("allow", "localhost"):表示隻有本機可以通路
//initParams.put("allow", ""):為空或者為null時,表示允許所有通路
initParams.put("allow", "");
//deny:Druid 背景拒絕誰通路
//initParams.put("kuangshen", "192.168.1.20");表示禁止此ip通路
//設定初始化參數
bean.setInitParameters(initParams);
return bean;
}
然後在背景就可以檢視相應的操作對應的SQL語句了。
6.3、配置Druid Web監控的filter過濾器
過濾器可以了解成一張網,你可以選擇在哪些位置将網的孔弄小一點,哪些位置孔大一些,友善我們抓魚,這裡就是統計資訊。
//配置 Druid 監控 之 web 監控的 filter
//WebStatFilter:用于配置Web和Druid資料源之間的管理關聯監控統計
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//exclusions:設定哪些請求進行過濾排除掉,進而不進行統計
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
bean.setInitParameters(initParams);
//"/*" 表示過濾所有請求
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
7、整合Mybatis
我們前面說過整合JDBC,這裡又是整合Mybtis,我們是否可以聯想到我們之使用Mybatis代替了原生的JDBC?
整合Mybatis的主要步驟:
- 在JDBC依賴的基礎上,添加Mybatis的依賴
- 使用IDEA連接配接資料庫
- 在JDBC資料庫配置的基礎上,添加Mybatis的别名配置以及mapper檔案位置的配置
- 編寫對應的實體類
- 編寫對應的SQL語句的接口類
- 編寫對應接口類的mapper.xml檔案
- 編寫對應的控制器類
- 測試
我們不難發現,其實步驟大體上與Mybatis編寫查詢語句差不多(4、5、6、7、8),我們這裡的整合隻是将之前的mybatis-config.xml中的資訊轉移到了application.yaml檔案中,并添加對應的依賴
8、SpringSecurity
看到名字我們就應該明白,Spring安全,這是Spring為我們提供的安全模闆,我們隻需要添加對應的啟動器,然後在核心配置檔案中進行配置,最後再進行配置即可使用。雖然是這樣幾個步驟,但是我不會,哈哈,是以這裡就不說了!!!
Spring Security的兩個主要目标是“認證”和“授權”(控制通路)
我先記住這兩個概念吧,這在很多的安全架構中都是有這兩個概念的:
- 認證:Authentication
- 授權:Authorization
9、Shiro
與前面的SpringSecurity一樣,這個也是一個安全架構。
由于我對這兩個安全架構的了解都沒有太深,甚至沒有了解,不敢妄寫總結,不過有幾個點我們應該明确:
- 既然是新東西,那麼我們也需要拿出一部分時間去學習Shiro架構本身
- Shiro這個安全架構與SpringSecurity都是安全架構,不過Shiro是一個外來的
- 對于自家的架構,SpringBoot總歸是幫我們做了一些整合優化
- Shiro既然是外來的,那麼我們就應該和很多東西都需要整合,比如Mybatis、Thymeleaf,當然還有最重要的SpringBoot
- 安全在網絡中是一個比較重要的點,個人覺得應該盡可能的深入學習,而不是入門就完了
- 保證安全的具體安全形式,我們需要自己編寫對應的代碼
10、Swagger
讓代碼和程式一體化。
這是一個用于監控前後端接口的一門技術。現在大部分都是前後端分離,如果前端或後端有了相應的改變,卻沒有及時溝通,就有可能産生許多不必要的麻煩。Swagger就是用來讓前後端及時通信的。前後端分别将自己的代碼部署在Swagger上面,以此讓兩者能夠及時看見變化。
與SpringBoot整合步驟:
- 建立一個含有web依賴的SpringBoot項目
- 導入相關的依賴(2個)
- 編寫對應的配置類(内含我們每個人的資訊。友善前端及時檢視)
- 編寫對應的類
- 運作Swagger背景,檢視對應的類資訊
11、任務
11.1、異步任務
我們可以根據對應的配置,指定對應的異步任務。最終的效果為,前端與背景服務之間不是同步顯示的,前端先顯示,後端再出現相應的形式。
11.2、定時任務
這裡引入一個新的知識點:cron表達式
我們的程式會根據cron表達式設定的時間,進行對應時間的執行。就像我們的鬧鐘一樣
11.3、郵件任務
我們可以進行相應的配置,實作郵件的發送
12、分布式Dubbo + ZooKeeper + SpringBoot
終于到了最後一個知識點了
12.1、分布式理論
我們學習一個技術不能是僅僅學會用,更要學會背後的思想的轉變,是以個人覺得分布式的學習,需要輔助一些文檔資料才能對其核心理念有更加深入的了解
分布式系統是由一組通過網絡進行通信、為了完成共同的任務而協調工作的計算機節點組成的系統。分布式系統的出現是為了用廉價的、普通的機器完成單個計算機無法完成的計算、存儲任務。其目的是利用更多的機器,處理更多的資料
12.2、RPC
RPC(Remote Procedure Call)指遠端過程調用,是一種程序間的通信方式,它不是一種技術思想,而是一種規範。它允許程式掉用另一個位址空間(通常是共享網絡的另一台機器上)的過程函數。
舉個簡單的例子,我們本地編寫一個方法需要使用一個Student的實體類,如果是以前,我們可能就在pojo包下建立了實體類了。但是現在變成了遠端協同開發,我要的那個實體類是存在的,隻不過不在我的這個項目裡面,那我們怎麼才能拿到别人那裡的Student實體類呢?我們就可以根據RPC的規範,使用它去拿。當然具體實作細節還有很多,比如序列化和反序列化、Call ID、網絡傳輸…
是以要多看相關的文檔資料,我們這裡更多的是側重于學習怎麼使用。
12.3、Dubbo
RPC是一種通信方式,是一種規範,Dubbo就是它的具體落地
還是帶上官網的圖把,畢竟看起來挺好看的。
Dubbo是一個RPC架構,我們将編寫的程式注冊到RPC的注冊中心裡面,然後再通過注冊中心實作我們的遠端調用。
名詞解釋:
- 服務提供者(Provider):暴露服務的服務提供方,服務提供者在啟動時,向注冊中心注冊自己提供的服務。
- 服務消費者(Consumer):調用遠端服務的服務消費方,服務消費者在啟動時,向注冊中心訂閱自己所需要的服務,服務消費者,從提供者位址清單中,基于軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用
- 注冊中心(Registry):注冊中心傳回服務提供者位址清單給消費者,如果有變更,注冊中心将基于長連接配接推送變更資料給消費者
- 監控中心(Monitor):服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計資料到監控中心
12.4、ZooKeeper
我們剛才在談論Dubbo的時候有說到,我們将編寫好的程式注冊到注冊中心裡面,然後就可以進行相應的調用了。那麼問題又來了
注冊進來的那麼多的服務,我們怎麼去管理它呢?
Dubbo推薦使用ZooKeeper來進行注冊中心的管理。Dubbo是RPC通信方式的一個落地實作,它更多的是給出一個架構形式,具體的實作可以使用相應的功能。Dubbo将注冊中心進行抽象,使得它可以外接不同的存儲媒介給注冊中心提供服務。
引入了Zookeeper作為存儲媒介,也就把Zookeeper的特性引進來了。ZooKeeper的特性包括載均衡、資源同步、命名服務。反正一句話就是,ZooKeeper很好,很适合Dubbo,是以Dubbo推薦它。
12.5、安裝環境
1、安裝測試ZooKeeper
2、安裝Dubbo
3、安裝Dubbo-admin(使用用戶端進行觀測)
12.6、集中整合
整合前提是,我們Dubbo、ZooKeeper環境已經搭建完成
整合步驟:
- 建立兩個不同的項目(配置不同的端口号,用來表示不同的程式)
- 導入對應的依賴
- 将其中一個類設定為Provider,一個設定為Consumer
- 配置對應的程式端口号以及dubbo的資訊
- 編寫不同項目的相應的方法體
- 執行項目,觀測背景資訊(要配置Dubbo-admin)