개요
도메인 주도 개발 책을 읽던 중 ‘이벤트 소싱’에 대한 내용을 접하고 이를 스프링 애플리케이션에서 어떻게 활용할 수 있을지 고민했습니다. 그 과정에서 스프링 이벤트를 알게 되었고, 이 두 가지 개념을 어떻게 활용할 수 있을지 정리해 보았다.
스프링 이벤트란?
스프링 이벤트는 애플리케이션 내에서 특정 이벤트가 발생하면, 이를 구독하고 있는 리스너가 해당 이벤트를 처리하는 구조를 제공한다. 주로 애플리케이션 내부 모듈 간 통신을 느슨하게 유지하면서, 작업을 비동기로 처리하는데 유용하다.
- 이벤트 발행을 위해서는 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 - 반가워요
'Backend > SpringBoot' 카테고리의 다른 글
| Spring Boot에서 일관된 API 응답을 위한 예외 처리 전략 (0) | 2025.03.27 |
|---|---|
| 의존성 주입( Dependency Injection, Di ..) (0) | 2024.08.26 |