[TOC]
# base-spring-boot-starter
base-spring-boot-starter 提供了平臺通用的模型和工具類,作為公司二方包提供基礎組件。
## 功能
* 加密解密算法
* 公用model類
* 通用工具類
* 通用事件驅動模型
* 通用異常類
* 通用異常通知
* 通用線程池配置
* 通用下載水印
* 統一異常處理
## maven 配置

## 公用model類
用戶 角色 菜單 公共模型,提供權限模型的基礎工具類。映射數據庫中的三張表sys_user,sys_role,
sys_menu

## 通用工具類
通過各種通用配置,通用工具類簡化開發
### 菜單樹

### 獲取用戶信息
* 獲取用戶信息工具類1

* 獲取用戶信息工具類2
```
com.open.capacity.uaa.common.util.AuthUtils.getLoginAppUser()
```
### 通用分頁對象

### BeanValidator參數校驗

### 父子線程異步傳遞問題

### Optional工具類
```
Optional.of(1).ifPresent(o ->{
System.out.println(o);
});
System.out.println(Optional.ofNullable(2).orElseGet( ()-> 1));
```
### EntityUtils
```
List<Long> userIds = EntityUtils.toList(list, SysUser::getId) ;
EntityUtils.toSet(roles, SysRole::getCode);
Map<Long, SysMenu> roleMenusMap = EntityUtils.toMap(roleMenus, SysMenu::getId);
```
### json通用配置

### spring 安全防火墻配置

### 白名單配置

### spring自定義密碼處理器

### google 二維碼

~~~
@Override
@SneakyThrows
public BufferedImage createQrCode(String deviceId, String secret) {
String codeUrl = GoogleOTPAuthUtil.generateTotpURI(deviceId, secret);
//生成二維碼配置
Map<EncodeHintType,Object> hints = new HashMap<>();
//設置糾錯等級
hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.L);
//編碼類型
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl,BarcodeFormat.QR_CODE,200,200,hints);
MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig();
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);
return bufferedImage;
}
~~~
### 白名單配置類

### 接口級自動加密工具

