【JeecgBoot】關於 jeecg-boot 的項目理解、使用心得和改進建議

工欲善其事,必先利其器。

腳手架選型

一年前,我接到爲團隊落地一個快速開發腳手架的任務。javascript

在月底這節骨眼上,時間緊,任務急,有想本身擼一個腳手架的人都趕忙把這想法收起來吧!這勞民又傷身的事咱確定是不能幹的!前端

因而,我將目光放在了 Gitee Star比較靠前的開源項目上,這是當時調研的數據 Java Web 開發腳手架調研vue

其中MCMSlenospbootdo等項目,咱們甚至已經有過項目落地經驗,但最終咱們仍是選擇了jeecg-boot,選擇它的理由咱們有這幾點:java

  • [x] 先後分離架構webpack

    1. 當時咱們正在推前端工程化,先後分離的工做模式是咱們團隊的趨勢
  • [x] 熱門技術棧git

    1. 後端同窗使用 Spring Boot + Mybatis Plus,能更專一理解需求與業務邏輯
    2. 前端同窗使用Vue + Ant Design Vue,既能快速開發業務,還有時間對頁面性能優化作研究
    3. 設計同窗使用Ant Design組件庫設計資源,統一了設計風格
  • [x] 基於角色的訪問控制體系github

    1. 符合公司當前業務場景
  • [x] 完善的開發文檔web

    1. 開發文檔清晰且詳細,有經驗的同窗確定知道維護一份完善的開發文檔每每比寫這個項目花費的時間和精力還要多。
    2. 除了文檔,社區還提供了視頻教學,真的是貼心到了極致
  • [x] 活躍的社區生態redis

    1. github issue 1300+
    2. jeecg開源社區會員20000+
    3. 活躍的社羣交流

正是基於這些點,咱們選擇相信 jeecg-boot!<img src="https://img-blog.csdnimg.cn/20200827115123583.png" width="100px"/>spring

通過一年多,咱們見證了 jeecg-boot 在 github 從 star 2000+ 到如今的 star 14.7k

而咱們團隊也已經有 5 個服務是基於 jeecg-boot 2.0.0 進行開發,並有 4 個服務已投入生產使用。

改進建議

後端

關於分層領域模型

  • 【建議】將 分層領域模型 落地

相比咱們使用的 2.0.0 版本,jeecg-boot 2.2.1 在功能上已經很是完善,且已經造成了穩定的代碼風格,在代碼分層的工做上也細化了不少。

可是,在分層領域模型方面,始終是使用Entity貫穿各層,若是能將分層領域模型落地,jeecg-boot 必定會更加優秀。

咱們在分層領域模型規約的一些實踐: 遵循 JAVA開發手冊

# 對象模型
Model (接口入參 表單驗證 swagger註解) 
VO (返回頁面對象) View Object
BO (業務層對象)
DO (數據庫返回結果集)
DTO (遠程調用傳輸對象)
實體類 (與數據表一一對應)

# 接口入參接收對象:XXXModel
【推薦】不包含`id、updateBy、updateTime、createBy、createTime`等屬性,經過sql攔截注入這一系列字段
【推薦】必傳字段校驗
【推薦】字段長度校驗
【推薦】格式校驗
【推薦】時間格式轉換 `@DateTimeFormat` (入參格式化,將字符串時間格式化爲Date對象)

# 接口返回值:XXXVO
【強制】不包含敏感字段(手機號、密碼、郵箱、身份證號)
【強制】包含敏感字段時對數據加密
【推薦】使用`@JsonView`註解控制返回值的字段可見性
【推薦】字典字段轉換 如,`@Dict(dicCode = "sex")`
【推薦】時間格式轉換 `@JsonFormat` (出參格式化,將Date對象時間格式化爲字符串)

關於簽發給前端的 token

  • 【建議】不將 jwt 生成的 token 直接返回給前端

這裏之因此有這個建議,是由於咱們安所有門的同窗找了開發同窗好幾回麻煩,最後咱們將 token 的存儲作了一些改造。

方案一

  1. redis 中 token 的 key 不使用 username_token的形式,使用 username_UUID
  2. 在登陸接口中,不將 jwt 生成的 token 直接返回給前端,而是返回 UUID 。
  3. 調整 ShiroRealm#doGetAuthenticationInfo邏輯,先使用 token 從 redis 獲取 jwt token 。
  4. 從 request 中獲取 token 並使用 JwtUtil.getUsername(token)以前須要先從 redis 獲取 jwt token 。

