尧图精选

SpringBoot轻量级开发框架Sun Frame:Starter自动装配实践

🕒 发布时间:2026/10/2 9:54:26 📁 来源:尧图网络
有些东西用久了会有一种“明明很简单却每次都重复做”的烦躁感。SpringBoot 确实帮我们省了大量配置但真正落到一个业务项目里还是免不了要搭统一返回体、写全局异常捕获、接 Redis、接 MinIO、做参数校验、整操作日志。我做了几年后端以后慢慢意识到自己真正需要的不是一个什么都会的大而全平台而是一套“刚刚好”的骨架。Sun Frame 就是基于这个想法诞生的一个基于 SpringBoot 的轻量级开发框架也是我个人维护了挺久的开源项目。它不是微服务全家桶不强制你用云原生也不搞代码生成的神话就是老老实实把 SpringBoot 项目里最常用的一些能力收敛起来打包成 starter做到“加依赖、写配置、直接用”。如果你正在做一个单体应用、中小系统或者想看一个 SpringBoot 自动装配的落地案例这篇文章应该能给你不少真实可用的东西。1. 为什么会做Sun Frame个人项目背后的真实需求1.1 被重复代码逼出来的决定我刚开始用 SpringBoot 的时候和绝大多数人一样新建一个项目复制上一套项目的工具类改包名再手动加一堆依赖。最痛苦的还不是配置过程而是每个项目的 Controller 返回结构都不一样。你写一个MapString, Object也能返回但到前端对接的时候就乱了同一个接口今天返回{code: 200}明天另一个项目返回{status: 0}前端同学恨不能为每个系统单独写一套拦截逻辑。我印象很深有次帮朋友排查一个线上问题那个项目里光“统一返回体”就有三套实现分散在好几个模块里。有的是R.ok()有的是Result.success()还有的直接往 HttpServletResponse 里写 JSON。当时我就觉得这种基础能力应该在一开始就固化下来而不是等项目越写越大以后再回头去收敛。Sun Frame 的雏形其实就是把我自己项目里的ResultT、全局异常处理、枚举定义这些基础代码抽出来形成了一个独立的公共模块。另外个人开源项目和公司内部项目不一样你没有团队给你写文档也没有人帮你 review 设计合理性。所以我一开始就给自己定了一个目标一切设计都以“最简单的 SpringBoot 体验”为准则。也就是说使用者拿到依赖之后最好连代码都不用看光凭配置项就能跑起来。这个原则后来贯穿了 Sun Frame 的整个版本演进也避免了很多“为了抽象而抽象”的设计。1.2 选择“轻量级”而不是“全家桶”的原因现在市面上的开发脚手架很多有重型的微服务框架也有非常完善的中后台快速开发平台。那么 Sun Frame 为什么坚持走“轻量级”路线我自己的体会是绝多数后端项目其实根本不需要一开始就用上分布式事务、服务网格、消息队列这些重型武器。一个运营后台、一个内容管理系统、一个教务考勤系统单体 SpringBoot 就足够了。你把框架搞得太重反而会造成学习和排查的成本。“轻量级”在我这里的定义有三条。第一依赖收敛能不强引的包就不强引比如你不做文件上传那 MinIO 相关的自动配置就不会加载。第二约定优先配置项必须有默认值不配置也能跑但这不意味着功能缺失而是把常见场景的默认值调好。第三容易替换Sun Frame 不会侵入你的业务代码你想换掉某个组件直接去掉依赖再补一个自己的 Bean 就行。我一直觉得个人开源项目的生命力不在于功能数量而在于能不能让一个完全陌生的人快速上手。如果你做的东西连作者自己都要看半天文档才跑起来那别人更不可能用。轻量级还有一层好处当使用者遇到问题他看源码的门槛低几个关键类翻一翻就能理解整个调用链这也是很多开发框架流行的原因之一。2. Sun Frame整体设计与核心能力拆解2.1 模块划分core、web、data、security、generatorSun Frame 从结构上不是一个大 jar 包而是拆成了几个可以按需引用的模块。这个设计参考了很多知名开源项目的做法但进一步做了减法。核心模块sunframe-core是最底层的东西包含通用返回体、业务异常定义、分页对象和基础工具方法。这部分几乎不依赖第三方框架只有几个必要的默认依赖所以引入成本极低。sunframe-spring-boot-starter-web提供 Web 场景下的能力比如全局异常处理器、参数校验的自动开启、请求日志埋点、统一响应体包装。它会在 SpringMVC 挂载一些自动配置类但不会影响你原有的RestController写法。sunframe-spring-boot-starter-data则围绕数据访问层做了封装包括 MyBatis-Plus 的通用 BaseMapper 扩展、自动填充创建时间和更新时间、分页插件配置和简单数据权限支持。这部分是我自己在业务里被 MyBatis-Plus 的重复配置折磨后的成果。还有sunframe-spring-boot-starter-security它不是重新造一套权限系统而是基于 Spring Security 做了简化配置把常见的登录认证、Token 管理、接口鉴权封装成可继承配置类。最后sunframe-generator是一个独立工具模块不是让你在网页上点来点去生成代码而是通过命令行或者 Maven 插件方式生成 Controller、Service、Mapper 的基础代码这样能让骨架代码保持统一同时不会像很多在线生成器一样生成一坨没人维护的代码。2.2 自动装配原理SpringBoot Starter机制怎么被我用起来Sun Frame 能“加依赖即用”靠的是 SpringBoot 的自动配置机制。这个机制本质上是 Spring 容器在启动时通过spring.factories或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件找到我们声明的自动配置类列表再根据条件注解决定是否创建对应的 Bean。我举个最简单例子。sunframe-spring-boot-starter-web里有一个WebAutoConfiguration类上标注了AutoConfiguration和ConditionalOnClass(DispatcherServlet.class)方法上标注ConditionalOnMissingBean(GlobalExceptionHandler.class)。也就是说只有当你的项目里存在 SpringMVC 环境并且你自己没有定义全局异常处理器的时候Sun Frame 才会帮你创建一个默认的异常处理器。这个机制非常关键它保证了框架的“不强占”特性——你想用自己的实现直接定义一个同名 Bean 就能覆盖掉默认行为。很多人会担心使用这种 starter 会不会被“暗箱操作”了其实你只要记住一句话SpringBoot 自动配置的 Bean 默认是兜底不是强制覆盖。ConditionalOnMissingBean就是给使用者留的扩展口子。我在 Sun Frame 的文档里也一直强调如果某个配置和你的项目有冲突优先考在配置类加排除比如SpringBootApplication(exclude WebAutoConfiguration.class)而不是盲目改依赖版本。这个思路在我自己接手过的一些老项目里尤其有用。2.3 对比市面通用脚手架若依/RuoYi、pigen等既然聊到开发框架很多人会拿 Sun Frame 和 RuoYi、pig 这类开源项目对比。我不是说这类项目不好它们功能非常完整很多企业项目甚至直接基于它们二次开发。但它们的定位是“后台权限管理系统”或者“微服务脚手架”自带菜单权限、部门数据权限、代码生成、系统监控等一大堆功能。你引入之后需要先理解他们的业务表结构和封装逻辑然后才能开始写自己的业务。Sun Frame 想解决的是另一个问题如果你已经有一个自己的项目结构或者你不想把整个项目交给一个大平台约束你需要的只是一组可复用的 starter 模块。它更像是一个“积木盒子”而不是“样板间”。我用 Sun Frame 做过几个新项目也试过在旧项目里混用效果都还不错。最直接的好处是代码结构统一了不管哪个项目Controller 的返回响应长得一样全局异常格式一样分页参数一样内部人员维护起来没有心智负担。当然轻量级也有代价。你不会开箱就得到一整套后台管理页面也没有菜单权限的数据模型。但如果你只是需要一个快速搭建业务接口的能力以及规范化的返回结构Sun Frame 的价值会非常直接。我经常和朋友说选脚手架不是看谁功能多而是看谁“删起来容易”。Sun Frame 的每个自动配置类都可以独立排除、独立替换这一点在长期维护里太重要了。3. 实操如何从零集成Sun Frame到你的SpringBoot项目3.1 环境准备与依赖引入先说基本环境。Sun Frame 推荐使用 JDK 1.8 及以上版本目前主分支基于 Spring Boot 2.7.18 构建同时提供 spring-boot-3.x 的兼容分支。如果你还在用旧版本 Spring Boot建议先升级到 2.5 以上如果已经上了 Spring Boot 3注意包名从javax换成了jakarta部分老版本 starter 可能会因为类名问题启动失败。我在 2.7 上验证过绝大多数功能3.x 分支主要用于新项目探索。引入方式很简单。你只需要在pom.xml里加一个依赖dependency groupIdcom.sunframework/groupId artifactIdsunframe-spring-boot-starter-web/artifactId version1.2.0/version /dependency如果你想做数据访问再加一个sunframe-spring-boot-starter-data。这几个模块并没有强制依赖关系所以你可以按需组合。依赖加好之后SpringBoot 主类不需要加任何额外的EnableSomething注解因为自动配置会帮你完成。我在设计时特意避免了任何“开启注解”因为从我经验看注解越多越容易忘记加导致诡异问题。这里有个实际操作技巧引入依赖后第一次启动时多加一个面板配置debugtrue。这样 SpringBoot 启动日志里会打印所有自动配置的匹配报告你能清楚看到 Sun Frame 的哪些自动配置类生效了哪些因为条件不满足被跳过。这个排查手段能省下大量时间尤其当你觉得某个功能没生效时。3.2 配置项说明与默认值Sun Frame 的配置项前缀是sunframe用 YAML 格式来说大概长这样sunframe: web: response-wrapped: true global-exception-enabled: true trace-id-enabled: true data: auto-fill: create-time-field: createTime update-time-field: updateTime page: default-size: 10 max-size: 100 security: token: secret: change-me expire-minutes: 120每一项都有默认值。比如response-wrapped默认开启但如果你不习惯框架自动包装返回值可以把它关掉。我不建议关因为前端对接统一返回体是刚需。trace-id-enabled是给日志追踪用的会在每个请求响应头里加上一个X-Trace-Id并且在 MDC 里写入同一个值这样查日志时可以按 TraceId 把整个请求串起来。这个小功能实际上很多团队后期都会自己加我干脆在框架里默认做掉了。关于配置项我比较坚持的一个原则是“少而明确”。Sun Frame 的配置项控制在三十个以内如果一个配置项对 95% 的用户来说都用不上就不暴露。这样使用者的学习成本很低文档也不用写太多。有些项目把配置项搞出上百个反而降低了可维护性。实际写代码时配置项的注入也尽量用ConfigurationProperties(prefix sunframe)统一管理避免一堆散落的Value注解。3.3 第一个接口统一响应与全局异常处理接下来我们写一个最简单的接口看看 Sun Frame 帮我们做了什么。假设有一个 UserControllerRestController RequestMapping(/user) public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService userService; } GetMapping(/{id}) public UserVO getUser(PathVariable Long id) { return userService.getById(id); } }没有显式包ResultT但最终返回给前端的数据会是{ code: 0, message: success, data: { id: 1, name: 张三 }, traceId: a8b9c0d1e2f3 }这是 Sun Frame 通过ResponseBodyAdvice实现的统一响应包装。它只包装正常的返回值和特定的业务异常其它交给全局异常处理器处理。如果你在方法上标记了IgnoreResponseWrap那就保持原样返回比如对接第三方接口时不需要统一包装直接返回原始数据即可。全局异常处理的规则也很直接业务异常沿用 HTTP 200 返回因为网络层没有错是业务逻辑层面的问题系统级错误则返回到 500且 message 不直接展示堆栈信息避免泄露代码细节。同时框架会自动记录一条带 TraceId 的 error 日志方便后面排查。我在这个设计上踩过不少坑最深刻的教训是不要把异常堆栈直接放到 message 里传回前端既危险又不专业。3.4 集成MyBatis-Plus的数据访问Sun Frame 的 data 模块默认集成 MyBatis-Plus目前是 3.5.3 版本。它能提供自动填充、分页插件和基础 CRUD 扩展。比如你的实体类上有createTime和updateTime字段只需要在类上加上TableField(fill FieldFill.INSERT)Sun Frame 的MetaObjectHandler扩展就会在插入和更新时自动帮你填充时间省掉一堆手动 set。很多人问为什么选 MyBatis-Plus 而不是直接 JPA我的理由很简单国内团队大多数业务 SQL 都掌握得比较好而且 MyBatis-Plus 在简单 CRUD 上的体验接近 JPA复杂查询又可以转 XML 写原生 SQL适配度很高。Sun Frame 里封装了一个BaseEntity包含主键、创建时间、更新时间、逻辑删除标记和乐观锁版本号这几个常见字段你可以选择继承它也可以不继承。非侵入性还是第一位。分页插件也是现成的。你只需要在 Service 层接收一个PageQuery然后传给Page参数就能拿到PageResultT对象返回给前端。它的结构里预先处理了“当前页、每页条数、总条数、总页数、数据列表”这些常见字段。我再补充一点分页查询时千万不要把max-size设得太大一个后台管理系统的列表一页显示 10 到 20 条已经完全够用我见过不少因为单页拉取太多数据导致数据库压力山大的事故。3.5 把MinIO集成到SpringBoot文件上传中文件存储是很多后台项目的刚需。Sun Frame 的 web 模块里预留了文件上传的抽象接口FileStorageService默认实现是本地磁盘存储但你可以很轻松地把它换成 MinIO。MinIO 是一个兼容 S3 协议的对象存储服务个人项目里面也足够好用开源部署简单能在本地用 Docker 跑起来docker run -p 9000:9000 -p 9001:9001 \ -e MINIO_ROOT_USERadmin \ -e MINIO_ROOT_PASSWORDadmin123456 \ minio/minio server /data --console-address :9001启动之后只需要在 Sun Frame 配置里填入地址和密钥然后实现FileStorageService接口的upload方法就能用 MinIO 存储了。为什么特意做这个抽象因为文件存储方案很容易被业务绑定死早期用本地磁盘后来服务器磁盘不够了换云对象存储或者 MinIO如果代码里到处都是FileInputStream和FileOutputStream改起来会非常痛苦。我见过好几个项目因为文件存储方案替换导致大面积返工所以 Sun Frame 把这个切换成本降到了最低。实际写 MinIO 的上传代码时有一个容易忽略的点上传时必须把Content-Type设置正确不能让 MinIO 把图片、PDF 都识别成application/octet-stream否则前端预览和下载都会出问题。而且生成文件名时不要直接使用原始文件名最好用 UUID 或者时间戳加随机数来重命名避免中文文件名和路径冲突。这些经验不是从文档里看来的都是线上踩过的坑。4. 关键实现细节自动配置、starter与banner定制4.1 自定义starter的三步走很多读者可能好奇Sun Frame 的 starter 到底是怎么写出来的。这里我总结成三步。第一步准备一个普通的 Maven 项目创建自动配置类第二步注册自动配置类在resources/META-INF下新建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件把自动配置类的全限定名写在里面第三步写spring-configuration-metadata.json提供配置项的元数据提示这样使用者在 IDEA 里写sunframe.web这些配置时会有提示。自动配置类的核心是条件注解组合。我会在类上同时使用AutoConfiguration和ConditionalOnProperty实现“配置项没打开就不初始化”的效果。比如下面的示例AutoConfiguration ConditionalOnProperty(prefix sunframe.web, name enabled, havingValue true, matchIfMissing true) public class WebAutoConfiguration { Bean ConditionalOnMissingBean(GlobalExceptionHandler.class) public GlobalExceptionHandler globalExceptionHandler() { return new GlobalExceptionHandler(); } Bean ConditionalOnMissingBean(ResponseBodyAdvice.class) public ResponseBodyAdviceObject responseBodyAdvice() { return new ResponseWrapAdvice(); } }这段代码看起来简单但里面有非常多的门道。比如ResponseBodyAdvice的实现如果要包装返回值一定得判断当前请求是否走的是 SpringMVC 的ResponseBody而且不能重复包装。否则你可能会陷入“包装了一次后又包装一次”的递归问题。具体到代码里我会通过instanceof语句判断返回值是不是Result如果是就直接放行。这种细节只有自己实现过一遍才能理解为什么很多 starter 源码里会有那么多防御性判断。4.2 把项目Banner换成Sun FrameSpringBoot 启动时那个字符画 banner 其实是个很好的品牌展示位。不少公司项目里都会把它替换成企业 Logo。Sun Frame 也提供了一个自定义 Banner 类但我更想说的是 banner 生成技巧。我喜欢用在线 banner 生成器选择纯字模风格再用\033转义序列把文字加上颜色。这样项目启动时控制台会打出Sun Frame字样配合版本号一眼就能看出来这个项目用的是哪个框架版本。不过这个功能要谨慎使用。如果你的团队有人用 Windows cmd注意 ANSI 颜色在部分终端下会显示成乱码符号。我建议默认 banner 不加颜色只保留 ASCII 字符这样最安全。如果你也想在项目里做自定义 banner可以保持一个banner.txt文件放到src/main/resources下SpringBoot 会自动识别。个人项目里这种小细节会被很多用户看到我第一次发现有人把 banner 截图发到群里时还挺有成就感的。4.3 版本兼容性与SpringBoot版本选择前面提到 SpringBoot 3.x 和 2.x 有javax到jakarta的坑这里展开说一下。Spring Boot 3 发布于 2022 年底它不再支持 JDK 8默认从 JDK 17 起步。如果你的项目还停留在 JDK 8 环境想用 Spring Boot 3 基本不可能。所以 Sun Frame 的定位是双轨并行2.7.x分支给大多数存量项目用3.x分支给新项目用。实际操作中版本兼容问题是引依赖时最容易翻车的点。比如在 Spring Boot 3 的 starter 里如果你还没把javax.servlet-api换成jakarta.servlet-api项目启动时会报NoClassDefFoundError。即使代码上通过spring.factories注册自动配置类Spring Boot 3 也不再从spring.factories读取自动配置必须改为AutoConfiguration.imports文件。所以如果你要兼容两个版本这套映射关系就得维护两份。我的经验是个人框架不要一味追最新等一个 SpringBoot 大版本发布后至少半年生态稳定了再迁移会舒服很多。特别是 MyBatis-Plus、MinIO 这些第三方库它们对大版本的适配有自己的节奏。过早跟进新版本可能会因为某个依赖还没有适配导致整个项目启动不了。5. 完整项目结构示例与本地部署验证5.1 demo工程目录结构光说不练是假把式这里给一个完整 demo 项目的结构。假设我们要做一个简单的“图书借阅管理”系统使用 Sun Frame SpringBoot MyBatis-Plus MinIO。项目骨架如下sunframe-demo ├── pom.xml ├── src/main/java/com/example/demo │ ├── DemoApplication.java │ ├── common │ │ └── Result.java │ ├── config │ │ └── MinioConfig.java │ ├── controller │ │ └── BookController.java │ ├── entity │ │ └── Book.java │ ├── mapper │ │ └── BookMapper.java │ └── service │ ├── BookService.java │ └── impl/BookServiceImpl.java └── src/main/resources ├── application.yml ├── banner.txt └── mapper/BookMapper.xml这个结构里Result.java是 Sun Frame 提供的通用响应体你通常不需要自己写。DemoApplication.java上只需要标准的SpringBootApplication注解。如果你想让分页插件和自动填充生效也只要在启动类上继承一下BaseAutoConfiguration或者更简单因为 starter 已经自动配置了你什么都不用加。很多初学者会犯一个错误以为用框架就一定需要各种EnableXXX结果要么找不到注解要么重复配置导致 Bean 冲突。Sun Frame 的设计哲学是能用自动配置解决的绝不开启手动开关。你只需要把依赖加对了写业务就行。要是遇到不生效的问题先开debugtrue看自动配置报告再决定是否需要手动声明。5.2 启动流程与常见错误启动之前检查一下application.yml里的数据源配置。我这里推荐用 H2 内存库先做快速联调毕竟不想让读者为了跑 demo 还要专门装 MySQLspring: datasource: url: jdbc:h2:mem:testdb;MODEMySQL;DATABASE_TO_LOWERTRUE driver-class-name: org.h2.Driver username: sa password: sunframe: web: trace-id-enabled: true启动时常见的报错有两大类。第一类ClassNotFoundException: javax.servlet.*这基本就是 SpringBoot 版本和 Sun Frame 模块版本不匹配。第二类Error creating bean with name globalExceptionHandler多半是你自己项目里已经有一个同名 Bean和自动配置的默认 Bean 撞了。解决方法是把你自己的 Bean 删掉或者在自动配置类上用ConditionalOnMissingBean处理Sun Frame 已经处理过这种情况但如果你自己又加了一个全局异常处理器还是可能会冲突。我在本地验证时通常会用mvn spring-boot:run启动配合 IDEA 的 Rest Client 工具直接调接口。第一次跑通后把这个启动过程写成一个 README 文档方便以后其他同事加入项目时快速上手。一个好的 README 应该包含运行环境、启动命令、默认端口、测试账号、配置项说明和常见问题。这些内容如果只存在个人脑子里项目交接时就是灾难。5.3 Vue打包后如何放进SpringBoot运行还有一个很常见的问题前后端分离项目前端 Vue 工程打包后怎么放进 SpringBoot 一起发布。我在 Sun Frame 的 demo 里也做了一版。简单说把 Vue 构建出来的dist目录里的文件复制到 SpringBoot 的src/main/resources/static目录下然后后端访问http://localhost:8080/就能看到前端页面。但是要注意前端路由如果是 history 模式刷新子路由时会出现 404因为 SpringBoot 没有把非接口路径转发到index.html。解决这个问题的方案是添加一个简单的路由转发控制器或者写一个WebMvcConfigurer注册PathResourceResolver。我在 demo 里是这么处理的Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/**) .addResourceLocations(classpath:/static/) .resourceChain(true) .addResolver(new PathResourceResolver()); } }这种方案能覆盖绝大多数普通场景。不过如果你在 SpringBoot 内置了 JWT 鉴权还得在安全配置里把前端的静态资源路径排除掉否则第一次加载首页就会被拦截。很多人会在这一步卡很久其实只需要在安全过滤链里允许/,/index.html,/assets/**这些路径匿名访问就行。6. 个人开源项目维护心得与避坑清单6.1 文档比代码更值得花时间一个开源项目代码写得再好没有清晰的文档使用者很容易在最初的十分钟里就放弃。我自己维护 Sun Frame 的体感是每写一段代码就要花同样甚至双倍的时间去写 README、写注释、写示例。尤其是 Starter 的配置项一定要配上完整的 YAML 示例并且拿真实项目跑出来的结果截图放在文档里。使用者看到实际的返回 JSON 结构会比看抽象定义更放心。文档里我还坚持放一个“快速开始”目标是让用户在三分钟内启动一个带接口的项目。如果一个新用户能在三分钟内看到自己的第一个接口返回Result.success他对这个框架的好感度会大幅提升。这个快速开始的脚本我会在每次发布新版本前用一台干净的虚拟机按照文档从零跑一遍确保上面的步骤没有遗漏。有一次我发版前没有跑文档结果用户按文档操作时发现少了一个依赖那个问题还被提了 issue后来我就再也不敢偷懒了。6.2 版本管理与发布到Maven中央仓库的经验个人项目要发布到 Maven Central 其实不是很难但流程细节很多。首先你得准备一个 Sonatype 账号然后要有一个自己的域名来绑定 groupId否则只能用io.github.xxx这样的前缀。接下来需要配置 GPG 签名每次发布都要对构件进行签名验证。我一开始觉得这很麻烦但一旦配好后面的发布就是执行一条命令的事情。版本管理我采用语义化版本规范主版本号变化意味着可能有破坏性更新次版本号变化是新增功能保持兼容修订号则是缺陷修复。发布前我会把所有依赖的版本也确认一遍避免因为某个传递依赖更新导致使用者构建失败。这里有个细节SpringBoot 的 BOM 会在父子项目之间传递依赖版本但如果你把 Sun Frame 作为一个独立依赖引入别人的项目不要在你的 pom 里把依赖范围设成provided否则一些本来应该打包的类会被漏掉我踩过一次快被用户骂惨了。另外版本发布不是越多越好。小步快跑的策略在业务项目里很好用但在框架项目里频繁发版会让使用者不断面临依赖更新和兼容性测试的负担。我一般是一个功能稳定后集中测试完再发一个小版本确保每个发布版本都能在 demo 项目里跑通。6.3 后续规划分布式支持、代码生成器扩展最后聊聊 Sun Frame 后续的方向。目前它更适合单体应用但我也确实考虑做一个扩展模块支持基于 Redis 的分布式锁和简单的多租户数据隔离。分布式锁其实没那么神秘核心是拿到 Redis 的SETNX锁再设置过期时间需要注意的是一定要把 key 和 value 绑定到业务维度并判断是否是自己的锁不能简单解锁。这个功能放进去之后Sun Frame 在中小型分布式场景下也能有用武之地。代码生成器也是很多人催的功能。我打算把它做成一个 Maven 插件而不是一个单独的启动器界面。因为在线生成的代码往往第一次能跑后面维护就会越来越痛苦。我更倾向于用模板在工程里生成规范一致的代码文件同时保留手工改动的余地。生成器要支持策略选择比如生成 Controller、Service、Mapper、Entity 的开关以及覆盖保护。如果生成器不做保护不小心覆盖掉用户已经写好的业务逻辑那就惹祸了。维护开源项目最真实的感受是它不像写公司业务代码那样闭环交差就行而是要长期和用户打交道持续打磨边界场景。如果你也想做自己的开源框架我的建议是先从一个两三万行的小工具起步解决一个你自己最痛的问题比想做一个通用平台要靠谱得多。Sun Frame 的下一步大概率还是继续做减法把那些不常用、维护成本又高的模块移出主分支让核心越来越稳定。我始终相信一个好的开发框架不是让你觉得它强大而是让你意识不到它的存在专心写业务就好。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →