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

资讯详情

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

Spring Boot二手交易平台实战:从设计到部署全解析

Spring Boot二手交易平台实战:从设计到部署全解析 简介这是一套面向计算机专业本科生及毕业设计开发者的Spring Boot二手交易平台完整实现方案聚焦Web全栈开发实践与电商类系统架构训练。资源包含前后端分离的可运行源码、详细部署说明文档及配套SQL脚本覆盖用户注册登录支持QQ/微信第三方、商品发布与搜索、订单全流程管理、支付宝/微信支付集成、站内信与邮件通知、JWTSSL安全防护等核心业务模块。压缩包共810个文件含130个Java后端逻辑文件、48个Vue前端组件、153个JS交互脚本、44个CSS/HTML页面资源、79个GIF动效及SVG图标等结构清晰便于按层学习与二次开发整体大小为16.78MB。目前已有690人下载学习适合用于课程设计、毕设选题或Spring BootVue技术栈的工程化能力提升开箱即用且具备完整交易闭环能力。 作为一个常年用 Spring Boot 折腾各种项目的人拿到二手交易平台这种题目第一反应是这不又是一个典型的 CRUD 练手项目吗但真要把一个带完整源码、能直接部署上线、还有像样交易闭环的平台做出来里面的门道其实比想象中多得多。它不只是用户注册登录、发个商品、下个单那么简单支付状态怎么流转、商品上下架怎么处理、图片存在哪、会话怎么保持这些问题在写代码的时候都会逼着你做选择。这篇文章我会以一个实际可运行的 Spring Boot 二手交易平台为核心把项目从需求拆解、数据库设计、后端接口实现到最后的本地部署、云服务器部署甚至 Docker 打包一条线完整讲透。适合正在做毕业设计、想熟悉 Spring Boot 全流程开发、或者打算接私活做商城类项目的朋友照着这篇内容可以少走很多弯路。1. 项目整体设计与技术选型思路1.1 先想清楚二手交易平台的本质很多人一上来就急着重写用户表、商品表、订单表但其实先想清楚业务闭环更重要。二手交易平台和普通电商最大的区别在于买家卖家都是普通用户没有平台自营、没有商家后台核心流程是用户注册登录发布闲置商品设置价格和成色其他用户浏览搜索感兴趣就下单卖家看到订单后确认发货买家收货后确认完成整个过程围绕一件二手商品的状态变更展开。所以设计时要把商品状态和订单状态当作两条独立的状态机来看。商品有在售、下架、已卖出三种状态订单有待付款、待发货、待收货、已完成、已取消五种状态。每一个状态变更都要有明确的操作入口和权限校验比如只有卖家能把商品下架只有买家能确认收货。把这个想明白了后面写 Service 层的业务逻辑就很顺畅。1.2 技术栈选型Spring Boot 为主前后端分离为辅这个项目我选择的是标准的前后端分离架构后端用 Spring Boot前端用 Vue 3 Element Plus。Spring Boot 负责提供 RESTful API前端通过 axios 调用接口渲染页面。这样做有好处接口可以被 PC 端、移动端、小程序等多端复用开发时前后端可以并行遇到问题排查起来也清晰后端返回 JSON前端渲染页面谁出错看谁。后端内部的选型也值得一提。持久层我用了 MyBatis-Plus它和 Spring Boot 是绝配内置的BaseMapper能把单表 CRUD 的工作量砍掉一大半分页插件通过一个MybatisPlusInterceptor配置就能搞定实在需要手写 SQL 的部分用Select注解写在 Mapper 接口里就行。鉴权方案没有用重的 Spring Security 加 OAuth2而是选择了轻量级的 JWT在拦截器里做 Token 校验逻辑直观、代码量少对中小型项目来说完全够用。注意Spring Boot 版本建议用 2.7.x不要去追最新的 3.x。很多第三方 starter 对 3.x 的 Jakarta 命名空间适配还有坑网上资料也多以 2.x 为主出了问题好查。JDK 用 1.8 或 11 都行如果是 17 以上记得注意兼容性。1.3 工程结构怎么摆才不混乱项目包结构我按模块分包而不是技术分包来组织这样后期维护找文件效率高很多com.example.secondhand ├── config # 配置类CORS、拦截器、MyBatis-Plus分页插件、文件上传 ├── controller # 控制器层只做参数接收和结果返回 ├── service # 业务逻辑层核心业务都在这 │ └── impl # 实现类 ├── mapper # MyBatis-Plus 的 Mapper 接口 ├── entity # 数据库实体类 ├── dto # 前端交互的对象登录请求、商品发布请求等 ├── vo # 视图返回对象统一响应格式 ├── utils # 工具类JWT、MD5、文件上传工具 └── common # 全局异常处理、返回结果封装我见过不少人的项目所有代码堆在几个包下面controller 里写 SQL、entity 里塞业务逻辑一开始觉得快后面改需求简直想哭。模块分包会让每个类的职责单一controller 只负责接收参数和响应service 只负责业务逻辑mapper 只负责数据库操作这是 Spring Boot 项目能不能持续迭代的分水岭。2. 数据库设计核心表结构与关键字段解析2.1 五张核心表的职责划分数据库设计是整个项目的基石表结构不合理后面写代码全是痛苦。二手交易平台最小的数据集合需要五张表用户表、商品表、订单表、收藏表、留言表。实际扩展还可以加轮播图表、分类表但核心五张表必须先设计好。用户表user的核心字段包括id、username、password、nickname、avatar、phone、balance。这里balance是用户余额用于模拟交易支付避免真实对接支付网关的麻烦。密码字段只存 MD5 或 BCrypt 加密后的密文绝对不允许明文。商品表product是最重要的一张表字段包括id、user_id、title、description、price、original_price、category、condition_level、images、views、status。注意price和original_price我用的是decimal(10,2)类型用 BigDecimal 对象接收。images字段存的是 JSON 数组字符串形如[/uploads/1.jpg,/uploads/2.jpg]前端拿到后直接JSON.parse就能用省去一张图片关联表的开销。订单表order字段是id、order_no、product_id、seller_id、buyer_id、price、status、create_time、pay_time、ship_time、confirm_time。order_no是业务编号手动生成格式类似20250315123000001不要直接用自增 id 当订单号给用户看会暴露平台数据量也容易被遍历。收藏表和留言表相对简单主要存储关联关系。2.2 几个容易忽略却关键的设计细节第一所有表都加上create_time、update_time两个时间字段MyBatis-Plus 有TableField(fill FieldFill.INSERT)配合MetaObjectHandler能自动填充省心而且排查问题时能知道每条数据是什么时候产生和修改的。第二商品表要有deleted逻辑删除字段用户下架商品不是真删数据只是标记删除这样已下单的订单还能追溯到商品快照信息。第三金额字段的设计是最容易踩坑的地方。电商业务中金额一律用BigDecimal禁止用double和float。我在项目里亲眼见过0.1 0.2 0.30000000000000004这种问题在交易场景中出现那真的是事故。数据库字段用decimal(10,2)精确到分Java 实体用 BigDecimal中间任何计算都用 BigDecimal 的方法不要用运算。第四商品表中的seller_id和订单表里的seller_id、buyer_id都属于用户表的外键但实际开发中我通常不加物理外键约束只加普通索引。原因很简单物理外键在批量导入数据、逻辑删除、分库分表时会带来额外开销和约束功能上用代码保证数据一致性就够了项目里用逻辑外键是常见的做法。2.3 初始化 SQL 脚本和测试数据源码里一定带一个sql/init.sql里面除了创建数据库和建表语句我还会预置几条测试数据比如一个管理员账号admin/admin123、一个普通用户test/test123以及七八条不同分类的商品记录图片用占位图路径。这样拿到源码的人导入数据库后一启动项目不用注册就能直接登录看到效果体验好很多。测试数据很重要因为前端页面拿到空数据时看不出布局效果分布式部署时也方便验证接口是否打通。我在商品表预置数据时故意让两条商品处于已卖出状态这样首页展示已售标签、详情页展示已下架按钮马上能看到状态机的作用也算是一种隐性的演示设计。3. 核心功能实现从登录鉴权到订单流转3.1 JWT 登录鉴权与全局拦截器配置登录逻辑不复杂前端提交用户名和密码后端校验通过后生成一个 JWT 返回给前端前端存在 localStorage 里以后每次请求在 header 里带上Authorization: Bearer token后端拦截器解析 token 拿到用户 id 并放入 ThreadLocal。我在config包下写了一个JwtInterceptor实现HandlerInterceptor核心方法preHandle里做这些事public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行 OPTIONS 预检请求 if (OPTIONS.equals(request.getMethod())) { return true; } String token request.getHeader(Authorization); if (StringUtils.hasText(token) token.startsWith(Bearer )) { token token.substring(7); try { Claims claims JwtUtil.parseToken(token); // 将用户id存入 request 属性后续 Controller 通过参数获取 request.setAttribute(userId, claims.get(userId)); return true; } catch (Exception e) { throw new BusinessException(401, 登录状态已过期请重新登录); } } throw new BusinessException(401, 未登录请先登录); }然后注册到 WebMvcConfigurer 中同时配置放行路径登录接口、注册接口、首页商品列表接口、商品详情接口这些不需要登录就能访问的接口。ThreadLocal 的用法我在项目里测过简单场景好用但要注意请求结束后清理否则线程池复用会导致数据串号。这里我选择把 userId 直接放进request.setAttribute用的时候从 request 取更安全也更直观。拦截器的执行时机是在 Controller 方法之前所以被拦截的接口里能直接从 request 里拿到当前登录用户的 id省去每个接口手动解析 token 的重复代码。3.2 商品发布与文件上传图片到底存哪里商品发布功能涉及到一个绕不开的问题图片存哪里。最省钱省事的方案是本地存储配置一个上传目录用 UUID 重命名文件后保存到/uploads目录然后在 WebMvcConfigurer 里把/uploads/**映射成静态资源路径。上传接口的实现要点public String upload(MultipartFile file) { if (file.isEmpty()) { throw new BusinessException(400, 文件不能为空); } // 限制文件大小和类型 if (file.getSize() 5 * 1024 * 1024) { throw new BusinessException(400, 文件大小不能超过5MB); } String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); ListString allowedSuffix Arrays.asList(.jpg, .jpeg, .png, .gif, .webp); if (!allowedSuffix.contains(suffix.toLowerCase())) { throw new BusinessException(400, 不支持的图片格式); } String newFileName UUID.randomUUID().toString().replace(-, ) suffix; // 按日期分目录存储如 /uploads/20250315/xxx.jpg String datePath new SimpleDateFormat(yyyyMMdd).format(new Date()); File dir new File(uploadPath datePath); if (!dir.exists()) { dir.mkdirs(); } file.transferTo(new File(dir, newFileName)); return /uploads/ datePath / newFileName; }注意文件路径的问题。本地开发时这个绝对路径和项目根目录有关系部署到 Linux 服务器时要确保上传目录存在且有写权限否则会抛FileNotFoundException。我在application.yml里配置了一个自定义属性upload.path上线时直接改配置指向服务器的数据盘路径建议放在项目外例如/data/secondhand/uploads这样以后升级项目也不会把图片搞丢部署时一定要记得把上传目录挂载出来。3.3 订单状态机下单、支付、发货、确认收货订单流程是整个项目业务逻辑最密集的地方也是最容易出 bug 的地方。用户点击立即购买后后端要做的事包括检查商品状态是否在售、获取商品价格、创建订单初始状态为待付款、修改商品状态为已下架防止重复购买、扣减用户余额、生成支付记录。我选择在创建订单时就锁定商品并标记为下架状态避免同一件商品被两个用户同时下单这是二手商品与普通电商的一个显著差异。支付环节我做了模拟支付逻辑是如果余额够就扣减并更新订单状态为待发货不够就提示余额不足。真实项目对接微信或支付宝支付流程也一样只是把扣余额替换成调支付网关回调里再修改订单状态。关键的事务控制不能省。我写了这样一个方法Transactional(rollbackFor Exception.class) public Order createOrder(Long userId, Long productId) { Product product productMapper.selectById(productId); if (product null || !ProductStatus.ON_SALE.equals(product.getStatus())) { throw new BusinessException(商品不存在或已下架); } if (product.getUserId().equals(userId)) { throw new BusinessException(不能购买自己发布的商品); } // 扣减买家余额 int rows userMapper.deductBalance(userId, product.getPrice()); if (rows 0) { throw new BusinessException(余额不足); } // 给卖家加余额 userMapper.addBalance(product.getUserId(), product.getPrice()); // 标记商品已下架 productMapper.updateStatus(productId, ProductStatus.SOLD); // 创建订单 Order order new Order(); order.setOrderNo(generateOrderNo()); // 省略设置字段... orderMapper.insert(order); return order; }Transactional保证下面的操作要么都成功要么都失败比如扣买家余额成功之后卖家加余额失败事务回滚不会造成资金不一致。这里有个细节扣余额用UPDATE user SET balance balance - #{price} WHERE id #{userId} AND balance #{price}这条 SQL 来保证原子性在高并发下也不会有超扣问题。事务方法不能被同类内部调用否则注解失效这个问题我在项目里踩过坑也建议你在写代码时留意。3.4 商品搜索、分类筛选与分页首页商品列表通常支持三种检索维度按关键字模糊匹配标题、按分类精确过滤、按价格升序降序排序。我用的 MyBatis-Plus 的 LambdaQueryWrapper 写起来很简洁public PageProductVO listProducts(int page, int size, String keyword, String category, String sort) { PageProduct p new Page(page, size); LambdaQueryWrapperProduct wrapper new LambdaQueryWrapper(); wrapper.eq(Product::getStatus, ProductStatus.ON_SALE) .eq(StringUtils.hasText(category), Product::getCategory, category) .and(StringUtils.hasText(keyword), w - w.like(Product::getTitle, keyword) .or().like(Product::getDescription, keyword)) .orderByDesc(sort.equals(new) ? Product::getCreateTime : Product::getViews); productMapper.selectPage(p, wrapper); // 转 VO附带卖家昵称和头像 return convertToVO(p); }分页大小我固定为 12前端每页显示 12 条比较整齐。关键字搜索的or条件需要用and(...)方法包一层否则会和其他eq条件拼出错误的 SQL。另外搜索时商品列表只返回在售商品但详情页可以显示已售和下架商品让用户知道这件商品已经卖出去了避免重复咨询。4. 部署说明从本地跑起来到云服务器上线4.1 本地环境准备JDK、Maven、MySQL、Redis拿到源码后本地部署需要准备的环境如下组件版本建议用途JDK1.8 或 11编译运行 Java 代码Maven3.6依赖管理、打包MySQL5.7 或 8.0数据存储Redis5.x 及以上验证码、缓存可选Node.js14前端项目构建如果包含前端JDK 版本这里要多说一句如果源码是 Spring Boot 2.7.x 写的JDK 1.8 是最稳的搭配。有些人的机器装的是 JDK 17启动时可能出现模块访问权限报错要么换回 JDK 8/11要么在启动参数里加--add-opens明显麻烦得多。Maven 建议用 IDEA 自带的 Bundled Maven 或自己下载解压配置好阿里云镜像国内网络环境直接拉默认仓库慢得让人崩溃。MySQL 导入初始化脚本时注意先手工CREATE DATABASE secondhand DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;再use secondhand;后source init.sql;。utf8mb4 一定要用否则用户发商品描述里带个表情符号直接报Incorrect string value错误这是很多新手最容易碰到的编码坑。4.2 配置修改真正要改的只有一处半源码里的application.yml尽量把环境相关配置抽出来部署时按实际情况修改。我贴一下核心配置块来说明server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/secondhand?useUnicodetruecharacterEncodingutf8mb4useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: 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 # 自定义配置 upload: path: /data/secondhand/uploads jwt: secret: your-secret-key-please-change expire-hours: 24密码改成你自己的upload.path改成你想存图片的目录jwt.secret一定要改成一个足够长的随机字符串否则 token 可以被伪造。密码加密建议用 BCrypt 而不是 MD5源码里如果看到 MD5 工具类可以替换成BCryptPasswordEncoder安全性提升一个档次。如果 Redis 不可用可以把验证码等缓存逻辑降级为本地内存缓存这样最小化部署时可以不装 Redis但生产环境还是建议装上。4.3 Linux 云服务器部署手动部署完整流程云服务器手动部署的流程是打包后端 - 上传 jar 到服务器 - 装环境 - 启动进程 - 配置 Nginx 反向代理。后端打包用mvn clean package -DskipTests打完包在target/目录找到secondhand-0.0.1-SNAPSHOT.jar通过scp或者宝塔面板上传到服务器的/opt/secondhand目录。启动命令用nohup java -jar /opt/secondhand/secondhand-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod /opt/secondhand/logs/app.log 21 nohup和保证进程在 SSH 断开后继续运行。把日志输出到文件是为了出问题时能tail -f查看。如果你希望开机自启可以写一个 systemd service 文件这样进程被误杀时也会自动重启我建议生产环境尽量用 systemd 管理 Java 进程。前端构建后把dist目录里的静态文件放到 Nginx 的html目录Nginx 配置里做两个关键点location /指向静态文件location /api/反向代理到http://127.0.0.1:8080并去掉/api前缀。如果是前后端不分离的单体项目后端直接打包成包含静态资源的 jar省去 Nginx 这层但前后端分离模式下这个配置是标配。部署到云服务器后访问不通的排查路径通常是防火墙有没有开端口、安全组有没有放行、Nginx 有没有启动、后端进程有没有挂掉、数据库白名单有没有限制。按这条链路从外到内一层层排查90% 的问题都能定位。4.4 Docker 部署把环境固化成一个镜像如果服务器上已经装了 Docker把整个 Spring Boot 应用做成镜像会省很多心。一个标准的Dockerfile长这样FROM openjdk:8-jre-alpine WORKDIR /app COPY secondhand-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar, --spring.profiles.activeprod]构建并运行docker build -t secondhand:1.0 . docker run -d --name secondhand -p 8080:8080 \ -v /data/secondhand/uploads:/app/uploads \ -v /data/secondhand/logs:/app/logs \ --restartalways \ secondhand:1.0为什么-v挂载这两个目录因为容器是临时的一旦容器被删掉容器里的数据就全没了。图片上传目录在容器重启或升级时必须持久化到宿主机这是 Docker 部署 Spring Boot 最值得注意的一环。数据库直接用宿主机的 MySQLjar 里配置jdbc:mysql://宿主机IP:3306/secondhand。如果数据库也容器化了建议用docker-compose把 MySQL、Redis、后端应用编排到一起启动一条命令搞定适合演示和交付。5. 常见问题与排查技巧实录5.1 项目启动失败的几类典型问题Spring Boot 项目最常见的启动失败原因是端口被占用。报错信息是Web server failed to start. Port 8080 was already in use.排查方法很简单Linux 上用netstat -tlnp | grep 8080找出占用进程要么 kill 掉要么改项目的端口。Windows 上是netstat -ano | findstr 8080然后去任务管理器结束进程。第二个高频问题是数据库连接失败报Access denied for user rootlocalhost或者Communications link failure。前者是账号密码或权限问题后者是数据库没启动或者 url 写错。判断思路先在本机用命令行连一下 MySQL确认账号密码没问题再查application.yml里的配置是否一致。另外 MySQL 8 的驱动类名是com.mysql.cj.jdbc.Driver老项目里如果还是com.mysql.jdbc.Driver会报警告建议升级。第三个问题是依赖下载不了Maven 报一堆红。这种基本是网络问题或者仓库没配好把settings.xml里的镜像改成阿里云公共仓库clean 一下重新 import。我的经验是本地没网时别碰 Maven 项目装依赖能把人装崩溃。5.2 前后端联调时典型的跨域与请求问题前端页面能打开但接口请求全部失败打开浏览器控制台能看到Access-Control-Allow-Origin相关报错这就是跨域问题。解决方式有两种后端加CrossOrigin或全局 CORS 配置或者通过 Nginx 反向代理同源。开发环境推荐后端加全局 CORSConfiguration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }还有一个很容易忽略的问题拦截器拦截了所有路径但OPTIONS预检请求没放行导致前端发 POST 请求一直报跨域。实际上请求是先发 OPTIONS 预检再发实际请求后端如果拦截器直接拦截 OPTIONS 返回 401那跨域解决得再好也没用。我在 JwtInterceptor 的preHandle里第一行就放了if (OPTIONS.equals(request.getMethod())) return true;这个雷我已经替各位踩过了。5.3 图片上传后访问 404 的排查方法本地测试图片上传成功接口返回了/uploads/20250315/xxx.jpg但浏览器访问这个路径 404。原因基本是静态资源映射没配置。需要在 WebMvcConfigurer 中显式地注册Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/uploads/**) .addResourceLocations(file: uploadPath /); }这里file:前缀不能丢它告诉 Spring 这是一个文件系统路径而不是 classpath 路径。部署到 Linux 后还要确认目录权限chmod 755确保 nginx 或 Java 进程有权限读取。如果是用 Nginx 部署前端和后端分离的结构更稳妥的做法是在 Nginx 层把/uploads/直接映射到服务器磁盘目录不经过 Java 层性能更好。5.4 部署到服务器后接口访问慢或超时本地一切正常部署到云服务器后某些接口偶尔超时先从这几个方面查数据库连接池配置是否偏小、慢 SQL 是否有索引支撑、服务器带宽是不是太小。拿商品列表接口举例如果 product 表只建了主键索引搜索直接全表扫描数据量上来之后接口会越来越慢。解决方式是给status、category、user_id都加上普通索引这种索引占空间可以忽略但对查询性能是质的提升。另外分享一个我自己的习惯上线前一定要先用 JMeter 或 Postman 做一次简单的并发测试不用多复杂100 个并发请求商品列表接口看看平均响应时间和错误率。如果 100 并发就撑不住赶紧回去查慢 SQL 和连接池。我见过太多单人用没问题、一上服务器就崩的情况都是流量没测过就上线。6. 源码之外的几个加分设计很多二手交易平台项目做到基础 CRUD 就停了但真正让人眼前一亮的往往是那些细节设计。这里分享几个我在源码里额外加入、被用户评价最多的功能点。商品浏览量的处理很值得说。如果用数据库字段views累加每次访问都 UPDATE 一次其实没必要。我在 Redis 里用incr累加再定期批量回写数据库减轻数据库压力。如果没有 Redis也可以用内存 Map 加定时任务批量更新但注意要加锁防止并发问题。详情页浏览量做到刷新一次只加一次是前端控制的用 sessionStorage 标记是否已经浏览过。我的发布和我的足迹这两个功能虽然简单但对用户体验提升明显。发布列表就是查询当前用户的所有商品包括在售、下架、已售的配合状态标签和对应操作按钮卖家能清晰地看到每件商品的生命周期。浏览足迹本质是一个浏览记录表插入时做唯一约束、重复浏览时更新时间列表倒序展示这种小功能写起来快但对用户粘性帮助很大。管理员后台也是加分项。虽然二手平台的核心是用户之间交易但平台运营需要管理入口。一个简单的 admin 后台包含用户管理禁用/启用账号、商品管理强制下架违规物品、订单查看、数据统计每日注册量、交易量就能撑起一个项目的完整度。我在源码里单独写了 admin 接口模块Controller 路径以/admin开头拦截器判断当前用户的 role 字段是否为admin用角色区分权限没有引入复杂的权限框架。7. 这个项目还能怎么扩展如果你拿到这份源码之后不满足于现状想往深了做我提供几个方向供参考。第一个方向是增加消息通知功能。买家下单后给卖家发站内信卖家发货后给买家发通知用 WebSocket 做实时提醒。这个可以结合 Spring Boot 封装好了的 WebSocket 支持来写属于中等难度但很见功力的扩展。第二个方向是引入缓存。把首页商品列表、商品分类、热门搜索词放进 Redis热点商品详情做缓存预热接口响应能从几百毫秒降到几十毫秒。这个方向会让你从CRUD 程序员向真正做性能优化的人迈进。第三个方向是接入真实的支付网关。现在源码里是模拟余额支付把支付部分抽象出来对接支付宝当面付或者微信 Native 支付回调处理是这套逻辑里最有含金量的部分。不过做的时候注意要用沙箱环境测试合规方面多看看官方文档。第四个方向是给项目补充单元测试和 CI/CD。写几个核心 Service 层的单元测试用例用 GitHub Actions 或 Jenkins 在提交代码后自动跑测试、自动打包部署流程固化。这个方向虽然不增加业务功能但对工程素养的要求很高面试时也是很好的谈资。最后聊点实际的做了这么多年 Spring Boot 项目我最大的体会是源码能跑起来只是第一步真正值钱的是你对业务逻辑理解的深度和排查问题的能力。多花时间想想这个状态为什么这样流转这个字段为什么这样设计比急着复制粘贴代码有用得多。如果你在本地把这个二手交易平台跑通、部署上线、并且自己动手改了一两个功能那么你对 Spring Boot 的理解绝对会上一个台阶。后面再做其他项目你会发现很多思路都是相通的这就是应有的迭代节奏。本文还有配套的精品资源点击获取
返回列表