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 어노테이션을 통해 실행할 수 있다.
- SpringBootApplication에 @EnableAsync 추가
- 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: 이벤트 전송합니다~
반응형