Java 项目结构与分层

源码目录约定与包分层:如何让依赖方向稳定、测试与部署边界清晰。

#type / concept #status / growing #tech / dev #resource / java

[!info] 关联笔记

Java 项目结构与分层

这个概念为什么出现

语言会了仍可能把代码堆成“大泥球”。项目结构回答:源码放哪、测试放哪、依赖朝哪指、模块如何拆。

[!abstract] 一句话理解 采用构建工具约定目录;用包/模块表达边界;分层让依赖单向(入口→应用→领域→基础设施),避免基础设施细节污染领域。

最小可运行示例

场景:订单服务的包草图

src/main/java/shop/order/
  api/OrderController.java      # 入口适配
  app/PlaceOrderService.java    # 用例
  domain/Order.java             # 领域
  infra/JdbcOrderRepository.java# 基础设施
src/test/java/shop/order/...

依赖方向:

api → app → domain
infra → domain(实现接口)
app → domain 接口(不直接依赖 JDBC 细节)

结合场景再看三个关注点

  1. 领域不依赖框架注解也可测(理想)。
  2. 接口定义在使用方/领域,实现放 infra。
  3. 测试镜像主包结构

核心概念与准确模型

1. 标准目录

Maven/Gradle 默认 main/test 分离。

2. 分层 vs 按功能

  • 按层:controller/service/repo 全局切
  • 按功能:order/ 下聚合层——扩展时常更清晰

3. 模块拆分

  • 多模块:order-domain/order-infra
  • 控制循环依赖

边界情况与反直觉行为

  1. 过度微服务拆分早于边界清晰。
  2. 共享 kernel 变成新泥球。
  3. 测试只测框架装配不测领域。

常见误区

[!warning] 常见误区:utils 包垃圾桶 无主名责任的 util 膨胀是架构腐烂信号。

工程实践

  1. ArchUnit 等守护依赖方向(可选)。
  2. 公共库慎抽。
  3. README 写清模块职责。
  4. 与团队统一一种主风格。

本节总结

  • 目录约定 + 依赖方向
  • 功能包 + 分层思想
  • 为 Web/数据访问落地

自测题

  1. 为什么领域层不要直接依赖 JDBC 驱动类型?
  2. main/test 分离的收益?
参考答案
  1. 便于替换持久化与单测,避免基础设施细节泄漏。
  2. 生产产物不带测试代码,测试可依赖测试范围库。

延伸阅读与资料来源

资料类型支撑内容
Maven Standard Directory Layout官方目录约定
Gradle Java projects官方源集
创建于 2026/7/15 更新于 2026/7/15