方案二

固然,還能夠將 jwt token 進行加密,向前端返回加密後的 token,然後端只需增長一個對被加密的token進行解密的過濾器。

既可知足不將 jwt token 返回給前端,又不會對原有邏輯進行調整,知足開閉原則

關於防暴力破解

  • 【建議】增長帳戶鎖定策略

這也是安所有門同窗找開發同窗談過話的案例!<img src="https://img-blog.csdnimg.cn/20200827114603322.png" width="50px"/>

咱們的實踐方案

使用 redis 對單位時間內(咱們是 5 分鐘)的用戶登陸失敗次數進行計數。

失敗次數達到 5 次後,將對該帳戶進行凍結(5 分鐘),5 分鐘後 redis key 過時,該用戶便可正常登陸。

關於 jeecg 配置

  • 增長JeecgPorperties.java對前綴爲jeecg的配置進行管理,避免使用@Value獲取屬性值的行爲。
  • 引入spring-boot-configuration-processor依賴,爲已聲明的配置項增長提示。

前端

關於環境配置文件

  • 【建議】引入.env.*配置文件,將配置與環境隔離

目前 jeecg-boot 的前端,一直使用的是 window._CONFIG 來掛載相關全局變量,它有一個缺點就是沒有將配置與環境隔離

好比:

在開發環境下window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot'
在測試環境下window._CONFIG['domianURL'] = 'http://test.product.com:8080/jeecg-boot'
在生產環境下window._CONFIG['domianURL'] = 'http://prod.product.com:8080/jeecg-boot'

打包不一樣的環境,都須要人爲的去改動這些配置,對CI/CD極不友好。

咱們的實踐方案

  1. .env
  2. .env.development
  3. .env.production
  4. .env.test
  5. ...

分環境提供配置,並在package.json增長相應打包腳本,提升部署效率。

相似於後端項目中的:

application.yml
application-dev.yml
application-prod.yml
application-test.yml

關於加強 JeecgListMixin.js

  • 【建議】圍繞 JeecgListMixin 向下提供一些勾子函數

    咱們能夠看到initDictConfig是一個空方法,它就是一個勾子函數,子組件若是重寫了該方法,則會在執行created生命週期函數時,執行子組件中重寫的邏輯。

    因此,咱們能夠向JeecgListMixin的賦能更多勾子函數,知足更多場景,提升靈活性,提升開發效率。

咱們的實踐方案

// created生命週期函數中執行 應用場景:加載異步詞典項等
initDictConfig() {} 

// 搜索以前執行 應用場景:對 queryParam 對象內的數據,作一些數據轉換工做等
beforeSearch() {}

// 重置以前執行 應用場景:重置一些沒有綁定在 queryParam 對象內的數據等
beforeReset() {}

// loadData加載數據成功以後執行 應用場景:須要在該時機下作一些數據的轉換工做等
afterLoadDataSuccess() {}

// 在 loadData 內執行 應用場景:自定義數據加載邏輯
// 執行 loadData 時,會先判斷是否重寫了 customLoadData 方法
customLoadData() {}

關於頁面性能的優化

  • 【建議】路由懶加載
    須要注意使用路由懶加載後所帶來的問題,即刷新時會觸發兩次路由守衛的beforeEach函數
  • 【建議】對體積較大的第三方資源拆包,或使用CDN引入

當前 jeecg-boot 2.2.1 是一次性加載全部資源,不管是開發仍是生產階段都是不利的!
對於開發階段,開發同窗每次刷新頁面須要等待 3 ~ 4 秒,
對於生產階段,就會涉及到首屏加載這個指標的考驗。

對資源作按需加載/縮減資源體積能極大的優化加載性能,也是一件頗有意義的事。

咱們能夠對 jeecg-boot 前端作的一些優化

  1. 路由懶加載 component:() => import(/* webpackChunkName: "component" */ component.vue)
  2. 根據環境須要,使用splitChunks對依賴的第三方資源拆包

固然,還有更多 jeecg-boot 用戶能夠作的優化

  1. 文件內聯(減小請求數)
  2. 搖樹優化(用不到的方法或者模塊就不打包)
  3. gzip壓縮
  4. CDN加速

