Spring Event와 ApplicationEventPublisher

spring event

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.

잘 돌아간다.

Spring Event와 ApplicationEventPublisher

https://yoo0926.github.io/2023/06/16/spring/spring-3/

Author

Jaeyong Yoo

Posted on

2023-06-16

Updated on

2023-06-16

Licensed under

댓글