Spring Modulithは、モノリシックアプリケーションをモジュール化するためのフレームワークです。マイクロサービスに分割することなく、単一のアプリケーション内で明確な境界を持つモジュールを作成し、保守性と拡張性を向上させます。Spring Modulithは、モジュール間の依存関係を明示的に定義し、アーキテクチャの整合性を確保するための機能を提供します。
Spring Modulithは、「モジュラーモノリス」アーキテクチャパターンを実装するためのSpringベースのソリューションです。このパターンは、マイクロサービスの複雑さを避けながら、モジュール性の利点を享受したいプロジェクトに最適です。Spring Modulithは、Spring Bootプロジェクトに簡単に統合でき、既存のSpringの機能(特にアプリケーションイベント)を活用して、モジュール間の疎結合な通信を実現します。
+------------------------------------------+ | Spring Boot Application | | | | +-------------+ +-------------+ | | | | | | | | | Module A | | Module B | | | | | | | | | +------+------+ +------+------+ | | | | | | | Event Bus | | | +---------------------+ | | | | | +---------+---------+ | | | | | | +------+------+ +------+------+ | | | | | | | | | Module C | | Module D | | | | | | | | | +-------------+ +-------------+ | | | | Spring Modulith Framework | +------------------------------------------+
図1: Spring Modulithアーキテクチャの概要 - モジュール間の通信はイベントバスを通じて行われる
Spring Modulithの主な目的は以下の通りです:
Spring Modulithでは、Javaパッケージ構造を使用してモジュールの境界を定義します。各モジュールは、特定のパッケージとそのサブパッケージで構成されます。例えば、com.example.application.orders
パッケージは「orders」モジュールを表し、com.example.application.inventory
パッケージは「inventory」モジュールを表します。
モジュールの境界は、@Modulith
アノテーションを使用して定義します。このアノテーションは、アプリケーションのルートパッケージに配置され、そのサブパッケージがモジュールとして扱われることを示します。例えば:
@org.springframework.modulith.Modulith
package com.example.application;
import org.springframework.modulith.Modulith;
また、特定のパッケージをモジュールとして明示的に定義するために、@org.springframework.modulith.Module
アノテーションを使用することもできます:
@org.springframework.modulith.Module
package com.example.application.orders;
import org.springframework.modulith.Module;
Spring Modulithは、モジュール間の依存関係を制御するための強力な機能を提供します。デフォルトでは、モジュールは他のモジュールの内部実装に依存することはできません。モジュール間の依存関係は、明示的に公開されたAPIを通じてのみ許可されます。
公開APIは、@org.springframework.modulith.ApplicationModule.API
アノテーションを使用して定義します:
package com.example.application.orders.api;
import org.springframework.modulith.ApplicationModule;
@ApplicationModule.API
public interface OrderService {
// 公開APIメソッド
}
また、特定のモジュールに対する依存関係を明示的に許可するために、@org.springframework.modulith.NamedInterface
アノテーションを使用することもできます:
@org.springframework.modulith.NamedInterface("api")
package com.example.application.orders.api;
import org.springframework.modulith.NamedInterface;
Spring Modulithは、Spring ApplicationEventを使用して、モジュール間の疎結合な通信を実現します。イベントは、モジュールの境界を越えて情報を伝達するための主要な手段です。これにより、モジュール間の直接的な依存関係を減らし、システムの柔軟性と拡張性を向上させることができます。
イベントの発行は、ApplicationEventPublisher
を使用して行います:
@Service
class OrderService {
private final ApplicationEventPublisher events;
OrderService(ApplicationEventPublisher events) {
this.events = events;
}
@Transactional
public Order createOrder(Order order) {
// 注文の処理
// ...
// イベントの発行
events.publishEvent(new OrderCreatedEvent(order));
return order;
}
}
イベントの購読は、@EventListener
アノテーションを使用して行います:
@Service
class InventoryService {
@EventListener
@Transactional
void on(OrderCreatedEvent event) {
// 在庫の更新
// ...
}
}
明確な境界を持つモジュールにより、コードの理解と保守が容易になります
モジュール間の依存関係を制御することで、アーキテクチャの整合性を確保します
必要に応じて個々のモジュールをマイクロサービスに分割できます
モノリスの単純さを維持しながら、モジュール化の利点を享受できます
パッケージ構造に基づいてアプリケーションのモジュールを定義します
モジュール間の許可された依存関係を強制するためのチェック機能
モジュール間の疎結合な通信のためのイベント駆動アーキテクチャ
モジュール構造とその依存関係を視覚化するドキュメント生成機能
@org.springframework.modulith.Modulith
package com.example.application;
import org.springframework.modulith.Modulith;
@Service
class OrderService {
private final ApplicationEventPublisher events;
OrderService(ApplicationEventPublisher events) {
this.events = events;
}
@Transactional
public Order createOrder(Order order) {
// 注文の処理
// ...
// イベントの発行
events.publishEvent(new OrderCreatedEvent(order));
return order;
}
}
@Service
class InventoryService {
@EventListener
@Transactional
void on(OrderCreatedEvent event) {
// 在庫の更新
// ...
}
}
Spring Modulithは、モジュール単位のテストを容易にするための強力な機能を提供します。@ModuleTest
アノテーションを使用することで、特定のモジュールとその依存モジュールのみをロードしてテストを実行できます。これにより、テストの実行時間が短縮され、テストの信頼性が向上します。
@SpringBootTest
@ModuleTest
class OrderModuleTests {
@Autowired OrderService orders;
@Test
void testCreateOrder() {
// テストコード
// ...
}
}
Spring Modulithは、モジュール間のイベント発行をテストするための機能も提供します。ApplicationModuleTest
クラスを使用することで、イベントの発行と購読をテストできます。
@SpringBootTest
@ModuleTest
class OrderModuleTests {
@Autowired ApplicationModuleTest moduleTest;
@Autowired OrderService orders;
@Test
void testOrderCreationPublishesEvent() {
// イベント発行のテスト
moduleTest.verify(orders)
.publishesEventOfType(OrderCreatedEvent.class)
.when(service -> service.createOrder(new Order()));
}
}
Spring Modulithは、モジュール間の依存関係を検証するためのテスト機能も提供します。これにより、アーキテクチャの整合性を確保できます。
@Test
void verifyModuleDependencies() {
// モジュール間の依存関係の検証
new Modulith(Application.class)
.verify()
.assertThatDependenciesAreValid();
}
特徴 | Spring Modulith | マイクロサービス |
---|---|---|
デプロイ | 単一のアプリケーションとしてデプロイ | 個別のサービスとして独立してデプロイ |
通信 | メモリ内のイベント発行と購読 | ネットワーク経由のAPI呼び出し |
トランザクション | 単一のトランザクション境界が可能 | 分散トランザクションが必要 |
スケーリング | アプリケーション全体をスケーリング | 個別のサービスを独立してスケーリング |
複雑さ | 比較的低い | 比較的高い |
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter</artifactId>
<version>1.1.0</version>
</dependency>
Spring Modulithは、Spring Bootアプリケーションにシームレスに統合できます。Spring Bootの自動設定機能を活用することで、最小限の設定でSpring Modulithの機能を利用できます。
Spring Modulithは、Spring Boot Starterを提供しており、必要な依存関係を自動的に追加します。
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-starter</artifactId>
<version>1.1.0</version>
</dependency>
また、特定の機能のみを使用する場合は、個別のスターターを追加することもできます。
<!-- イベント発行のみを使用する場合 -->
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-events</artifactId>
<version>1.1.0</version>
</dependency>
<!-- ドキュメント生成のみを使用する場合 -->
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-docs</artifactId>
<version>1.1.0</version>
</dependency>
Spring Modulithは、Spring Bootの設定ファイル(application.properties または application.yml)を使用して設定できます。
# application.properties
spring.modulith.events.enabled=true
spring.modulith.events.async.enabled=true
spring.modulith.events.persistence.enabled=true
# application.yml
spring:
modulith:
events:
enabled: true
async:
enabled: true
persistence:
enabled: true
Spring Modulithは、モノリシックアプリケーションをモジュール化するための強力なフレームワークです。マイクロサービスに分割することなく、単一のアプリケーション内で明確な境界を持つモジュールを作成し、保守性と拡張性を向上させることができます。モジュール間の依存関係を明示的に定義し、イベント駆動アーキテクチャを使用することで、アーキテクチャの整合性を確保しながら、疎結合なモジュール間の通信を実現できます。
Spring Modulithの主な利点は以下の通りです:
Spring Modulithは、マイクロサービスアーキテクチャの複雑さを避けながら、モジュール化の利点を享受したいプロジェクトに最適なソリューションです。特に、将来的にマイクロサービスへの移行を検討しているが、現時点ではモノリシックアプリケーションの単純さを維持したいプロジェクトに適しています。