### javers審計比較對象不同
```
import org.javers.core.Changes;
import org.javers.core.Javers;
import org.javers.core.JaversBuilder;
import org.javers.core.diff.Change;
import org.javers.core.diff.Diff;
import org.javers.core.diff.changetype.NewObject;
import org.javers.core.diff.changetype.ObjectRemoved;
import org.javers.core.diff.changetype.ValueChange;
import lombok.Data;
public class ObjectComparator {
public static void main(String[] args) {
// 創建Javers實例
Javers javers = JaversBuilder.javers().build();
// 創建要比較的對象
Person person1 = new Person("John", 30);
Person person2 = new Person("John", 35,"1");
// 使用Javers比較兩個對象
Diff diff = javers.compare(person1, person2);
// 輸出ValueChange類型的變化
Changes changes = diff.getChanges();
for (Change change : changes) {
if ((change instanceof NewObject)) {
System.out.println("新增改動: " + change);
// change.getAffectedObject().ifPresent(System.out::println);
System.out.println("新增");
}
if ((change instanceof ObjectRemoved)) {
System.out.println("刪除改動: " + change);
// change.getAffectedObject().ifPresent(System.out::println);
}
if ((change instanceof ValueChange)) {
System.out.println("修改改動: " + change);
// change.getAffectedObject().ifPresent(System.out::println);
}
}
}
}
@Data
class Person {
private String name;
private int age;
private String id ;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age,String id ) {
this.name = name;
this.age = age;
this.id=id ;
}
}
```
### hutool 工具類
文檔:[https://www.hutool.cn/docs/#/](https://www.hutool.cn/docs/#/)
#### 類型轉化
~~~
int a = 1 ;
String aString = Convert.toStr(a) ;//整型轉String
System.out.println(aString);
long[] b = {1L,2L,3L,4L,5L} ;
String bString = Convert.toStr(b) ;//long數組 轉String數組
System.out.println(bString);
String[] c = {"1","2","3","4","5"};
Integer[] cArray = Convert.toIntArray(c) ;// String數組轉int數組
System.out.println(cArray);
String dateString ="2018-05-22 14:09:33" ;
Date date = Convert.toDate(dateString) ;//時間轉化
System.out.println(date);
String quanjiao ="1234567" ;
String banjiao =Convert.toSBC(quanjiao) ;//半角轉化
System.out.println(banjiao);
System.out.println(Convert.toDBC(banjiao)) ;//全角轉化
String str = "明文字符串" ;
String encodeString = Convert.toHex(str,CharsetUtil.CHARSET_UTF_8) ;//加密
System.out.println(encodeString);
String decodeString = Convert.hexToStr(encodeString, CharsetUtil.CHARSET_UTF_8) ;
//解密
System.out.println(decodeString);
String unicode = Convert.strToUnicode(str) ;
System.out.println(unicode);
String raw = Convert.unicodeToStr(unicode);
System.out.println(raw);
String result = Convert.convertCharset(str, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1) ;//字符集轉化
System.out.println(result);
String iso = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, CharsetUtil.UTF_8) ; //字符集轉化
System.out.println(iso);
long date = 72 ;
long day = Convert.convertTime(date, TimeUnit.HOURS, TimeUnit.DAYS);//時間轉化72小時3天
System.out.println(day);
double price = 6449.89;
System.out.println(Convert.digitToChinese(price)) ;//金錢轉化
~~~
#### 時間
~~~
Date date = DateUtil.date();
String format = DateUtil.format(date, "yyyy-MM-dd") ;
System.out.println(format);
Date beginOfDate = DateUtil.beginOfDay(date) ;
Date endOfDate = DateUtil.endOfDay(date) ;
System.out.println(beginOfDate);
System.out.println(endOfDate);
date = DateUtil.date(System.currentTimeMillis());
String now = DateUtil.now(); //yyyy-MM-dd HH:mm:ss
String tody = DateUtil.today();//yyyy-MM-dd
DateUtil.yesterday();
DateUtil.tomorrow();
DateUtil.lastWeek();
DateUtil.lastMonth();
int age = DateUtil.ageOfNow("1998-04-04" ) ;
System.out.println(age);
~~~
#### excel
~~~
List<?> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd", DateUtil.date(), 3.22676575765);
List<?> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1", DateUtil.date(), 250.7676);
List<?> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2", DateUtil.date(), 0.111);
List<?> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3", DateUtil.date(), 35);
List<?> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4", DateUtil.date(), 28.00);
List<List<?>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);
BigExcelWriter writer= ExcelUtil.getBigWriter("e:"+File.separator+"xxx.xlsx");
// 一次性寫出內容,使用默認樣式
writer.write(rows);
// 關閉writer,釋放內存
writer.close();
ExcelReader reader = ExcelUtil.getReader("e:"+File.separator+"xxx.xlsx");
List<Map<String,Object>> readAll = reader.readAll();
readAll.forEach( item -> {
System.out.println(item);
});
~~~
## 通用事件驅動模型
Disruptor是一個高性能的并發框架,專門用于改善事件驅動的系統。它可以在不使用鎖的情況下實現高并發,并能夠提供一些非常高效的內存讀寫操作,這使得它在處理高并發的情況下能夠獲得很高的性能。基于此創建的雙event事件模型可以簡化開發disruptor的難度,更快速的使用事件驅動解耦項目。

通過請求異步化帶來其他明顯優點:
* 可以處理更高并發連接數,提高系統整體吞吐量
* 請求解析與業務處理完全分離,職責單一
* 自定義業務線程池,我們可以更容易對其監控,降級等處理
* 可以根據不同業務,自定義不同線程池,相互隔離,不用互相影響
### 類圖關系

### 自動裝配

## 通用異常
平臺提供通用異常定義,后續可擴展

## 通用異常通知
平臺異常主動通知依賴alertmanager組件,根據eventbus方式異常通知配置化。

異常通知alertmanager與企業微信對接

## 通用線程池配置

## 通用水印
利用poi等組件對word,excel,ppt加水印

代碼詳解

示例代碼
```
public static void main(String[] args) throws FileNotFoundException {
{
String file = "D:\\file\\自主升級部分功能.docx" ;
FileInputStream is = new FileInputStream(file);
String waterMark = "管理員,2020-10-10";
WatermarkParam param = WatermarkParam.builder().file(file).inputStream(is).useImage(true).text(waterMark)
.fontSize(20).degree(345F).alpha(0.4f).bespread(Boolean.TRUE).color(Color.GRAY).build();
WatermarkUtils.addWatermark(param, new File("D:\\file\\自主升級部分功能1.docx"));
IoUtil.close(is);
}
}
```
下載水印效果

