개발/Spring
@EventListener 완벽 가이드
hanks
2025. 6. 3. 00:24
@EventListener 완벽 가이드
Spring의 @EventListener
는 애플리케이션 내에서 이벤트 기반 프로그래밍(event-driven architecture) 을 구현할 수 있도록 도와주는 기능입니다. 이는 코드 간의 결합도를 낮추고, 확장성과 유지보수성을 높이는 데 유용합니다.
🔧 기본 개념
- Spring에서는 이벤트를 객체로 정의하고, 이 이벤트가 발생했을 때 특정 메서드를 호출할 수 있도록 지원합니다.
@EventListener
는 특정 이벤트 클래스가 발행되면, 해당 이벤트를 처리하는 메서드에 붙여 동작을 트리거합니다.
🧱 동작 구조
이벤트 클래스 정의 (POJO)
public class UserCreatedEvent { private final User user; public UserCreatedEvent(User user) { this.user = user; } public User getUser() { return user; } }
이벤트 발행 (Event Publishing)
@Service public class UserService { private final ApplicationEventPublisher publisher; public UserService(ApplicationEventPublisher publisher) { this.publisher = publisher; } public void registerUser(User user) { // 사용자 등록 로직 publisher.publishEvent(new UserCreatedEvent(user)); } }
이벤트 리스너 작성 (Event Listener)
@Component public class UserEventListener { @EventListener public void onUserCreated(UserCreatedEvent event) { User user = event.getUser(); // 예: 환영 이메일 발송 System.out.println("Welcome email sent to: " + user.getEmail()); } }
🧵 비동기 처리: @Async
와 함께 사용
@Async
@EventListener
public void handleEventAsync(UserCreatedEvent event) {
// 비동기로 실행
}
@EnableAsync
설정이 필요
🔍 사용 시기
상황 | 이유 |
---|---|
사용자 가입 후 후처리 (이메일 발송 등) | 주 로직과 후처리를 분리하여 관심사 분리 |
주문 완료 후 재고 차감 | 이벤트 중심의 업무 흐름 설계 |
도메인 이벤트 적용 (DDD) | Aggregate Root가 Event를 발행하는 방식 구현 |
✅ 장점
- 발행자와 수신자의 결합도 감소
- 이벤트 수신자 자유롭게 추가/변경 가능
- 복잡한 트랜잭션 흐름 없이 유연한 설계 가능
- 비동기 확장 용이 (
@Async
활용)
⚠️ 주의사항
- 이벤트 리스너에서 예외 발생 시 전체 흐름에 영향 줄 수 있으므로 try-catch 사용 권장
- 도메인 이벤트와 어플리케이션 이벤트는 목적이 다르므로 구분 필요
- 트랜잭션 전파 여부 고려 필요 (
@TransactionalEventListener
사용 가능)
💡 실전 팁
- 이벤트는 불변 객체(immutable) 로 정의할 것
- 여러 이벤트 리스너를 동시에 등록해도 문제 없음 (복수 처리 가능)
- Spring의 기본 이벤트도 존재함:
ContextRefreshedEvent
,ApplicationReadyEvent
등
🔚 결론
@EventListener
는 단순한 비즈니스 이벤트부터 복잡한 도메인 이벤트까지 다양하게 활용할 수 있으며, 관심사 분리와 유지보수성을 향상시키는 데 강력한 도구입니다.