개발 기록

> [Spring Event] Spring Event 비동기 처리 본문

Spring

> [Spring Event] Spring Event 비동기 처리

1z 2024. 1. 19. 01:11

 

 

 

 

 

1. 이벤트 동기/비동기 개요

 

스프링 이벤트는 기본적으로 동기 방식으로 동작한다. 

이벤트를 발행하는 스레드와 이벤트를 소비하는 스레드 아이디를 확인하면, 스레드 아이디가 일치하는 것을 확인 할 수 있다.

 

 

동기 방식으로 동작하는 것이 중요한 이유는 트랜잭션이 하나의 범위로 묶일 수 있기 때문이다. 

만약 이벤트를 발행하는 곳에서 트랜잭션이 시작된 상태라면 이벤트를 구독하는 곳에서도 동일한 트랜잭션을 공유하게 된

이벤트를 비동기 방식으로 동작시키는 것은 이벤트 발행를 발행하기 전/후가 더 이상 하나의 트랜잭션으로 묶일 수 없다는 것을 의미하기도 한다. 따라서 정밀하게 트랜잭션을 사용하는 경우라면 이러한 부분을 반드시 염두해두어야 한다.

 

 


2. 이벤트 비동기 처리 방법

 

이벤트를 비동기로 처리하기 위해서는 다음의 2가지 방법이 있다.

☞   @Async

 @ApplicationEventMuticaster

 

※ 기본 공통 설정 :  Application 클래스에 @EnableAsyne 어노테이션으로 비동기 설정을 활성화 한다.

 

 

(1) @Async 로 비동기 구현

 

1.  비동기로 동작해야하는 EventListener 에 @Async 어노테이션을 선언한다.

 

 

2. 결과 

실행 후 스레드를 확인하면  EventPublisher 와 기본 EventListener 는 스레드 아이디가 같고 @Async 어노테이션을 선언한 리스너는 스레드 아이디가 다른 것을 확인할 수 있다.

 

이벤트, 게시자 및 리스너 구현은 이전과 동일하게 유지되지만 이제 NoticeEventListener 는 별도의 스레드에서 이벤트를 비동기적으로 처리한다. 

 

 

 

(2) ApplicationEventMuticaster 로 비동기 구현

 

일부 메세지만 비동기 처리할 경우에는 위와 같이 처리하면 된다. 하지만 모든 메세지들을 기본적으로 비동기 처리할 것이라면 위와 같은 방식은 번거롭다. 이럴때는 ApplicationEventMulticaster 인터페이스를 이용하면 된다.

 

ApplicationEventMulticaster  :

     다수의 ApplicationListener개체를 관리하고 해당 개체에 이벤트를 게시할 수 있는 개체에 의해 구현되는 인터페이스

 

아래와 같이 ApplicationEventMulticaster 를 Bean 으로 등록한다. 참고로 여기서 bean의 이름을 명시적으로 지정해 주는 것이 좋다. 

스프링은 applicationEventMulticaster라는 이름의 빈을 찾고, 없으면 기본적으로 만들어 SimpleApplicationEventMulticaster를 생성해 빈으로 등록한다. 그래서 비동기로 동작하는 ApplicationEventMulticaster 객체를 만들면 되는데, 해당 부분은 다음과 같이 작성하면 된다. 

@Configuration
public class AsynchronousSpringEventsConfig {
    @Bean(name = APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
    public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
        SimpleApplicationEventMulticaster eventMulticaster =
          new SimpleApplicationEventMulticaster();
        
        eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
        return eventMulticaster;
    }
}

 

 

 

(3) 비동기 순서 정하기

이벤트를 사용하면서 EventListner 의 실행 순서를 조정해야 할 경우 @Order 어노테이션으로 조정하면 된다.

@EventListener
@Order(1)
public void on(CustomEvent event) {
    log.info(String.format("Event Data : %s", event.getEntityId()));
}

 

 

 

 

참고

https://mangkyu.tistory.com/292