EventListener

Publisher

  • 이벤트를 Listen하고 있는 모든 객체에게 게시합니다.
  • 게시하는 객체에서는 ApplicationEventPublisher을 따로 주입받고 ApplicationEventPublisher의 publishEvent() API를 사용합니다.

Listener

  • Listener은 빈이어야 합니다.
  • 빈의 public 메소드에 @EventListener 어노테이션을 붙여서 사용합니다.
  • 파라메터 타입에 맞는 이벤트가 발행한다면 해당 메소드가 실행됩니다.

 

기본적으로 EventListener은 동기화 되어 있습니다. 예시로 트랜잭션 내에서 Event를 발행하면, Event를 수신하기를 기다리며 수신 측에서 예외가 터진다면 Transaction이 롤백됩니다.

커밋이 된 이후에 이벤트를 처리하도록 하려면 TransactionalEventListener을 사용하면 됩니다.

 

 

그럼 언제 이벤트를 사용할까요?

다음과 같은 경우를 생각해 봅시다.

단방향 의존성

 

게임 플랫폼이 게임에 의존하고 있는 형태입니다. 스팀 비슷하게 생각하면 될 거 같습니다. 사용자는 게임 플랫폼을 통해 게임을 접속하게 됩니다. 그렇다면 한가지 케이스에 대해 이야기해보겠습니다. 게임을 점검해야 하는 기능이 도입된다면 어떨까요? 게임 측에서 본인이 점검중이라고 게임 플랫폼에게 알려주어야 할 것입니다.

private GameRepository gameRepository;
private GamePlatformService gamePlatformService;

void maintenance(Long gameId) {
    final Game game = gameRepository.findById(gameId);
    gamePlatformService.unableGame(gameId);
    
    ...
}

양방향 의존성

 

위와 같이 작성하는 순간 의존성이 양방향으로 바뀌게 됩니다. 게임에서도 결국 게임 플랫폼을 알고 있어야 하기 때문입니다. 그렇다면 결국 양방향이 됩니다. 양방향은 썩 좋지 않은 구조입니다. A가 변경되면 B도 변경되고, 반대로 B가 변경되도 A를 변경시켜 주어야 하기 때문입니다. 또한 양방향이 좋지 않은 구조인 이유는 자칫 잘못하면 메소드를 순환 호출할 위험이 생기고 양쪽 상태를 맞추어 주어야 하는 작업이 필요합니다.

 

그렇다면, 이러한 양방향을 어떻게 해결해 줄 수 있을까요? 여러 방법이 있겠지만 위에서 설명한 이벤트를 사용한다면 해결 가능합니다. 게임이 점검 상태라고 이벤트를 publish 하면 게임 플랫폼에서 이를 받아서 상태를 바꾸도록 바꿔서 구현하면 될 것 같습니다.

 

Game

private ApplicationContext applicationContext;

void maintenance(Long gameId) {
    final Game game = gameRepository.findById(gameId);
    applicationContext.publishEvent(new GameMaintenanceEvent(this, game.getId()));
}

GamePlatform

@EventListener
public void unableGame(final GameMaintenanceEvent event) {
    Long gameId = event.getGameId();
    
    ...
}

이로써 Game이 GamePlatform을 더이상 의존하지 않아도 되어 단방향으로 되었습니다.

 

이벤트의 단점은?

  1. 동기화되는 이벤트의 경우는 오류처리가 가능할 수 있지만, 비동기 이벤트의 경우 오류 처리가 어렵습니다.
  2. 명확한 실행 순서가 존재하지 않습니다.

 

참고 문헌

https://www.baeldung.com/spring-events

https://blog.pragmatists.com/spring-events-and-transactions-be-cautious-bdb64cb49a95

https://www.techtarget.com/searchapparchitecture/tip/Event-driven-architecture-pros-and-cons-Is-EDA-worth-it

+ Recent posts