尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用myBuilder脚手架搭建企业级Spring Boot项目:从课设到实战

用myBuilder脚手架搭建企业级Spring Boot项目:从课设到实战 最近在带实验室项目时用了myBuilder这个脚手架工具明显感觉到学生从“会写接口”到“理解企业级开发流程”之间的距离被压缩了一大截。很多同学在学校里课程设计做得风生水起数据库表画了一堆接口也调通了可真到了企业面试和实习场景一问到“权限怎么控制”“异常怎么统一处理”“日志怎么排查”就支支吾吾答不上来。说白了不是大家不努力而是校园里练的东西和企业级开发要的东西压根不是一回事。这篇内容我想从一个带项目的人的视角聊聊怎么用myBuilder在校园环境里把“企业级web开发”这套东西真正落到手上。它不是什么高深框架而是一套能快速生成标准工程结构的脚手架工具特别适合毕设、课设、实验室项目这几个典型场景。如果你现在还在纠结“我写的代码是不是太学生气”或者想让自己的项目在简历上看起来更贴近真实企业实践这篇文章应该能给你一些能直接用上的思路。1. “学用脱节”到底断在哪课程设计满分实习面试照样卡壳先说一个我反复见到的场景。有学生拿着自己的课设项目来给我看功能确实都做出来了登录注册、增删改查、分页搜索界面也凑合。但我问三个问题基本就露馅了——第一个问题“用户登录状态你是怎么保持的”答“我用session。”第二个问题“如果两个接口都要判断用户是不是管理员你怎么做”答“每个接口里写一段判断。”第三个问题“前端传过来的参数你校验了吗”答“前端已经校验过了后端没怎么做。”这三个回答放在校园环境里其实挑不出大毛病课程设计验收老师不会深究。可一旦放到企业级开发语境里每一个都是硬伤。Session在集群环境下要处理粘滞会话或集中式存储权限判断如果散落在每个接口里后期维护就是一场灾难后端不校验参数更是安全漏洞的温床。这就是“学用脱节”的本质校园里教的、练的是“功能能不能跑通”企业里要求的是“这个系统能不能被一群人长期维护、稳定运行、安全上线”。1.1 校园代码的四个典型特征我从这些年看过的学生项目里总结了四个高频特征不一定每个项目全占但至少中两三条。第一所有逻辑都往一个类里堆。Controller里面直接写SQL查询Service层形同虚设更常见的是根本没有Service层页面请求进来直接在Servlet或者一个Controller类里全部处理完。代码行数是不少但耦合度极高。第二异常处理靠try-catch包全场。要么是方法内部自己吃掉异常然后返回null要么是完全没有异常处理出错了直接抛500前端页面白屏。这种代码在企业里连code review都过不了因为出了问题你根本不知道是参数错了、数据库错了还是网络错了。第三权限控制靠页面按钮隐藏。很多课设项目把按钮隐藏掉就觉得自己做了权限控制实际上后端接口直接裸奔懂点HTTP的人用Postman一调就能绕过前端拿到数据。第四配置全部写死在代码里。数据库连接、上传路径、接口地址全用常量写在Java文件里。换一台机器部署就得改代码重新编译这跟企业里“一份代码多处部署”的基本要求完全相反。1.2 企业级开发到底“级”在哪很多同学一听“企业级”三个字就觉得是微服务、分布式、高并发其实这是很大的误解。真正意义上的企业级web开发核心在于“规范”和“可维护性”而不是技术栈有多新。我用一个表格来对比你就明白差距在哪了。对比维度校园课设常见做法企业级开发要求项目结构所有代码堆在Controller或单个类中按分层结构组织Controller、Service、Mapper、Entity、DTO接口返回直接返回JSON对象或页面片段统一响应体状态码、消息、数据、时间戳异常处理try-catch后返回null全局异常处理器统一拦截分类响应权限控制前端隐藏按钮后端拦截器/注解校验接口级别鉴权参数校验前端校验或完全不校验后端基于注解校验非法请求直接拒绝部署方式本地Tomcat跑起来多环境配置、容器化部署、持续集成日志排查System.out.println分级日志、请求链路追踪、集中式日志采集企业级开发不是门槛高到学生碰不了而是有一套固定的“章法”。问题在于校园课程里几乎没有哪一门课会系统性地教你这套章法。你学Spring Boot的时候教程上写的是“创建一个Controller返回Hello World”但没人告诉你一个真实项目里Controller应该长什么样、哪些事它不该做、异常了找谁处理。这正是我后来愿意把myBuilder带到校园项目里的原因它直接把“章法”做进了生成模板里你只要用它就会被引导着按企业级的结构去写代码。2. myBuilder的定位与设计逻辑一个适合校园实训的企业级脚手架先给不了解的朋友打个底。myBuilder在我常用它的场景中是一个偏向教学和企业快速交付的代码生成脚手架工具。它的工作方式很简单你告诉它数据库表结构它负责生成一套符合工程规范的代码骨架——实体类、Mapper、Service、Controller、统一返回体、全局异常处理、分页插件、鉴权模板、多环境配置文件一次性全给你铺好。很多同学第一次接触这类工具会想这不是偷懒吗代码都生成了我还学什么这是我最想纠正的误解。脚手架的价值不是让你不写代码而是把那些“不需要动脑子但容易出错”的重复工作先干掉让你把精力花在真正需要思考的业务逻辑上。就像你写字之前总得先有张白纸myBuilder帮你把白纸的格子线都画好了你往里面填内容就行。2.1 脚手架训练的不是打字能力是工程化思维我在带项目的时候经常说一句话如果你连一个项目应该有哪些层、每层该干什么都没建立体感那写再多代码也只是一堆代码堆在一起。而myBuilder这类工具最好的地方在于它会强迫你按它生成的这套结构去写业务。举个例子。它生成的Controller里默认就会带上RestController、RequestMapping、接口返回统一用Result这个类型。你上手第一个接口自然就会问为什么返回值不直接返回对象而是要包一层Result这时候我再解释统一响应体在前后端联调里的作用学生就很容易接受。因为他是从“照着写”的过程中发现了问题而不是听我讲一堆抽象概念。同样的逻辑也适用于分层。生成的Service层默认有接口和实现类你往里写业务逻辑的时候自然就会知道Controller里不应该碰Mapper。时间一长“Controller只做参数接收和路由转发、Service做业务、Mapper做数据访问”这套企业级web开发的基本盘就成了肌肉记忆。2.2 为什么校园场景用myBuilder特别合适市面上其实有不少代码生成器有的很重配置起来能把人绕晕有的太轻只是生成几个实体类就没后续了。myBuilder之所以在校园实训这个场景里好用我总结了几点。一是上手成本低。不需要额外部署独立的生成服务也不需要写一堆引擎模板。它跟Spring Boot项目贴合得比较紧密配置好数据源和生成路径命令行或者插件点一下就出代码。对于还没有建立起完整工程概念的学生来说这是非常关键的一点工具不能比业务本身还难用。二是生成的代码本身就是教材。这一点我觉得是它最大的价值。我经常让学弟学妹把生成的代码从头到尾读一遍读完了再看自己以前写的课设代码基本都能自己说出差距在哪。因为生成出来的代码就是“标准答案”你对照着学比听任何课程都直观。三是它把企业级开发的“标配组件”预埋好了。统一返回体、全局异常、Swagger文档、JWT认证模板这些在企业项目里几乎必有的东西myBuilder在生成骨架时都会带上。学生哪怕只是把这些组件理解了、改一改用起来简历上多出“具备统一异常处理、基于JWT的接口鉴权经验”这种描述面试官一看就知道你不是只做过玩具项目。四是保留了一定的自由空间。它生成的是一个基准工程不是一口吃成胖子。学生完全可以在生成之后继续引入Redis做缓存、引入消息队列做异步也可以把自带的简单鉴权换成Spring Security OAuth2。骨架是固定的但进阶的路没有被堵死。2.3 一个容易被忽视的点从“单体规范”起步别急着上微服务我还想多说一句校园项目真的不建议一上来就搞微服务。分布式、注册中心、配置中心、网关、链路追踪这一套东西对新手来说学习成本极高而且大部分课设、毕设的业务复杂度根本用不上。你花两周时间搭了一套微服务架构结果每个服务里就两三个接口既浪费时间也学不到真正的业务深度。我的经验是先把一个单体应用按企业级规范写扎实把分层、权限、异常、日志、测试这些基本功打牢未来再去接触微服务你会容易得多。因为微服务只是把单体里的模块拆成了独立进程但每一进程内部的代码规范跟你写一个规范的单体应用是完全一致的。myBuilder这套东西训练的就是这个“内功”。3. 校园实战用myBuilder从零搭建一个二手书交易平台光说不练没什么意思。下面我用一个校园里特别常见的“二手书交易平台”作为例子完整走一遍用myBuilder从零搭起企业级结构的过程。这个项目大家在课设里肯定见过需求也不复杂用户注册登录、发布书籍、浏览书籍、下单购买。但我们要把它做成一个结构规范、有权限控制、能够部署演示的完整web应用。3.1 第一步准备环境并初始化工程先说环境。myBuilder运行的基础条件并不高一台普通笔记本就行。你需要准备的东西如下。JDK 8及以上版本我建议直接用JDK 17反正新项目别再用老版本了Maven 3.6以上MySQL 5.7及以上IDE工具IDEA或者Eclipse都行myBuilder插件或命令行工具在本地装好初始化工程的时候myBuilder一般会提供一个创建项目的入口。你在界面里填好项目的基础信息groupId、artifactId、包名、端口号、数据库连接信息它就会生成一个完整的Spring Boot工程目录结构。这里有一个很关键的经验包名的规划一定要认真想好再填。因为Java的包名决定了代码的组织方式myBuilder会根据你填的包名生成对应的目录结构。我见过有人图省事填了个“com.test”结果整个项目的类全在test包下面后期看代码怎么看怎么别扭。建议遵循“域名倒写项目名”的格式比如“com.university.booktrade”这种。3.2 第二步设计数据表让表结构驱动代码生成myBuilder这类工具最核心的思路是“表驱动”。数据库表设计成什么样子直接影响生成出来的代码质量。所以不要急于点生成先把表结构想清楚。以二手书交易平台为例我建了这样几张核心表。-- 用户表 CREATE TABLE t_user ( id bigint NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 登录名, password varchar(100) NOT NULL COMMENT 密码加密存储, nickname varchar(50) DEFAULT NULL COMMENT 昵称, email varchar(100) DEFAULT NULL COMMENT 邮箱, role tinyint NOT NULL DEFAULT 1 COMMENT 角色1-普通用户2-管理员, status tinyint NOT NULL DEFAULT 1 COMMENT 状态1-正常0-禁用, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 书籍表 CREATE TABLE t_book ( id bigint NOT NULL AUTO_INCREMENT, title varchar(100) NOT NULL COMMENT 书名, author varchar(50) DEFAULT NULL COMMENT 作者, publisher varchar(100) DEFAULT NULL COMMENT 出版社, price decimal(10,2) NOT NULL COMMENT 售价, original_price decimal(10,2) DEFAULT NULL COMMENT 原价, description text COMMENT 书籍描述, seller_id bigint NOT NULL COMMENT 发布人ID, status tinyint NOT NULL DEFAULT 0 COMMENT 状态0-在售1-已售出2-下架, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_seller_id (seller_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT书籍表;关于表设计在学校做项目时有几个细节一定别忽略。第一所有表都要有create_time和update_time两个字段这是企业开发的共识你在myBuilder里配置好之后插入和更新的时候会自动填充不用手写。第二关联字段要加索引比如t_book表里的seller_id因为它经常出现在where条件里。很多学生课设的表一个索引都不建数据量小没事数据量一上来慢查询教做人。第三字段命名用下划线风格因为Java实体类会映射成驼峰风格myBuilder在生成时能自动完成这个转换。建好表之后在myBuilder里配置数据库连接选择要生成的表它就能识别出表之间的主外键关系。这个步骤里观察生成配置是很有意思的你会发现它会给每个字段生成注释这是因为我们建表的时候给每个字段都写了COMMENT。所以建表时字段注释一定不要省注释写得好生成的代码里注解就全代码的可读性完全不一样。3.3 第三步一键生成看看到底生成了什么配置完成后点生成myBuilder会创建或更新下面的内容。Entity实体类对应数据库表Mapper接口及XML文件Service接口及实现类Controller控制器通用的Result统一返回体类全局异常处理类GlobalExceptionHandler分页请求参数封装application.yml多环境配置文件为了让你直观看到“企业级”长什么样我把生成的Controller代码贴一段出来。RestController RequestMapping(/api/book) public class BookController { Resource private BookService bookService; /** * 分页查询书籍列表 */ GetMapping(/page) public ResultPageResultBookVO page(BookQuery query) { PageResultBookVO page bookService.pageBooks(query); return Result.success(page); } /** * 查看书籍详情 */ GetMapping(/{id}) public ResultBookVO detail(PathVariable(id) Long id) { return Result.success(bookService.getBookDetail(id)); } /** * 发布书籍 */ PostMapping public ResultVoid publish(RequestBody Valid BookPublishRequest request) { bookService.publishBook(request); return Result.success(); } /** * 下架书籍 */ PutMapping(/{id}/off-shelf) public ResultVoid offShelf(PathVariable(id) Long id) { bookService.offShelfBook(id); return Result.success(); } }注意几个细节。第一返回值统一用了Result 请求参数里用了Valid注解说明参数校验是放在接口入口处的。第二分页查询有专门的Query对象和PageResult封装。第三发布和下架操作不是简单的增删改而是被设计成有业务语义的接口。这些都不是我在生成之后手动改的而是myBuilder基于表和基础包结构直接生成的。当然生成出来的代码不一定100%满足业务需求比如你要做“根据书名模糊搜索”“按价格区间筛选”这些需要自己在Service实现类里补写。好的脚手架思路是通用的结构它给你特殊的业务你来填互不冲突。3.4 第四步编译运行拿到第一份接口文档代码生成之后并不代表直接就能跑。你需要检查一下application.yml里的数据库账号密码、端口号这些配置。myBuilder生成的多环境配置通常长这样。spring: profiles: active: dev --- spring: config: activate: on-profile: dev datasource: url: jdbc:mysql://localhost:3306/book_trade?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0把数据库账号密码改成你自己的然后在项目根目录执行Maven命令。mvn spring-boot:run等控制台出现“Started BookTradeApplication”之类的日志服务就起来了。因为myBuilder生成的工程里自带Swagger依赖你直接访问http://localhost:8080/swagger-ui/index.html就能看到一个可以交互调试的API文档界面。这一步给很多没见过企业级项目结构的学生带来的冲击是很大的自己以前做完课设最多拿Postman一个个敲接口测试从来没有过一份自动生成的、随时可以联调的接口文档。实际上Swagger/OpenAPI在企业里就是前后端协作的基础设施不会这个实习第一天联调就能卡住。4. 生成代码背后的事这一整套结构每天都在解决什么问题这一节我想把myBuilder生成的那套代码逐层拆开来讲。不是说生成的代码就是标准答案就完事了你得理解它每一层存在的理由才能真正在企业项目里游刃有余。4.1 统一返回体与全局异常为什么接口不能想返回什么就返回什么先看一个很多学生不理解的问题接口为什么非要包一层Result前端拿到不就直接是数据吗多包一层不麻烦吗要解释这个问题我一般会说一个场景前端页面上有一个列表正常情况下接口返回一个数组。如果这时候后端出错了你说接口该返回什么如果后端直接抛异常前端拿到的是HTTP 500的响应页面直接白屏。如果后端返回null前端拿到null之后遍历报错一样白屏。不管是哪种用户看到的都是“这个系统坏了”。在企业项目里我们要求接口无论成功还是失败返回给前端的结构都是一致的。成功就返回数据失败就返回错误码和错误信息。前端只需要判断状态码就能决定是渲染数据还是弹出错误提示。myBuilder生成的Result结构通常长这样。public class ResultT { private Integer code; private String message; private T data; private Long timestamp; public static T ResultT success() { return build(200, success, null); } public static T ResultT success(T data) { return build(200, success, data); } public static T ResultT error(Integer code, String message) { return build(code, message, null); } private static T ResultT build(Integer code, String message, T data) { ResultT result new Result(); result.setCode(code); result.setMessage(message); result.setData(data); result.setTimestamp(System.currentTimeMillis()); return result; } }配合全局异常处理类业务代码里你就不用到处写try-catch了。Service层只管抛业务异常比如“库存不足”“无权操作”全局异常处理器统一接住转成规定的错误码返回。这样既保证接口返回结构一致又让业务代码干净很多可维护性大大提高。4.2 分层边界Controller、Service、Mapper各管一段MyBuilder生成的工程里一个典型请求的流转路径是这样的前端请求进入ControllerController只做接收参数、简单校验、调用Service。Service负责核心业务逻辑比如检查卖家是不是当前用户、书籍是否在售、库存够不够然后通过Mapper访问数据库。Mapper只管数据读写不掺和业务判断。为什么要分这么细核心原因是可替换性和可测试性。如果Service是一个独立接口那我们可以在测试的时候用Mock对象替换掉真实实现不需要连数据库就能测试业务逻辑。如果Controller不直接写SQL那以后换数据库、换持久层框架业务逻辑不受影响。分层结构看着多写了很多类但企业项目动辄几十个人协作没有清晰分层很快就会变成一坨谁也看不懂的代码。学生在写课设的时候往往觉得分层浪费时间一个简单的增删改查直接Controller里写SQL多快。确实快但如果代码总量是几十个接口不分层的代码你两周后自己都未必能维护。企业开发不是写一次性脚本而是写“要长期养着的代码”。这个观念早一点建立职业发展会顺很多。4.3 注解授权后端权限为什么要用拦截器统一做生成代码里自带了一套基于JWT和注解的鉴权模板这是我在带项目时要求大家必须能讲清楚的部分。流程大体是这样的用户登录成功后后端签发一个JWT令牌前端请求时把它放在请求头里。后端有一个拦截器统一拦截所有需要登录的接口先从Header里取出令牌并校验如果令牌有效就把当前用户信息解析出来放进上下文。然后Controller方法上的RequireRole注解决定谁能访问这个接口。GetMapping(/admin/users) RequireRole(RoleConstant.ADMIN) public ResultPageResultUserVO listUsers(UserQuery query) { return Result.success(userService.pageUsers(query)); }这套机制的价值在哪里第一权限判断不再散落在每个方法里而是通过注解声明式地控制代码可读性极高。第二登录态校验是统一在拦截器里做的新写的接口默认就在保护范围内防止有人忘记加鉴权。第三JWT本身是无状态的服务端不需要保存session天然适合前后端分离架构。很多同学在做课设时都是把用户ID存在session里然后每个接口从session里取。这套方案在单体本地部署时没问题但一旦前端和后端分开部署或者后端起了多个实例session就不好使了。企业里现在普遍的做法就是JWT或者其他token方案。myBuilder生成的这套模板虽然不是企业里的全部但足够让你理解“无状态认证”到底是怎么回事这个理解在面试里非常重要。5. 生成之外的三件套日志、文档、部署脚手架能帮你生成骨架但企业级开发里的很多东西在骨架之上还得自己动手。我自己带项目时有一条原则代码能跑不算完能给别人看、能让别人接手才算阶段性完成。所以我把日志规范、API文档和部署演示这“三件套”单独拉出来说。5.1 日志规范别再System.out.println了学生项目最常出现的排查方式就是System.out.println打印变量然后去控制台翻。这么做在小项目里能凑合但企业项目里控制台日志根本不会长期保存你要排查线上问题只能去日志系统里查。所以从一开始就养成用日志框架的习惯很重要。myBuilder生成的工程里默认集成了SLF4J你在类上声明一个Logger就能用。要注意的是日志级别开发环境用DEBUG方便调试生产环境用INFO和ERROR减少量。重要的业务操作比如用户下单、修改订单状态要打INFO日志异常信息要打ERROR日志并且一定要带异常堆栈不要只打一句“出错了”。Slf4j Service public class BookServiceImpl implements BookService { Override public void publishBook(BookPublishRequest request) { // 业务代码 log.info(用户 {} 发布书籍{}, request.getSellerId(), request.getTitle()); } }你在日志里带上业务上下文信息出问题的时候才能还原现场。不带上下文的日志等于没打这个点一定要记住。5.2 API文档接口写好还要讲得清楚在校园里做项目接口文档通常是Word文档写完几天后就没人看了。企业里用的是Swagger/OpenAPI自动化文档代码里的注解就是文档的一部分。ApiOperation(value 分页查询书籍, notes 支持按书名模糊查询、按价格区间筛选) GetMapping(/page) public ResultPageResultBookVO page(BookQuery query) { return Result.success(bookService.pageBooks(query)); }生成工程里Controller自带这些注解把文档信息补全之后前端同事直接看swagger界面就知道接口需要什么参数、返回什么结构。在面试时如果你能说一句“我做的项目有完整的Swagger接口文档前后端通过它进行联调”面试官对项目的认可度会明显不一样。5.3 部署演示用Docker把项目跑给面试官看很多学生项目最后演示的时候要现场启动IDEA、可能要改数据库配置、可能要等好久编译。这个体验非常不专业。企业级开发里部署讲的是可复现一套配置、一个命令、到处运行。Docker就是干这个的。myBuilder生成的工程里一般会带一个Dockerfile内容大概是这样。FROM maven:3.8-openjdk-17 AS build WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src RUN mvn package -DskipTests FROM openjdk:17-jre-slim WORKDIR /app COPY --frombuild /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]构建并运行只需要两条命令。docker build -t book-trade:1.0 . docker run -d -p 8080:8080 --name book-trade book-trade:1.0不管换到哪台机器只要有Docker环境都能以相同方式跑起来。我在让学生准备项目答辩和简历之前都会要求他们把项目打成Docker镜像录一段启动和调用接口的演示视频。这一套流程比满屏代码的PPT有说服力太多了。6. 落地过程中踩过的坑与应对清单工具再好真用起来还是会踩坑。下面这几个是我带学生用myBuilder做项目时遇到的高频问题也是大家以后用类似脚手架工具大概率会碰到的。我把排查链路写出来方便你照着走一遍。6.1 坑一生成的实体类里字段类型对不上有些同学数据库里用的decimal字段生成的Java类型是BigDecimal这个是正常的。但有人用了tinyint(1)myBuilder映射成了Boolean然后代码里判断状态就变成了true/false。如果数据库里的0、1含义不是布尔语义很容易产生困惑。排查思路是先看数据库字段类型再看生成配置里有没有类型映射规则最后看实体类里实际映射成的类型。我的建议是状态类字段哪怕是0/1两个值也尽量用Integer不要用tinyint(1)去“省空间”。语义清晰比省几个字节重要得多。6.2 坑二权限拦截器把登录接口也给拦截了这是JWT鉴权模板最常见的坑。myBuilder生成的拦截器配置默认拦截所有路径但登录接口和Swagger文档路径必须放行。你会遇到项目启动后访问登录接口返回401的情况。解决方法是去WebMvcConfigurer的配置类里把白名单路径补全。以我常用的配置为例至少要放行这些。Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns(/**) .excludePathPatterns( /api/auth/login, /api/auth/register, /doc.html, /webjars/**, /swagger-resources/**, /v3/api-docs/**, /swagger-ui/**, /error ); }加白名单的时候有一个细节经常被忽略Swagger在Spring Boot 3里的路径跟Spring Boot 2不一样。如果你用的版本比较新swagger路径是多一个/v3/api-docs的漏掉它接口文档页面打不开。6.3 坑三改了生成代码之后重新生成被覆盖脚手架工具普遍存在“二次生成覆盖手写代码”的问题。myBuilder在这一点上处理得还可以它生成时会保留一部分手写区域但如果你把逻辑写在生成的类里覆盖后这些代码还是会丢。所以从第一天就要养成习惯生成的文件分两类一类是通用的、可以重复生成的基类一类是你手写的、继承基类的扩展类。业务代码尽量写在扩展类和Service实现类里不要动Entity和基类Controller。如果myBuilder支持给某些表配置跳过生成那就不需要改动的表直接跳过生成从源头避免覆盖问题。6.4 坑四跨域问题导致前端调不通接口前后端分离项目常见跨域。前端跑在8081端口后端跑在8080端口浏览器就会拦截请求。很多同学遇到这个问题就去网上复制一段CORS配置但不知道原理。配置CORS的核心是告诉浏览器哪些来源的请求可以被后端接受。myBuilder生成的工程里一般提供统一的CORS配置类你只需要把允许的来源地址改成前端的地址就可以。本地调试时大概是这样。Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(http://localhost:*); config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }这里有一个很关键的坑如果allowCredentials设置为了trueallowedOrigins就不能用通配符“*”要用allowedOriginPatterns指定模式。你复制网上的代码时如果没注意这点会出现“打开开发者工具看跨域报错但配置好像又没错”的诡异情况。这类问题排查起来耗时很长我自己至少在这上面卡过两回才彻底记住。6.5 坑五不读生成的代码直接往里堆逻辑这个不算技术坑是意识坑。有人生成完工程之后看都不看生成的类是什么直接在自己新建的类里写代码结果整个工程出现了两套规范一套是myBuilder生成的企业风格代码一套是自己以前的学生风格代码。两套风格混在一起比完全没有规范更难受。所以我带项目时给的铁律是生成之后第一件事把核心类读一遍懂了再动手。Entity里有哪些注解、Result是怎么封装的、GlobalExceptionHandler处理了哪些异常这些花二十分钟读一遍后面写代码会顺利很多。最后说几句实在的我把myBuilder这套东西带进校园项目实践之后最大的感触不是大家代码量多写了多少而是很多学生第一次对“企业级web开发”有了具体的体感。以前他们听“统一异常处理”觉得抽象看到生成的代码就明白了以前听“JWT鉴权”觉得高深看到拦截器配置就理解了以前不知道Spring Boot项目除了“能跑”还要“能部署”自己动手打了Docker镜像之后这个问题也通了。如果你是一个在校生建议别把myBuilder只当成写毕设的工具多花一点时间读读它生成的代码想想每一层为什么这么设计再试着把它生成的骨架改成自己的业务这一套下来你收获的不仅是一个能交差的项目而是一套可以带到实习岗位上的工作方式。工具总在更新但“先搭骨架、再填逻辑、注重规范、方便维护”这套思路不管以后用什么框架都不过时。
返回列表