Spring Modulith for Bounded Contexts
Implements DDD bounded contexts as application modules with enforced boundaries and event-driven communication.
Core Concepts
| Concept | Description | |---------|-------------| | Application Module | Package-based boundary = bounded context | | Module API | Types in base package (public) | | Internal | Types in sub-packages (encapsulated) | | Events | Cross-module communication mechanism |
Module Structure
src/main/java/
├── com.example/
│ └── Application.java ← @SpringBootApplication
├── com.example.order/ ← Module: order
│ ├── OrderService.java ← Public API
│ ├── OrderCreated.java ← Public event
│ ├── package-info.java ← @ApplicationModule config
│ └── internal/ ← Encapsulated
│ ├── OrderRepository.java
│ └── OrderEntity.java
├── com.example.inventory/ ← Module: inventory
│ ├── InventoryService.java
│ └── internal/
└── com.example.shipping/ ← Module: shipping
Types in com.example.order = public API Types in com.example.order.internal = hidden from other modules
Quick Patterns
See [EXAMPLES.md](EXAMPLES.md) for complete working examples including:
- Module Configuration with @ApplicationModule
- Event Publishing with domain event records
- Event Handling with @ApplicationModuleListener (Java + Kotlin)
- Module Verification Test with PlantUML generation
- Event Externalization for Kafka/AMQP
Spring Boot 4 / Modulith 2.0 Specifics
- @ApplicationModuleListener combines
@Async+@Transactional(REQUIRES_NEW)+@TransactionalEventListener(AFTER_COMMIT) - Event Externalization with
@Externalizedannotation for Kafka/AMQP - JDBC event log ensures at-least-once delivery
Detailed References
- Examples: See [EXAMPLES.md](EXAMPLES.md) for complete working code examples
- Troubleshooting: See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues and Boot 4 migration
- Workflow: See [WORKFLOW.md](WORKFLOW.md) for detailed step-by-step Modulith setup
- Module Structure: See [references/MODULE-STRUCTURE.md](references/MODULE-STRUCTURE.md) for package conventions, named interfaces, dependency rules
- Event Patterns: See [references/EVENTS.md](references/EVENTS.md) for publishing, handling, externalization, testing with Scenario API
Related Skills
| Need | Skill | |------|-------| | DDD concepts | domain-driven-design | | Data layer per module | spring-boot-data-ddd | | Module event testing | spring-boot-testing | | REST APIs for modules | spring-boot-web-api |
Anti-Pattern Checklist
| Anti-Pattern | Fix | |--------------|-----| | Direct bean injection across modules | Use events or expose API | | Synchronous cross-module calls | Use @ApplicationModuleListener | | Module dependencies not declared | Add allowedDependencies in @ApplicationModule | | Missing verification test | Add ApplicationModules.verify() test | | Internal types in public API | Move to .internal sub-package | | Events without data | Include all data handlers need |
Critical Reminders
- One module = one bounded context — Mirror DDD boundaries
- Events are the integration mechanism — Not direct method calls
- Verify in CI —
ApplicationModules.verify()catches boundary violations - Reference by ID — Never direct object references across modules
- Transaction per module —
@ApplicationModuleListenerensures isolation