關於增長ModalMixin.js

在業務開發過程當中,一個頁面可能有不少Modal / Drwaer,就須要咱們加一些響應式變量和方法去控制這些Modal / Drawer的 顯示/關閉,而這些工做每每都是重複的。

那麼,咱們能不能抽象一下這些重複的工做,將更多的精力放在組件的邏輯上去呢?

咱們的實踐方案

  1. Modal / Drawer 的父組件引入@/mixins/ModalParentMixin ,並在mounted生命週期函數中使用register方法對 ref 的值進行註冊

    <template>
     <div>
       <a-button type="primary" @click="showModal('addModal')">新增</a-button>
       <a-button type="primary" @click="showModal('editModal')">編輯</a-button>
       <a-button type="primary" @click="showModal('detailModal')">詳情</a-button>
       
       <!--新增-->
       <modal-add  ref="addModal" @ok="searchReset"/>
       
       <!--編輯-->
       <modal-edit  ref="editModal" @ok="searchReset"/>
       
       <!--詳情--> 
       <!--條件渲染,將v-if="isShow('detailModal')" @close="closeModal"一塊兒使用便可-->
       <modal-detail  ref="detailModal" @ok="searchReset" v-if="isShow('detailModal')" @close="closeModal"/>
     </div>
    </template>
    
    <script>
     import ModalParentMixin from '@/mixins/ModalParentMixin'
    
     export default {
       mixins: [ ModalParentMixin],
       mounted() {
         // 註冊當前頁面有哪些modal
         this.register(['addModal', 'editModal', 'detailModal'])
       },
     }
    </script>
  2. 在 Modal / Drawer 組件中引入@/mixins/ModalMixin

如今咱們控制頁面上全部的 Modal / Drawer 是否是要輕鬆不少了呢?

不再用聲明各類不一樣的 xxxVisible來控制這些子組件的顯示/關閉

關於修復 Ant Table 的 BUG

這個本應該去 Ant Design Vue 提 issue 的,可是跟了好幾個版本以後,他們並無作修復,獲得的答案彷佛是:設計如此

既然這樣,咱們就本身來作一些處理,去規避掉這個 BUG。

  • 復現步驟
    刪除數據前 { total: 11, current: 2, pageSize: 10 }
    刪除數據後 { total: 10, current: 2, pageSize: 10 },顯示暫無數據在這裏插入圖片描述

在這裏插入圖片描述

  • 修復
    JeecgListMixin.jshandleDeletebatchDel等方法,在操做成功後,對current進行從新計算。
  • 修復後效果
    刪除數據前 { total: 11, current: 2, pageSize: 10 }
    刪除數據後 { total: 10, current: 1, pageSize: 10 },正常顯示第一頁的數據。

其餘

關於更新計劃

  • 【建議】增長更新計劃菜單

能方便你們瞭解到 JEECG團隊 對新版本的迭代方向,增長用戶粘度。

關於這個建議已經有 issue,相信在近期內就會看到這個菜單!

關於平滑升級

不少社區的朋友都有反應這個問題。確實,當咱們的業務代碼與 jeecg-boot 的源碼融合在一塊兒的時候,作版本升級是比較頭疼的。
特別是大版本的升級,除了源碼的變更,可能還有數據庫表的變動,升級會不會對咱們的業務產生影響,誰也說不清楚!

咱們的實踐方案

依賴 jeecg-spring-boot-starter,解決業務代碼與 jeecg-boot 源碼融合的在一塊兒的窘境。

  • 適用人羣

    • 快速開發人羣
    • 不需對 jeecg-boot 的源代碼進行改動的人羣
    • 只需對 jeecg-boot 配置項進行調整便可知足開發的人羣

有興趣的同窗,能夠去 github 瞭解它 https://github.com/tanpenggood/jeecg-spring-boot-starter

總結

  1. jeecg-boot 明顯的提升了咱們團隊的開發效率。
  2. jeecg-boot 全套技術棧符合當前技術趨勢,學習文檔完善,是一個很是值得你們學習的開源項目。
  3. jeecg-boot 社區活躍,碰到問題基本上都能及時解決,有價值的問題最好再去 github 提 issue

最後,但願 jeecg-boot 的代碼質量更加優秀,但願 jeecg-boot 成爲2020最最最最受歡迎的開源項目!

相關文章
相關標籤/搜索