## 統一異常
### springboot異常


### feign異常

## 混沌工程
混沌工程是一種可試驗的、基于系統的方法來處理大規模分布式系統中的混亂問題。通過不斷試驗,了解系統的實際能承受的韌性邊界并建立信心,通過不同的試驗方法和目的,觀察分布式系統的行為和反應。一句話——**以試驗的方法盡早揭露系統弱點**。
混沌工程類似于“故障演練”,不局限于測試,而更像是工程實踐。混沌試驗類似于”探索性測試“,試驗本身沒有明確是輸入和預期結果,通過對系統和服務的干預,來觀察系統的”反應“。我們將混沌工程原則融入在試驗過程中:在生產環境小規模模擬系統故障并定期自動化執行試驗,通過試驗結果與正常結果進行比對,觀察系統”邊界“。
### 如何引入混沌工程?
在眾多服務化改造案例中,Netflix無疑是最成功的公司之一,該公司的很多試驗工具也都集成在Spring Cloud中,成為微服務框架的標準。而Chaos Monkey就是Netflix進行混沌試驗一個重要工具。
Spring Cloud是時下最流行的分布式微服務架構下的一站式解決方案之一,它方便快速的將Spring Boot的微服務有效的管理起來,并提供了包括負載均衡、全鏈路監控、服務網關以及眾多基于Netflix的開源工具。除此之外,鑒于Netflix在服務化演進中的成功案例,我們來了解下Netflix開源的混沌工程試驗框架Chaos Monkey究竟是什么?
### [Chaos Monkey for Spring Boot文檔](https://codecentric.github.io/chaos-monkey-spring-boot/)
chaos-monkey-spring-boot是專門為Spring Boot打造的Chaos Monkey,

maven位置

### 加配置

從配置文件中我們可以很容易看到,Chaos Monkey的三種襲擊方式——延時、異常和進程終止,同時我們也可以設置一個數值范圍,在對服務進行延時攻擊時生成隨機延時。默認攻擊方式為延時攻擊,當同時開啟異常攻擊時,進程攻擊則不會發生。Level:N表示第N個請求將被攻擊,N=1時,表示每個請求都會被攻擊,當同時開啟異常攻擊時,與N值無關,表示每個請求都將被攻擊。
### 總結
chaos-monkey-spring-boot非常適合用來進行故障演練,暴露服務間調用的問題,好提升系統的健壯性、故障自動恢復能力等。
- 01.前言
- 02.快速開始
- 01.maven構建項目
- 02.安裝mysql數據庫
- 03.安裝redis緩存中間件
- 04.快速啟動框架
- 03.總體流程
- 01.架構設計圖
- 02.oauth接口
- 03.功能介紹
- 04.部署細節
- 04.模塊詳解
- 01.基礎介紹
- 02.自定義db-spring-boot-starter
- 03.自定義log-spring-boot-starter
- 04.自定義redis-spring-boot-starter
- 05.自定義base-spring-boot-starter
- 06.自定義common-spring-boot-starter
- 07.自定義loadbalancer-spring-boot-starter
- 08.自定義swagger-spring-boot-starter
- 09.自定義uaa-client-spring-boot-starter
- 10.自定義uaa-server-spring-boot-starter
- 11.自定義oss-spring-boot-starter
- 12.自定義sentinel-spring-boot-starter
- 05.服務詳解
- 01.nacos-server
- 02.auth-server
- 03.user-center
- 04.new-api-gateway
- 05.file-center
- 06.log-center
- 07.back-center
- 08.auth-sso模塊
- 09.admin-server
- 10.job-center
- 06.系統安全
- 01.非法字符漏洞攻擊
- 02.防重放攻擊
- 03.代碼審計
- 04.Xray掃洞
- 05.混沌工程質量保證
- 07.生產部署K8S
- 01.基本環境安裝
- 02.基本組件安裝
- 03.集群驗證
- 04.安裝Metrics Server
- 05.安裝容器平臺
- 06.Ingress網關
- 07.metalb負載均衡器
- 08.容器平臺集群
- 08.K8S資源練習
- 01.Deployment
- 02.StatefulSet
- 03.DaemonSet
- 04.redis集群服務
- 05.elasticsearch集群
- 06.rocketmq部署
- 09.生產容器化部署
- 01.nacos集群部署
- 02.user-center服務
- 03.auth-server服務
- 04.new-api-gateway服務
- 技術交流