网站的ftp信息燕郊今日头条
创建Order项目实现Clean & Hexagonal架构
前言
在上一节中,讲到了Clean & Hexagonal架构的理论部分,并且通过图形解释了从MVC架构到清洁架构到演变。下面我们通过创建项目的方式来进一步理解Clean & Hexagonal架构。
1.项目创建
1. 项目整体结构规划
项目采用 Maven 多模块架构,父模块聚合子模块,依赖层级清晰。
结构说明:
order-system/ # 父项目(聚合所有子模块)
├── .git # Git 仓库目录
├── .gitignore # Git 忽略规则(如 target/、.DS_Store 等)
├── .idea/ # IntelliJ IDEA 配置目录(自动生成)
├── order-service/ # 订单服务模块(子模块)
│ ├── order-application/ # 应用层(接口、DTO、服务入口)
│ ├── order-container/ # 容器配置(Spring Boot 启动类)
│ ├── order-dataccess/ # 数据访问层(DAO、JPA/MyBatis 实现)
│ ├── order-domain/ # 领域层(领域模型、领域服务)
│ ├── order-message/ # 消息处理(MQ 消费者/生产者)
│ └── pom.xml # 子模块的 pom 文件
└── pom.xml # 父模块的 pom 文件
1.1 父项目order-system
父项目聚合了所有的子模块,进行统一的依赖管理,对应的pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath /></parent><groupId>com.jackmouse</groupId><artifactId>order-system</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>order-service</module></modules><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version></properties><dependencyManagement><dependencies><dependency><groupId>com.jackmouse</groupId><artifactId>order-domian-core</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-application-service</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-application</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-dataaccess</artifactId><version>${project.version}</version></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-message</artifactId><version>${project.version}</version></dependency></dependencies></dependencyManagement><dependencies></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven-compiler-plugin.version}</version><configuration><release>17</release></configuration></plugin></plugins></build></project>
1.1 order-container
(容器/启动模块)
-
作用:
- 包含 Spring Boot 的主启动类(
Application.java
),是项目的入口。 - 负责整合所有子模块的依赖(如
order-application
、order-dataccess
等)。 - 配置全局属性(如数据源、消息队列连接、Web 端口等)。
- 包含 Spring Boot 的主启动类(
-
示例代码:
@SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} }
-
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.jackmouse</groupId><artifactId>order-service</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>order-container</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.jackmouse</groupId><artifactId>order-domian-core</artifactId></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-application-service</artifactId></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-application</artifactId></dependency><dependency><groupId>com.jackmouse</groupId><artifactId>order-message</artifactId></dependency></dependencies> </project>
1.2 order-application
(应用层)
-
作用:
- 调用领域层(
order-domain
)。 - 处理输入输出(如接收 HTTP 请求,返回 DTO 对象)。
- 调用领域层(
-
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.jackmouse</groupId><artifactId>order-service</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>order-application</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.jackmouse</groupId><artifactId>order-application-service</artifactId></dependency></dependencies></project>
1.3 order-domain
(领域层)
-
作用:
- 核心业务逻辑和领域模型(如
Order
实体、OrderStatus
值对象)。 - 定义领域服务(如校验订单规则的
OrderValidator
)。 - 声明仓储接口(如
OrderRepository
),但不实现具体逻辑。
- 核心业务逻辑和领域模型(如
-
可以将domain层在细化为service层和core层,service层实现具体的业务逻辑和外部接口的定义,core层定义实体和值对象。
-
关键文件:
Order.java
(领域实体):
public class Order {private Long id;private String orderNumber;private BigDecimal totalAmount;public void cancel() {// 领域逻辑:校验订单是否可取消if (this.status == OrderStatus.SHIPPED) {throw new IllegalStateException("已发货订单不可取消");}this.status = OrderStatus.CANCELLED;} }
-
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.jackmouse</groupId><artifactId>order-service</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>order-domain</artifactId><packaging>pom</packaging><modules><module>order-domian-core</module><module>order-application-service</module></modules><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>
1.4 order-dataccess
(数据访问层)
-
作用:
- 实现领域层定义的仓储接口(如
OrderRepositoryImpl
)。 - 集成 ORM 框架(如 JPA、MyBatis),操作数据库。
- 处理数据持久化细节(如分页查询、事务管理)。
- 实现领域层定义的仓储接口(如
-
关键文件:
OrderRepositoryImpl.java
(仓储实现):
@Repository public class OrderRepositoryImpl implements OrderRepository {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic void save(Order order) {String sql = "INSERT INTO orders (...) VALUES (...)";jdbcTemplate.update(sql, ...);} }
-
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.jackmouse</groupId><artifactId>order-service</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>order-dataaccess</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.jackmouse</groupId><artifactId>order-application-service</artifactId></dependency></dependencies></project>
1.5 order-message
(消息处理模块)
-
作用:
- 处理异步消息(如订单创建后发送 Kafka 事件)。
- 定义消息生产者(如
OrderEventPublisher
)和消费者(如PaymentEventListener
)。 - 解耦系统间通信,支持事件驱动架构。
-
关键文件:
OrderEventPublisher.java
(消息生产者):
@Component public class OrderEventPublisher {@Autowiredprivate KafkaTemplate<String, OrderEvent> kafkaTemplate;public void publishOrderCreated(Order order) {OrderEvent event = new OrderEvent(order);kafkaTemplate.send("order-topic", event);} }
-
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.jackmouse</groupId><artifactId>order-service</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>order-message</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.jackmouse</groupId><artifactId>order-application-service</artifactId></dependency></dependencies></project>
2.生成依赖图
使用depgraph-maven-plugin插件可以生成项目的依赖关系。
首先要在系统安装graphviz(https://www.graphviz.org/):
mac使用brew安装过程中,可能会因为系统版本高导致报错
使用–build-from-source命令用从源代码安装,如
brew install --build-from-source graphviz
安装完成后在项目的根目录执行:
mvn com.github.ferstl:depgraph-maven-plugin:aggregate -DcreateImage=true -DreduceEdges=false -Dscope=compile "-Dincludes=com.jackmouse*:*"
com.jackmouse为你自己的包路径,执行成功后:
项目的target目录下会生成png文件:
可以看到domain层不依赖于其他任何外部部组件,所有外部服务(如数据库、消息队列、外部服务)都通过接口和适配器与业务逻辑交互。核心业务逻辑保持独立,易于测试和替换,使得系统具有更好的扩展性和灵活性。