创建Order项目实现Clean & Hexagonal架构

创建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 复制代码
<?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-applicationorder-dataccess 等)。
    • 配置全局属性(如数据源、消息队列连接、Web 端口等)。
  • 示例代码

    java 复制代码
    @SpringBootApplication
    public class Application {
      public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
      }
    }
  • pom文件:

    xml 复制代码
    <?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 复制代码
    <?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(领域实体):
    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 复制代码
    <?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(仓储实现):
    java 复制代码
    @Repository
    public class OrderRepositoryImpl implements OrderRepository {
      @Autowired
      private JdbcTemplate jdbcTemplate;
    
      @Override
      public void save(Order order) {
        String sql = "INSERT INTO orders (...) VALUES (...)";
        jdbcTemplate.update(sql, ...);
      }
    }
  • pom文件:

    xml 复制代码
    <?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(消息生产者):
    java 复制代码
    @Component
    public class OrderEventPublisher {
      @Autowired
      private KafkaTemplate<String, OrderEvent> kafkaTemplate;
    
      public void publishOrderCreated(Order order) {
        OrderEvent event = new OrderEvent(order);
        kafkaTemplate.send("order-topic", event);
      }
    }
  • pom文件:

    xml 复制代码
    <?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命令用从源代码安装,如

bash 复制代码
brew install --build-from-source graphviz

安装完成后在项目的根目录执行:

bash 复制代码
mvn com.github.ferstl:depgraph-maven-plugin:aggregate -DcreateImage=true -DreduceEdges=false -Dscope=compile "-Dincludes=com.jackmouse*:*"

com.jackmouse为你自己的包路径,执行成功后:

项目的target目录下会生成png文件:

可以看到domain层不依赖于其他任何外部部组件,所有外部服务(如数据库、消息队列、外部服务)都通过接口和适配器与业务逻辑交互。核心业务逻辑保持独立,易于测试和替换,使得系统具有更好的扩展性和灵活性。

相关推荐
电商api接口开发16 分钟前
ASP.NET MVC 入门指南三
后端·asp.net·mvc
声声codeGrandMaster17 分钟前
django之账号管理功能
数据库·后端·python·django
我的golang之路果然有问题43 分钟前
案例速成GO+redis 个人笔记
经验分享·redis·笔记·后端·学习·golang·go
嘻嘻嘻嘻嘻嘻ys1 小时前
《Vue 3.3响应式革新与TypeScript高效开发实战指南》
前端·后端
高桐@BILL1 小时前
1.4 大模型应用产品与技术架构
人工智能·架构·agent
暮乘白帝过重山1 小时前
路由逻辑由 Exchange 和 Binding(绑定) 决定” 的含义
开发语言·后端·中间件·路由流程
CHQIUU1 小时前
告别手动映射:在 Spring Boot 3 中优雅集成 MapStruct
spring boot·后端·状态模式
广西千灵通网络科技有限公司1 小时前
基于Django的个性化股票交易管理系统
后端·python·django
zizisuo1 小时前
6.1.多级缓存架构
缓存·架构
CodeFox1 小时前
动态线程池 v1.2.1 版本发布,告警规则重构,bytebuddy 替换 cglib,新增 jmh 基准测试等!
java·后端