Spring에서 Event
Spring은 일반적으로 DI를 통해 메서드를 호출하여 데이터를 전달한다.
규모가 작을 때는 큰 문제가 없지만 도메인이 점점 복잡히질 경우 여러 도메인 사이에 강한 의존성 결합으로 시스템이 복잡해지는 문제가 발생할 수 있다.
Spring은 Event를 통해 Bean과 Bean 사이의 데이터를 전달할 수 있는데 ApplicationContext에 이벤트를 넘겨주면 Listener에서 받아서 처리한다.
이벤트를 발생시키는 publisher와 받아서 처리하는 Listener, 전달할 데이터를 가지고 있는 event클래스로 구성된다.
ApplicationEventPublisher
Spring의 ApplicationContext가 상속하는 인터페이스 중 하나로 옵저버 패턴의 구현체이다.
Publisher와 Listener를 Spring의 Bean으로 등록하고 publishEvent()가 실행되면 등록된 listener에 Event를 던진다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Getter @Builder public class TestEvent { private String eventId; private String type; private String data;
public static TestEvent toCompleteEvent(String data){ return TestEvent.builder() .eventId(UUID.randomUUID().toString()) .type("completed") .data(data) .build(); }
public static TestEvent toErrorEvent(){ return TestEvent.builder() .eventId(UUID.randomUUID().toString()) .type("error") .data("data is Null") .build(); } }
|
Spring 4.2 부터는 ApplicationEvent를 상속받지 않아도 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Slf4j @Service @RequiredArgsConstructor public class EventTestService { private final ApplicationEventPublisher applicationEventPublisher;
public Mono<String> publishTest(String message) { return Mono.fromCallable(() -> { if(message != null){ applicationEventPublisher.publishEvent(TestEvent.toCompleteEvent(message)); } else { applicationEventPublisher.publishEvent(TestEvent.toErrorEvent()); }
return "result: " + message; }); } }
|
ApplicationContext를 주입받아도 되지만 명시적으로 ApplicationEventPublisher를 주입받아서 사용한다.
1 2 3 4 5 6 7 8 9 10
| @Slf4j @Component public class TestEventListener {
@EventListener public void onTestEventHandle(TestEvent event) { log.info("event Id: " + event.getEventId() + ", type: " + event.getType() + ", Message: " + event.getData()); log.info("Handling context started event."); } }
|
Spring Bean에 등록된 EventListener에서 이벤트를 받아서 처리한다.
1 2
| 2023-01-19 15:26:28.072 INFO 20172 --- [ctor-http-nio-3] c.e.s.listener.TestEventListener : event Id: 8f9d4534-7ada-404a-9b1b-71f2958a749b, type: completed, Message: testSample! 2023-01-19 15:26:28.072 INFO 20172 --- [ctor-http-nio-3] c.e.s.listener.TestEventListener : Handling context started event.
|
잘 돌아간다.