领域驱动设计(DDD)Spring Boot 3 实现 二
使用 Spring Boot 3 实现领域驱动设计(DDD)是一种很自然的选择,因为 Spring 提供了良好的生态支持,特别是在分层架构、依赖管理、事件驱动等方面。以下是如何在 Spring Boot 3 中结合 DDD 进行开发的详细指南:
项目结构设计
基于 DDD 的项目通常按领域划分,而非传统的技术分层(如按 Controller、Service、Repository)。以下是推荐的项目结构:
src/main/java/com/example/project
├── application # 应用层:负责用例逻辑
│ ├── service # 应用服务,协调领域层与基础设施层
│ └── dto # 数据传输对象(DTO)
├── domain # 领域层:核心业务逻辑
│ ├── model # 领域模型(实体、值对象、聚合等)
│ ├── repository # 仓储接口
│ ├── service # 领域服务
│ └── event # 领域事件
├── infrastructure # 基础设施层:实现技术细节
│ ├── repository # 仓储实现
│ ├── event # 事件发布/订阅
│ └── config # 配置类
└── interfaces # 接口层:与外界交互
├── controller # REST 接口
├── vo # 前端视图对象(VO)
└── facade # 门面层,用于组合多个应用服务
分层详细说明
1. 领域层(Domain Layer)
领域层是整个应用的核心,包含领域模型及其逻辑。
- 实体(Entity):
使用 Java 类建模具有唯一标识的业务对象。
public class Order {
private Long id;
private String customer;
private List<OrderItem> items;
// 业务逻辑
public void addItem(OrderItem item) {
this.items.add(item);
}
// Getters and Setters
}
- 值对象(Value Object):
不可变,表示某种属性。
public record Money(BigDecimal amount, String currency) {}
-
聚合根(Aggregate Root):
控制聚合的一致性,其他对象通过聚合根访问。 -
领域事件(Domain Event):
用于描述领域内的重要变化,推荐使用 Spring 的事件机制。
public class OrderPlacedEvent {
private final Long orderId;
public OrderPlacedEvent(Long orderId) {
this.orderId = orderId;
}
}
2. 应用层(Application Layer)
负责用例逻辑,协调领域层和基础设施层。
@Service
public class OrderApplicationService {
private final OrderRepository orderRepository;
private final ApplicationEventPublisher eventPublisher;
public OrderApplicationService(OrderRepository orderRepository, ApplicationEventPublisher eventPublisher) {
this.orderRepository = orderRepository;
this.eventPublisher = eventPublisher;
}
public void placeOrder(Order order) {
orderRepository.save(order);
eventPublisher.publishEvent(new OrderPlacedEvent(order.getId()));
}
}
3. 基础设施层(Infrastructure Layer)
实现技术细节,例如持久化和事件管理。
- 仓储实现: 使用 Spring Data JPA。
@Repository
public class JpaOrderRepository implements OrderRepository {
private final SpringDataOrderRepository repository;
public JpaOrderRepository(SpringDataOrderRepository repository) {
this.repository = repository;
}
@Override
public void save(Order order) {
repository.save(order);
}
@Override
public Optional<Order> findById(Long id) {
return repository.findById(id);
}
}
- 事件发布: 使用 Spring 的事件发布机制。
@Component
public class DomainEventPublisher {
private final ApplicationEventPublisher eventPublisher;
public DomainEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void publish(Object event) {
eventPublisher.publishEvent(event);
}
}
4. 接口层(Interfaces Layer)
负责处理外部请求(如 HTTP 请求)。
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderApplicationService orderApplicationService;
public OrderController(OrderApplicationService orderApplicationService) {
this.orderApplicationService = orderApplicationService;
}
@PostMapping
public ResponseEntity<Void> placeOrder(@RequestBody OrderRequest orderRequest) {
Order order = new Order(orderRequest.getCustomer(), orderRequest.getItems());
orderApplicationService.placeOrder(order);
return ResponseEntity.ok().build();
}
}
特性支持
-
Spring Boot 3 特性:
- 原生支持 JDK 17+: 可利用增强的性能和特性。
- Spring AOT: 提高运行时性能,支持 GraalVM 原生镜像。
-
事件驱动:
使用@EventListener
处理领域事件。
@Component
public class OrderEventListener {
@EventListener
public void handleOrderPlacedEvent(OrderPlacedEvent event) {
System.out.println("Order placed: " + event.getOrderId());
}
}
- 事务管理:
使用 Spring 的事务支持保证数据一致性。
示例依赖配置(Maven)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
总结
结合 DDD 的 Spring Boot 3 项目具有清晰的分层、强大的解耦能力和良好的扩展性。在实践中,建议:
- 根据业务复杂度调整领域模型的粒度。
- 利用 Spring 的生态(如事件驱动、事务支持)简化实现。
- 强化限界上下文的设计,避免跨上下文的直接调用。