news 2026/5/1 6:11:29

微服务架构下的java应用工程结构实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微服务架构下的java应用工程结构实践

1. 为什么需要「工程结构」?

在单体时代,一个 src/main/java 往往就能跑完整业务;到了微服务,每个服务由 1-3 个小组、5-10 名工程师共同维护,生命周期长达数年。此时「工程结构」不再只是目录,而是一份多人协作“约定由于配置”的契约,它有这些好处:

  • 新人 On-boarding:代码在哪里找?该放哪里?一眼即知。
  • 长期可维护:业务膨胀后仍能快速定位、修改、回滚。
  • 自动化友好:目录即边界,CI、测试、覆盖率、安全扫描都可按模块并行。

2. 模块规范 & Java 类后缀最佳实践

下面是pom依赖关系

模块职责类后缀约定
startspring boot启动入口,继承测试放在这个子工程test源码下,所有子工程中的服务都可以在这里写复杂的继承测试无业务代码,仅启动入口和继承测试代码
gateway统一接入、路由、鉴权、限流、异常兜底处理,调用biz层,实现api包中的接口能力,消费消息队列的数据ServiceImpl / Consumer / Handler / Router
api对外暴露的接口 & 请求/响应模型DTO / VO / Request / Response / Result / Service / Constants / Enum
biz围绕业务逻辑,调用core、integration进行业务流程编排、事务、校验,尽量避免biz直接调用daoBizService / BizServiceImpl/ Helper / Executor
integration调用外部 RPC / 发外域模型的消息 / 依赖模型防腐层,所有DO都需遵循模型最小化,不要把依赖方的模型直接当成自己的模型Client / ClientImpl / Producer / DO / Request
core围绕核心领域模型的管理,调用dao进行持久化模型和核心领域模型的转换、组合、同步。比如:一个核心领域模型可能管理多个持久化数据表、同时需要维护持久化和缓存的一致性、还需要把数据的变更下通知给下游应用。领域模型不需要后缀 / CoreService
dao数据访问:持久化存储、缓存。和持久化表、缓存kv结构一一映射DO / Mapper
common复用常量、枚举、工具、异常Constants / Enum / Util / Exception
后缀就是语义化阅读线索。看到OrderBizService就知道是Biz层业务逻辑处理,看到OrderCoreService就知道是订单核心领域模型处理 OrderClient 知道是外部调用;看到 OrderDao 知道是领域存储;看到 OrderMapper 知道是 MyBatis XML 映射。

3. 树形工程目录 & 示例类

下面给出一个典型 order-service 应用的完整目录树。
每个叶子包都提供一个示例类名,可根据需要直接拷贝到 IDE 体验,为了缩短内容,把单测目录省略了,需要的话可自行添加。

order-service ├── start │ └── src/main/java │ │ └── com.example.order.starter │ │ └── Application.java │ └── src/main/resources │ │ ├── application.properties │ │ ├── application-pre.properties │ │ ├── application-dev.properties │ │ └── logback.xml │ └── src/test/java │ │ └── com.example.order │ │ └── ApplicationTest.java │ └── src/test/resources │ ├── application-test.properties │ └── logback.xml ├── api │ └── src/main/java │ └── com.example.order.api │ ├── OrderQueryService.java │ ├── OrderWriteService.java │ ├── result │ │ └── BaseResult.java │ │ └── ListResult.java │ │ └── PageResult.java │ ├── request │ │ └── OrderCreateRequest.java │ ├── response │ │ └── OrderCreateResponse.java │ ├── constants │ │ └── OrderFeatureConstants.java │ ├── enums │ │ └── OrderStatusEnum.java │ └── dto │ └── OrderDTO.java ├── gateway │ └── src/main/java │ └── com.example.order.gateway │ ├── impl │ │ ├── OrderQueryServiceImpl.java │ │ └── OrderWriteServiceImpl.java │ ├── filter │ │ └── AuthFilter.java │ └── router │ └── OrderRouter.java ├── biz │ └── src/main/java │ └── com.example.order.biz │ ├── OrderBizService.java │ ├── impl │ │ └── OrderBizServiceImpl.java │ ├── model │ │ └── OrderBO.java │ ├── helper │ │ └── OrderHelper.java │ ├── executor │ │ └── PaymentExecutor.java │ └── validator │ └── OrderValidator.java ├── integration │ └── src/main/java │ └── com.example.order.integration │ ├── inventory │ │ ├── InventoryClient.java │ │ ├── request │ │ │ └── InventoryRequest.java │ │ └── model │ │ └── InventoryDO.java │ ├── user │ │ ├── UserQueryClient.java │ │ ├── request │ │ │ └── UserQueryRequest.java │ │ └── model │ │ └── UserDO.java │ └── producer │ └── OrderEventProducer.java ├── core │ └── src/main/java │ └── com.example.order.core │ ├── OrderCoreService.java │ └── model │ └── Order.java ├── dao │ └── src/main/java │ │ └── com.example.order.dao │ │ ├── OrderDao.java │ │ ├── mapper │ │ │ └── OrderMapper.java │ │ ├── do │ │ │ └── OrderDO.java │ │ └── impl │ │ └── OrderDaoImpl.java │ └── src/main/resources │ │ └── mapper │ │ └── OrderMapper.xml └── common └── src/main/java └── com.example.order.common ├── constant │ └── BizCodeConstants.java ├── enum │ └── OrderStatusEnum.java ├── util │ └── DateUtil.java └── exception └── BizException.java
说明:
每个子模块(gateway、api…)在真实项目里是一个 Maven module,不建议用package来隔离,因为只有maven module才能在编译阶段杜绝不合理的依赖,比如:integration依赖dao就是不合理的
如果团队和业务规模更大,可以把 biz 再拆成 biz-A、biz-B 两个子模块。
测试代码放在同级的 src/test/java,保持镜像结构,只有集成测试才放到start中或者独立一个qatest的模块专门放置所有的集成类。

