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

脚手架选型

一年前,我接到为团队落地一个快速开发脚手架的任务。

在月底这节骨眼上,时间紧,任务急,有想自己撸一个脚手架的人都赶紧把这想法收起来吧!这劳民又伤身的事咱肯定是不能干的!

于是,我将目光放在了 Gitee Star比较靠前的开源项目上,这是当时调研的数据 Java Web 开发脚手架调研。

其中MCMS、lenosp、bootdo等项目,我们甚至已经有过项目落地经验,但最终我们还是选择了jeecg-boot,选择它的理由我们有这几点:

  • 前后分离架构

    1. 当时我们正在推前端工程化,前后分离的工作模式是我们团队的趋势
  • 热门技术栈

    1. 后端同学使用 Spring Boot + Mybatis Plus,能更专注理解需求与业务逻辑
    2. 前端同学使用Vue + Ant Design Vue,既能快速开发业务,还有时间对页面性能优化做研究
    3. 设计同学使用Ant Design组件库设计资源,统一了设计风格
  • 基于角色的访问控制体系

    1. 符合公司当前业务场景
  • 完善的开发文档

    1. 开发文档清晰且详细,有经验的同学肯定知道维护一份完善的开发文档往往比写这个项目花费的时间和精力还要多。
    2. 除了文档,社区还提供了视频教学,真的是贴心到了极致
  • 活跃的社区生态

    1. github issue 1300+
    2. jeecg开源社区会员20000+
    3. 活跃的社群交流

正是基于这些点,我们选择相信 jeecg-boot!

经过一年多,我们见证了 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 返回给前端,又不会对原有逻辑进行调整,满足开闭原则

关于防暴力破解

  • 【建议】增加账户锁定策略

这也是安全部门同学找开发同学谈过话的案例

我们的实践方案

使用 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

分环境提供配置,并在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() {// 注册当前页面有哪些modalthis.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最最最最受欢迎的开源项目!

【JeecgBoot】关于 jeecg-boot 的项目理解、使用心得和改进建议相关推荐

  1. 关于JeecgBoot 的项目理解、使用心得和改进建议

    1. 项目理解维护方便.我之前的项目用单体架构,所有模块都在一起,spring单线程实例化bean让人头疼,启动一次需要5分钟.代码生成部分,支持生成的模板类型涵盖的业务场景多,比如,主子表结构.支持 ...

  2. JAVA学习笔记JEECG BOOT介绍

    JEECG JEECG BOOT 低代码开发平台(前后端分离版本) 当前最新版本: 3.1.0(发布日期:2022-03-01) AUR GitHub stars GitHub forks 项目介绍: ...

  3. 【jeecg boot】【PowerDesigner】使用PD创建数据库,并使用jeecg生成代码来创建一个干部任命表单

    首先看一下需要完成的功能 不难发现,我们需要在数据库中设计两张表,分别是干部表和干部家属表,干部表和干部家属是一对多的关系 Power Designer部分 1. 打开Power Designer,点 ...

  4. [零代码工具推荐] 快速建站神器 Jeecg/Boot

    项目介绍 JeecgBoot 是一款基于代码生成器的低代码开发平台!前后端分离架构 SpringBoot2.x,SpringCloud,Ant Design&Vue,Mybatis-plus, ...

  5. Spring Boot+Vue项目 微博系统(2):构建前端Vue项目

    系列目录 Spring Boot+Vue项目 微博系统 目录 系列目录 前言 一.安装Vue CLi 二.构建一个前端项目 三.启动测试 四.项目结构 五.配置 前言 前端项目可以借助 Vue CLi ...

  6. 简单介绍基于Spring Boot的项目骨架使用

    前言 从大学开始接触 java 后台开发,到后来了解了更多的编程语言的开发.发现 java 的开发可以说是相较而言很复杂的了,光是 Spring MVC 的配置要是没有经历系统的学习,可能就能劝退一波 ...

  7. spring boot maven项目返回值乱码的解决方法

    spring boot maven项目返回值乱码的解决方法 1.先看乱码效果: spring boot maven项目,返回值乱码,如下图: 控制台打印log乱码,如下图: 有swagger的话,sw ...

  8. spring boot 开源项目汇总

    spring boot 开源项目汇集 一.spring-boot-examples 项目 项目主页 https://github.com/ityouknow/spring-boot-examples ...

  9. JEECG 社区开源项目下载(总览)

    JEECG 社区开源项目-下载总览 反馈问题板块:http://www.jeecg.org/forum.php?mod=forumdisplay&fid=153 资源1: JEECG 微云快速 ...

  10. spring boot 常用项目文件结构

    spring boot 常用项目文件结构 文件结构 文件结构 src/main/java 开发代码以及主程序入口 Application.java作为程序主入口,建议放在根目录下,主要用于一些框架配置 ...

最新文章

  1. Owncloud-X安装配置
  2. 解决remove @override annotation
  3. oracle的除,Oracle数据库如何去除别名 - daiyan0526的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  4. 恐怖黎明稳定服务器,恐怖黎明新人联机图文教程 怎么联机-游侠网
  5. 图论算法——图的遍历
  6. 为何 iOS 越来越偏爱 Swift?
  7. 【计算机网络笔记】数据链路层(封装成帧,差错检测,可靠传输)
  8. 【并行计算-CUDA开发】CUDA shared memory bank 冲突
  9. JAVA后台,对上传资源限定大小
  10. java 密码库_JCA-Java加密框架
  11. 分布式理论(六)—— Raft 算法
  12. 互联网春节红包的寓言:奇迹如斯,赢家寥寥
  13. thinkphp 的 whereIN() 、where IN 如何使用?
  14. BLOXORZ 游戏攻略
  15. Android自定义睡眠下表统计图,Android 进阶自定义View(5)图表统计PieChartView圆饼图的实现...
  16. 关于Windows下Uninstall的注册表键值
  17. android studio提示HAXM device is not found或者could not start avd
  18. python给图片批量重命名
  19. GGJ游戏《Splash Clash》开发经验分享
  20. 在U盘上运行的 Windows

热门文章

  1. ASP.NET MVC- UrlHelper的用法
  2. 【GIMP教程探索系列】GIMP将照片修改为符合要求的证件照吗,修改尺寸与像素,压缩图像大小
  3. MATLAB2016b安装包
  4. 数学建模算法python源码_如何使用python完成数学建模常见算法
  5. 程序员简历应该怎么写?
  6. java计算机毕业设计中美医院病历管理系统源代码+系统+数据库+lw文档
  7. et文件怎么转成excel_图片转PDF怎么转?这些都是文件转换的好方法!
  8. Python遗传算法工具箱的使用(二)求解最短路径问题
  9. matlab fseek ftell,fseek函数、ftell函数和fflush函数
  10. EIGRP协议的配置