본문 바로가기
Backend/SpringBoot

Spring Event (이벤트 발행과 구독 ..)

by burning-man 2024. 8. 27.

 

 

개요

도메인 주도 개발 책을 읽던 중 ‘이벤트 소싱’에 대한 내용을 접하고 이를 스프링 애플리케이션에서 어떻게 활용할 수 있을지 고민했습니다. 그 과정에서 스프링 이벤트를 알게 되었고, 이 두 가지 개념을 어떻게 활용할 수 있을지 정리해 보았다.

 

 

스프링 이벤트란?

스프링 이벤트는 애플리케이션 내에서 특정 이벤트가 발생하면, 이를 구독하고 있는 리스너가 해당 이벤트를 처리하는 구조를 제공한다. 주로 애플리케이션 내부 모듈 간 통신을 느슨하게 유지하면서, 작업을 비동기로 처리하는데 유용하다.

  • 이벤트 발행을 위해서는 ApplicationEventPublisher를 주입받아 사용해야한다.
  • 이벤트 구독을 위해서는 @EventListner를 사용해야한다.

 

스프링 이벤트 구성 요소

  • 이벤트 클래스 (Event Class) : 이벤트 클래스는 특정 이벤트를 정의하는 역할을 한다.
    public record MessageEvent( 
    	String message 
        ) { 
        
        }
  • 이벤트 발행자 (Event Publisher) : 이벤트 발행자는 특정 조건에서 이벤트를 발행하는 역할을 한다.
@Slf4j
@Component
public class MessagePublisher {

    private final ApplicationEventPublisher publisher;

    public MessagePublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    @EventListener
    public void publish(ApplicationReadyEvent event) {
        log.info("{} - 메시지 발행", Thread.currentThread().getName());
        publisher.publishEvent(new MessageEvent("Ok"));
    }
}

ApplicationEventPublisher를 주입받아 pulbishEvent로 이벤트를 발행하였다.

 

  • 이벤트 구독자 (Event Listener)
// MessageHandlerA
@Slf4j
@Component
public class MessageHandlerA {

    @EventListener
    public void scribe(MessageEvent messageEvent) {
        log.info("{} - 안녕하세요", Thread.currentThread().getName());
    }

}

// MessageHandlerB
@Slf4j
@Component
public class MessageHandlerB {

    @EventListener
    public void scribe(MessageEvent messageEvent) {
        log.info("{} - 고마워요", Thread.currentThread().getName());
    }

}

// MessageHandlerC
@Slf4j
@Component
public class MessageHandlerC {

    @Async
    @EventListener
    public void scribe(MessageEvent messageEvent) {
        log.info("{} - 반가워요", Thread.currentThread().getName());
    }
}

스프링 이벤트는 기본적으로 동기 방식으로 동작한지만 @EnableAsync 어노테이션을 통해 비동기 사용을 선언하고, 비동기로 동작하고자 하는 메서드에 @Async 어노테이션을 설정하면 된다.

 

실행 결과

2024-08-27T09:20:39.145+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.StudyEventsApplication   : Starting StudyEventsApplication using Java 21.0.4 with PID 34032 
2024-08-27T09:20:39.147+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.StudyEventsApplication   : No active profile set, falling back to 1 default profile: "default"
2024-08-27T09:20:39.881+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.StudyEventsApplication   : Started StudyEventsApplication in 1.223 seconds (process running for 1.855)
2024-08-27T09:20:39.885+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.events.MessagePublisher  : main - 메시지 발행
2024-08-27T09:20:39.887+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.events.MessageHandlerA   : main - 안녕하세요
2024-08-27T09:20:39.887+09:00  INFO 34032 --- [studyEvents] [           main] c.e.studyevents.events.MessageHandlerB   : main - 고마워요
2024-08-27T09:20:39.893+09:00  INFO 34032 --- [studyEvents] [         task-1] c.e.studyevents.events.MessageHandlerC   : task-1 - 반가워요