4. 经验小结

  1. module即边界:严禁跨层调用(如gateway 直接依赖dao )。
  2. 统一命名:各层的类名都有统一的后缀,见类名就能知道它在哪一层、在当前层使用这个类是否合适。
  3. 代码生成:利用 MyBatis Generator / MapStruct 自动生成 DO、Mapper,减少重复劳动。
  4. 演进友好:不一定这个结构完全可以套用到你现在的工程中,取其精华去其糟粕。
  5. 广泛应用:尽量让公司所有java业务系统都采用相同的module结构和命名,那么人员变动、组织调整等的成本会大幅降低。

坚持半年,你会惊喜地发现:

  • 新人一周即可提 PR;
  • 重构只影响一个模块;
  • 线上故障定位从小时级降到分钟级。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 11:32:38

Spring AI RAG实战指南:从零开始构建智能知识库(必收藏代码示例)

本文介绍Spring AI框架中RAG工作机制,详解如何将各类文档通过DocumentReader读取、DocumentTransformer处理、Embedding模型转换为向量并存储到向量数据库。当用户提问时,系统先从向量数据库查询相关内容,再与问题一起发送给大模型处理&#…

作者头像 李华
网站建设 2026/4/7 16:30:22

明文泄露与暗网截屏:什么是可行动的,什么不是

明文泄露与暗网截屏:什么是可行动的,什么不是 暗网截图并非情报,它只是一个提示。 安全团队需要的是其他东西:他们能够据以采取行动的证据。 30秒概要 暗网截图能制造紧迫感,但很少能促成有效的补救措施。明文泄露…

作者头像 李华
网站建设 2026/4/18 0:03:41

计算机等级考试(三级Linux技术)--- 真题综合题集合

目录 一、知识点 一、文件操作核心命令 1. 目录操作:mkdir/rmdir/cd/pwd/ls 2. 文件复制 / 移动 / 删除:cp/mv/rm 3. 权限修改:chmod(最核心) 4. 其他高频文件操作 二、SSH 远程登录与免密配置 1. 基础 SSH 远程登录 2. SSH 免密登录(核心配置,一步到位) 步骤…

作者头像 李华
网站建设 2026/4/19 23:36:09

强化学习研究者的成长之路与技术探索

Alexander Long 原计划追随父亲的脚步,在石油和天然气行业工作。在他的祖国澳大利亚,该行业是电气工程师的主要雇主,因此在他于昆士兰大学获得学士学位后,这似乎是一条自然的道路。 2013年,当 Long 准备毕业时&#xf…

作者头像 李华
网站建设 2026/4/22 20:13:29

选择CDN提升WordPress博客速度

在当今的互联网环境中,网站加载速度不仅直接影响用户体验,还对 SEO 排名有着重要影响。对于使用 WordPress 创建博客的用户而言,利用内容分发网络(CDN)是提升网站性能的重要方式。值得一提的是,许多服务器提…

作者头像 李华
网站建设 2026/4/16 11:57:37

如何解决Vite打包后静态资源(图片/字体)报404找不到的问题

Vite开发环境下图片、字体、图标等静态资源加载正常,执行vite build打包部署到服务器后,大量静态资源返回404 Not Found,是前端工程化部署中最常见的问题。这类问题与资源本身无关、与代码逻辑无关,核心原因只有一个:V…

作者头像 李华