AbstractAggregateRoot와 ApplicationEventPublisher 동작 과정
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
DevOps
대상자
스프링 프레임워크 기반 도메인 이벤트 처리를 구현하는 개발자, 중간 이상의 프레임워크 이해도를 가진 자
핵심 요약
AbstractAggregateRoot#registerEvent()
메서드를 통해 이벤트를 등록하고,save()
/delete()
호출 시 자동 발행EventPublishingRepositoryProxyPostProcessor
가@DomainEvents
메서드와ApplicationEventPublisher
를 연동하여 이벤트 전달ApplicationEventMulticaster
는@Async
와TaskExecutor
설정에 따라 동기/비동기 실행을 결정
섹션별 세부 요약
1. 도메인 이벤트 등록 및 발행 흐름
AbstractAggregateRoot
상속 엔티티에서registerEvent()
호출 시,domainEvents
리스트에 이벤트 저장save()
/delete()
호출 시EventPublishingMethodInterceptor
가 이벤트를 추출 후ApplicationEventPublisher.publishEvent()
호출deleteById()
는 이벤트 발행 X (이유: #issues/2084 참조)
2. ApplicationEventPublisher 내부 동작
ApplicationContext
가ApplicationEventPublisher
인터페이스 구현,publishEvent()
호출 시SimpleApplicationEventMulticaster
로 이벤트 전달- POJO 발행 시
PayloadApplicationEvent
로 래핑하여 호환성 유지 (Spring 4.2 이후 가능)
3. 이벤트 처리 및 비동기 설정
SimpleApplicationEventMulticaster
가TaskExecutor
존재 여부와supportsAsyncExecution()
결과에 따라 동기/비동기 실행 결정@Async
어노테이션 사용 시 메서드 본문만 별도 스레드 풀에서 실행 (전역 TaskExecutor 설정과 무관)@TransactionalEventListener
는 트랜잭션 커밋 후 실행 (TransactionSynchronizationManager 활용)
4. 예외 처리 및 안정성
ErrorHandler
설정 시 예외 로깅/무시 가능, 이후 리스너 실행 계속RejectedExecutionException
발생 시 동기로 우회 처리하여 이벤트 손실 방지
결론
@DomainEvents
메서드와ApplicationEventPublisher
연동을 위해EventPublishingRepositoryProxyPostProcessor
설정 필수TaskExecutor
를 통해 비동기 처리를 활성화하고,@Async
사용으로 리스너 메서드 병렬 실행 가능@TransactionalEventListener
는 트랜잭션 커밋 시점에 실행되므로phase
속성에 주의해야 함