一、前言
这一篇换个技术栈,聊 LikeShop 多商户 JAVA 版——一套基于 Spring Boot 的 B2B2C 平台型电商系统。
先抛出一个核心判断:多商户系统的难点从来不是“支持多少个店铺”,而是在一套共享架构下,如何同时保证数据隔离、权限分层和高并发承载能力。从工程视角来看,多商户系统本质上是多租户系统 + 权限系统 + 高并发系统的组合体。商户数据必须严格隔离、商品订单支付能力需要共享、所有商户的流量会叠加——这三重挑战决定了多商户系统的复杂度远高于单商户系统。
LikeShop 多商户 JAVA 版用一套多模块分层架构来应对这些挑战。这篇文章就从技术栈选型、分层架构、数据隔离、商家入驻和前后端分离五个层面,把它的架构设计拆开讲清楚。
二、多商户系统的本质:多租户架构
在讨论技术实现之前,有必要先厘清多商户系统的真正复杂度所在。很多商城系统介绍技术栈时只会罗列框架和数据库,但真正有价值的问题是:这些技术如何协同解决复杂电商业务?
多商户系统在工程层面本质上是一个多租户系统,它需要在一套系统中承载多个相互隔离但共享基础能力的业务单元。这带来了三个系统级挑战:
数据隔离(Tenant Isolation):商户数据必须严格隔离,防止越权访问。商户 A 不能看到商户 B 的订单、商品、客户数据。
资源共享(Shared Infrastructure):商品、订单、支付等基础能力需要共享,避免每个商户重复建设一套系统。
并发叠加(Concurrency Amplification):平台总流量是所有商户流量叠加的结果,且存在热点不均衡——某个商户的大促可能瞬时拉高整个平台的负载。
这三个挑战决定了 LikeShop 多商户 JAVA 版在架构设计上的核心诉求:隔离性、共享性、可扩展性。
三、技术栈选型:稳定优先的工程取舍
LikeShop 多商户 JAVA 版的技术栈不是“随意组合”,而是围绕稳定性、可扩展性和工程效率来设计的。
3.1 后端技术体系
| 层级 | 技术选型 |
|---|---|
| 基础框架 | Spring Boot 2.7.5 |
| 开发语言 | Java 1.8 |
| 项目管理 | Maven |
| ORM 框架 | MyBatis Plus 3.5.2 |
| 数据库 | MySQL 5.7.49 |
| 权限框架 | Sa-Token 1.32.0 |
| 缓存 | Redis |
| JSON 处理 | Fastjson2 2.0.16 |
为什么选择 Spring Boot 2.7.x + Java 8 而不是 Spring Boot 3.x + Java 17?答案很现实:电商系统优先考虑“稳定性 + 生态成熟度”。Spring Boot 2.7.x + Java 8 的组合生态最成熟、兼容性最好、企业使用最广。大量第三方库(支付、物流、短信等)在 Java 8 下经过长期考验,升级到 Java 17 可能引入不可预见的兼容性风险。对于电商业务,减少不可控问题远比“追新”更重要。
为什么选择 MyBatis Plus 而不是 JPA/Hibernate?MyBatis Plus 更接近原生 SQL,开发人员对最终执行的 SQL 有完全控制权。电商系统中经常需要复杂的统计查询、联表聚合,ORM 的自动映射容易产生性能坑,而 MyBatis Plus 允许精细调优,同时提供基础 CRUD 能力减少重复代码。
3.2 前端技术体系
LikeShop 多商户 JAVA 版的前端采用多端统一与工程化的设计思路,分为两条线:
管理后台(Admin):Vue 3 + TypeScript + Vite + Element Plus,状态管理使用 Pinia。Vue3 + TypeScript 提升代码可维护性和类型安全,Vite 提供快速的构建体验。
商户端 / 用户端(多端统一):UniApp + Vue 3 + TypeScript,支持微信小程序、支付宝小程序、H5 等平台的统一编译。一套代码多端运行,避免多端重复开发和维护成本爆炸,同时保证商品逻辑和订单逻辑在各端的一致性。
四、多模块分层架构
LikeShop 多商户 JAVA 版采用多模块分层设计,而不是单体“代码堆”。通过模块化 + 分层来防止业务逻辑互相污染,这是主动控制复杂度扩散的核心手段。
4.1 典型分层结构
从官方开发文档来看,服务端采用如下的分层结构:
server/ ├── like-admin/ # 后台应用模块 │ └── src/main/java/com/mdd/admin/ │ ├── cache/ # 缓存层 │ ├── config/ # 配置层 │ ├── controller/ # 控制器层 │ ├── service/ # 服务层 │ │ └── impl/ # 实现层 │ ├── validate/ # Dto 层(参数校验) │ └── vo/ # Vo 层(返回数据) ├── like-front/ # 前端应用模块 ├── like-common/ # 公共类库 │ ├── config/ # 全局配置 │ ├── core/ │ │ ├── entity/ # 实体目录 │ │ ├── exception/ # 异常目录 │ │ ├── mapper/ # Mapper │ │ ├── plugin/ # 扩展插件 │ │ ├── utils/ # 工具目录 │ │ └── validator/ # 自定义验证器 │ └── ... └── like-generator/ # 代码生成器各层的职责边界非常明确:
Controller 层:只做简单的调用,不做具体的逻辑实现。主要负责参数接收,调用 Service 层,返回 JSON 数据。如特殊要求不在此处编写逻辑代码。
Service 层:主要编写功能相关逻辑,提供给 Controller 层调用,或者其它 Service 层调用。
Validate 层:负责请求参数的处理和对参数的校验。
Vo 层:负责返回前端规定的字段格式。
Cache 层:统一存放缓存的实现类。
这种分层的实际好处是:当营销规则变更时,只需修改 domain 中的相关领域对象,不会波及 api 和 infrastructure。复杂业务被隔离在特定层级,整个系统不至于“牵一发动全身”。
4.2 请求拦截与权限控制
LikeShop JAVA 版使用Sa-Token作为权限框架,无论是登录拦截还是权限拦截,统一在LikeAdminInterceptor中完成。
拦截器提供了两个关键注解:
- @NotLogin:标记该接口不需要登录也能访问
- @NotPower:标记该方法不需要校验权限
这两个注解通常不会同时出现在一个方法上,因为如果添加了免登录,则不需要登录权限。
4.3 全局状态码体系
LikeShop 定义了全局公共的响应状态码,方便根据状态码快速排查错误:
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 300 | 失败 |
| 310 | 参数校验错误 |
| 330 | 登录账号或密码错误 |
| 332 | token 参数为空 |
| 333 | token 参数无效 |
| 403 | 无相关权限 |
| 404 | 请求接口不存在 |
| 500 | 系统错误 |
五、多租户数据隔离实现
多租户数据隔离是多商户系统的“生命线”。LikeShop 多商户 JAVA 版采用单库多租户方案,通过tenant_id字段实现数据隔离。
5.1 数据隔离方案
所有核心表(order、product、user 等)必须包含tenant_id字段。查询时通过tenant_id过滤数据,确保商户只能访问自己的数据。
关键约束有三条:
所有查询必须带tenant_id。这是最核心的约束,任何遗漏都可能导致跨商户数据泄露。
DAO 层统一封装。在数据访问层统一处理tenant_id的注入和过滤,避免在每个业务查询中手动拼接。
防止越权访问。商户端的查询接口必须校验当前登录商户的tenant_id是否与目标数据的tenant_id一致。
5.2 权限模型的多商户适配
LikeShop 多商户 JAVA 版的权限模型支持三级分层:平台 → 商户 → 子账号。
这个模型的核心是登录态分离:平台用户、商户用户、C 端用户是三个独立的登录态体系,各自有独立的会话管理。平台管理员可以管理所有商户的数据,商户管理员只能管理自己店铺的数据,子账号根据角色分配不同的操作权限。
这种设计与 PHP 多商户版的 RBAC 模型是一致的,区别在于 JAVA 版用 Sa-Token 替代了 PHP 版的自研中间件,权限校验的粒度更细、扩展性更好。
六、多商家入驻的实现
商家入驻是多商户系统的核心功能,也是平台招商能力的体现。LikeShop 多商户 JAVA 版实现了完整的商家入驻流程。
6.1 入驻流程
商家入驻的完整流程如下:
第一步:平台设置入驻协议。平台在后台设置商家入驻协议,商家必须同意协议才能提交入驻申请。协议支持富文本编辑,展示在商城端的商家入驻申请表单页面。
第二步:商家提交入驻申请。商家通过手机端或商城端提交入驻申请,填写店铺名称、经营类目、联系人信息等基本资料。
第三步:平台审核。平台端运营人员在后台查看入驻申请,点击审核按钮进行审批。选择审核通过时,系统会根据商家填写的基本信息自动创建商户并生成管理员账号,同时发送短信通知商家后台登录地址、初始账号和密码。
第四步:开通商家后台。审核通过后,商家获得独立的商家管理后台,可以自由上架商品、设置秒杀、拼团活动等。
6.2 商家管理的能力
平台端对商家提供完整的管理能力,包括:批量新增商家(需填写基础设置、经营设置、账号设置三部分内容)、商家权限分级、产品审核开关配置(自营旗舰店可设置无需产品审核,第三方入驻商家则开启产品审核)。
商家端的核心能力包括:独立后台管理、商品上架与管理、营销活动设置(秒杀、拼团)、订单查看与处理、财务管理与提现申请。
七、前后端分离的工程实现
LikeShop 多商户 JAVA 版采用前后端分离架构,前端和后端通过 RESTful API 交互。
7.1 前后端分离的工程结构
前后端分离的核心体现是:前端代码和后端代码完全分离,通过 API 接口通信。
- 后端提供 API 接口,前端通过 HTTP 请求调用
- 管理后台、商户端、用户端都是独立的前端工程
- 前端编译后的静态资源部署到 Nginx,通过反向代理调用后端 API
7.2 前端多端统一的实现机制
用户端采用 UniApp + Vue 3 + TypeScript,通过条件编译实现多端适配。微信小程序、支付宝小程序、H5 等平台的差异逻辑通过条件编译包裹,编译到不同平台时自动裁剪。
这种设计的核心价值是统一业务表达:商品逻辑一致、订单逻辑一致,避免了多端重复开发带来的维护成本爆炸。
7.3 AI 辅助开发的工程规范
值得一提的一个细节是:项目根目录内置了 AGENTS.md 和 CLAUDE.md 两份 AI 项目规范文件,能让 Cursor、Claude 等 AI 编程工具快速理解项目架构和业务逻辑。对于习惯用 AI 辅助开发的团队来说,这个设计可以减少 AI 生成代码与项目风格不一致的问题。
八、高并发模型
多商户平台的总流量是所有商户流量的叠加,且存在热点不均衡,这对系统的并发承载能力提出了更高要求。LikeShop 多商户 JAVA 版的请求链路设计为:
请求 → 限流 → Redis → MQ → MySQLRedis承担多重角色:热数据缓存、库存预扣、登录态存储、权限校验、并发削峰。
MQ(消息队列)负责异步化处理:下单削峰、日志处理等非核心操作异步执行。
MySQL作为最终一致性的保障:核心数据落库、强一致保证。
这个设计的本质思想是把压力从数据库转移到缓存与队列。核心数据最终落库到 MySQL,但在高并发场景下,Redis 和 MQ 承担了绝大部分的读请求和写削峰。
九、总结
LikeShop 多商户 JAVA 版的架构设计可以概括为四条线:
多租户隔离:单库多租户方案,通过tenant_id字段实现数据隔离。所有查询必须带tenant_id,DAO 层统一封装,防止越权访问。这是多商户系统的生命线。
多模块分层:Controller → Service → Domain → Mapper 的分层结构,业务逻辑隔离在特定层级,避免牵一发动全身。支持模块拆分,为后续微服务演进预留空间。
商家入驻闭环:平台设置入驻协议 → 商家提交申请 → 平台审核 → 自动创建商户和管理员账号 → 开通独立商家后台。形成完整的招商入驻闭环。
前后端分离:管理后台 Vue 3 + Element Plus,用户端 UniApp + Vue 3 多端统一。一套代码多端运行,统一业务表达,降低维护成本。
把这四条线理解清楚,就能把握 LikeShop 多商户 JAVA 版的架构全貌——它不是在 PHP 版基础上简单翻译,而是一套围绕 Java 生态重新设计的工程化体系。