spring / / 2022. 12. 23. 07:11

ApplicationEventPublisher

ApplicationEventPublisher

Spring Boot로 이벤트를 발행하는 방법이다.

Event 생성

text를 가진 Message 객체 생성

@AllArgsConstructor
@Getter
public class Message {

    private String text;
}

Message를 가진 MessageEvent 객체 생성

@AllArgsConstructor
@Getter
public class MessageEvent {

    private Message message;
}

Event Publisher 생성

Event를 Publish하는 것을 ApplicationRunner로 실행해보자.
ApplicationRunner로 구현하면 Spring이 기동될 때 자동으로 실행된다.

@Component
@RequiredArgsConstructor
@Slf4j
public class MessagePublisher implements ApplicationRunner {

    private final ApplicationEventPublisher publisher;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        publisher.publishEvent(new MessageEvent(new Message("이벤트 전송합니다~")));
        log.info("event published.");
    }
}

Event Listener 생성

Event를 구독하기 위해서 @EventListener 어노테이션을 통해 받을 수 있다.

@Component
@Slf4j
public class MessageListener {

    @EventListener
    public void handle(MessageEvent event) {
        log.info("event received: " + event.getMessage().getText());
    }
}

실행

Spring Boot Application을 실행하여 보자.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

실행하면 아래와 같이 표시된다.

2022-06-26 20:33:50.942  INFO 10009 --- [           main] r._._._spring_message.Application        : Started Application in 0.88 seconds (JVM running for 1.354)
2022-06-26 20:33:50.951  INFO 10009 --- [           main] r._._._spring_message.MessageListener    : event received: 이벤트 전송합니다~
2022-06-26 20:33:50.952  INFO 10009 --- [           main] r._._._spring_message.MessagePublisher   : event published.

비동기 실행

기본적으로 Event는 동기적으로 실행이 되므로 만일 EventListener가 오래걸리는 경우 지연되는 문제가 발생하므로 비동기로 실행하는 방법을 알아보자.

EventListener

EventListener가 3초의 delay가 발생한다고 생각하고 Thread.sleep(3000) 코드를 넣음

@Component
@Slf4j
public class MessageListener {

    @EventListener
    public void handle(MessageEvent event) throws InterruptedException {
        Thread.sleep(3000);
        System.out.println("event received: " + event.getMessage().getText());
    }
}

실행하면 EventListener의 실행이 완료(3초 후)된 후에 EventPublisher의 로그가 찍히는 것을 볼 수 있다.

2022-06-26 20:35:30.836  INFO 10241 --- [           main] r._._._spring_message.Application        : Started Application in 1.11 seconds (JVM running for 1.582)
2022-06-26 20:35:33.846  INFO 10241 --- [           main] r._._._spring_message.MessageListener    : event received: 이벤트 전송합니다~
2022-06-26 20:35:33.847  INFO 10241 --- [           main] r._._._spring_message.MessagePublisher   : event published.

EventListener를 비동기로 실행하는 방법은 @Async 어노테이션을 통해 실행할 수 있다.

  1. SpringBootApplication에 @EnableAsync 추가
  2. EventListener에 @Async 추가

SpringBootApplication

@EnableAsync
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

MessageEvent에 @Async 추가

@Slf4j
@Component
public class MessageListener {

    @Async
    @EventListener
    public void handle(MessageEvent event) throws InterruptedException {
        Thread.sleep(3000);
        log.info("event received: " + event.getMessage().getText());
    }
}

이를 실행하면 아래와 같이 EventPublisher가 동기로 실행된다.

2022-06-26 20:37:10.713  INFO 10508 --- [           main] r._._._spring_message.Application        : Started Application in 1.001 seconds (JVM running for 1.478)
2022-06-26 20:37:10.719  INFO 10508 --- [           main] r._._._spring_message.MessagePublisher   : event published.
2022-06-26 20:37:13.736  INFO 10508 --- [         task-1] r._._._spring_message.MessageListener    : event received: 이벤트 전송합니다~
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유