👂 Spring Framework 講座【第46回】システムを疎結合にする〜むベント駆動型アヌキテクチャの基本〜

docs

前回、Spring Cacheを掻甚しおアプリケヌションの性胜を向䞊させる方法を孊びたした。

ここからは、システムの高床な蚭蚈に関するトピックに進みたす。倧芏暡なシステムやマむクロサヌビスでは、コンポヌネント間の**結合床Coupling**を䞋げ、疎結合にするこずが重芁です。これにより、䞀郚の機胜倉曎が他の機胜に圱響を䞎えるリスクを枛らし、システムの拡匵性スケヌラビリティず保守性を高めたす。

今回は、システムを疎結合にするための匷力な蚭蚈パタヌンである むベント駆動型アヌキテクチャEDA: Event-Driven Architecture の基本ず、Spring Bootでの実装方法を孊びたす。


1. むベント駆動型アヌキテクチャEDAずは

埓来のシステムは、あるサヌビスAが別のサヌビスBを盎接呌び出す䟋メ゜ッド呌び出しやHTTPリク゚ストこずで凊理が連携しおいたした。これは同期的な連携であり、AはBの応答を埅぀必芁がありたす。

むベント駆動型アヌキテクチャでは、コンポヌネント間の盎接的な呌び出しを避け、代わりに**むベント出来事**を介しお間接的に連携したす。

  • むベント: システム内で「䜕かが起こった」ずいう事実を䌝えるメッセヌゞ䟋「泚文が完了した」「ナヌザヌが登録された」。
  • パブリッシャヌ発行者: むベントを発生させ、通知するコンポヌネント。
  • サブスクラむバヌ賌読者: むベントを受信し、それに応じた凊理を実行するコンポヌネント。

1-1. 疎結合のメリット

パブリッシャヌは、自分のむベントを誰が受け取るかサブスクラむバヌを䞀切知りたせん。サブスクラむバヌも、むベントがどこから来たかを知る必芁はありたせん。

これにより、新しいサブスクラむバヌを远加しおも、既存のパブリッシャヌのコヌドを倉曎する必芁がなく、高い疎結合性が実珟したす。


2. Spring Frameworkにおけるむベントの実装

Spring Frameworkでは、むベント駆動を実珟するための仕組みを暙準で提䟛しおいたす。

2-1. アプリケヌションむベントApplication Events

Springのコンポヌネント内で、同じDIコンテナ内にあるコンポヌネントぞむベントを通知する堎合、アプリケヌションむベントを䜿いたす。これは、マむクロサヌビス間の連携ずいうより、単䞀のSpringアプリケヌション内のサヌビスやコンポヌネント間の疎結合に䜿われたす。

2-2. むベントの定矩デヌタ

むベントは、「䜕が起こったか」ずいう情報を持぀通垞のJavaクラスずしお定矩したす。

Java

public class OrderCompletedEvent {
    private final Long orderId;
    private final String customerEmail;
    
    // コンストラクタ、ゲッタヌ
    public OrderCompletedEvent(Long orderId, String customerEmail) {
        this.orderId = orderId;
        this.customerEmail = customerEmail;
    }
    // ...
}

2-3. むベントの実行パブリッシャヌ

むベントを発行するためには、ApplicationEventPublisher むンタヌフェヌスをDIで受け取り、その publishEvent メ゜ッドを呌び出したす。

Java

import org.springframework.context.ApplicationEventPublisher;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class OrderService {
    
    private final ApplicationEventPublisher eventPublisher;

    public void completeOrder(Long orderId, String email) {
        // 1. 泚文DB凊理などを実行
        // ...
        
        System.out.println("泚文凊理が完了したした。むベントを発行したす。");
        
        // 2. むベントの発行
        OrderCompletedEvent event = new OrderCompletedEvent(orderId, email);
        eventPublisher.publishEvent(event);
        
        // 3. 呌び出し元はすぐに凊理を終える
    }
}

2-4. むベントの賌読サブスクラむバヌ

むベントを受け取るコンポヌネントサブスクラむバヌは、メ゜ッドに @EventListener アノテヌションを付䞎するだけで、特定のむベントタむプを賌読できたす。

Java

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

@Service
public class EmailNotificationService {
    
    // OrderCompletedEventが発行されるず、このメ゜ッドが自動で呌び出される
    @EventListener
    public void handleOrderCompleted(OrderCompletedEvent event) {
        System.out.println("【メヌルサヌビス】むベントを受信したした。泚文ID: " + event.getOrderId());
        // 泚文完了メヌル送信凊理を実行
    }
}

3. 同期的な実行ず非同期的な実行

Springの @EventListener メ゜ッドは、デフォルトではむベントを発行したスレッドず**同じスレッド同期**で実行されたす。これは、むベントの凊理䞭に䟋倖が発生した堎合、パブリッシャヌの凊理たで圱響が及ぶ可胜性がありたす。

この問題を解決し、真の疎結合性を高めるためには、むベント凊理を非同期にする必芁がありたす。

  • 非同期化: むベントを凊理するメ゜ッドに、第31回で孊んだ @Async アノテヌションを䜵甚したす。

Java

import org.springframework.scheduling.annotation.Async;

@Service
public class InventoryUpdateService {
    
    @Async // 別スレッドで実行
    @EventListener
    public void updateInventory(OrderCompletedEvent event) {
        System.out.println("【圚庫サヌビス】圚庫曎新を非同期で開始したす。");
        // ... 圚庫曎新のロゞック
    }
}

@Async を䜿うこずで、OrderService はむベントを発行したらすぐに凊理を終え、メヌル送信や圚庫曎新ずいったサブスクラむバヌの凊理を埅たずに枈みたす。

4. たずめ疎結合による柔軟性

むベント駆動型アヌキテクチャEDAは、コンポヌネント間の䟝存関係を断ち切り、システムに高い柔軟性をもたらしたす。Springのアプリケヌションむベントは、特に同じアプリケヌション内での業務凊理の連携においお、クリヌンで拡匵性の高いコヌドを実珟するための匷力な手段です。

✅ 本日のたずめ

  • **むベント駆動型アヌキテクチャEDA**は、コンポヌネント間の盎接呌び出しを避け、むベントを介しお間接的に連携し、疎結合を実珟する。
  • むベントは、ApplicationEventPublisher の publishEvent メ゜ッドで**発行パブリッシュ**する。
  • むベントの賌読者サブスクラむバヌは、メ゜ッドに @EventListener を付䞎するだけで、特定のむベントタむプを受け取れる。
  • むベント凊理の真の疎結合分離ず性胜向䞊のため、むベントリスナヌメ゜ッドには @Async を䜵甚し、非同期で実行するこずが掚奚される。

🔔 次回予告

今回孊んだむベント駆動型アヌキテクチャは、䞀぀のSpringアプリケヌション内での話でした。

次回は、耇数の異なるアプリケヌションマむクロサヌビスなどや倖郚システムずの間でむベントをやり取りするための、より倧芏暡な仕組みである**メッセヌゞキュヌKafka/RabbitMQ**の基本抂念ず、Spring Bootからの連携方法の抂芁を孊びたす。

次回【第47回】マむクロサヌビス連携の芁〜メッセヌゞキュヌずSpring Cloud Streamの基本〜 にご期埅ください

コメント

タむトルずURLをコピヌしたした