스프링 이벤트 0 - 개요

스프링에는 이벤트를 처리하는 기능이 있다.
이 기능을 통해 우리는 도메인 로직간의 결합도를 낮출 수 있다.

예를 들어 주문 서비스에서 결제가 완료되면 이메일로 결제 내역을 보내야 한다고 하면,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Service
public class OrderService {
private final EmailSender emailSender;

public OrderService(final EmailSender emailSender) {
this.emailSender = emailSender;
}

public Order order(final User user) {
Order order = doOrder(user); // 결제

if (order.isFailed()) {
throw new OrderFailException();
}

// 결제 내역에 대한 알림을 보낸다.
emailSender.sendOrderEmail(order);

return order;
}
}

여기까지는 크게 나쁘지 않다.
하지만 이후 기능이 추가되어 카톡으로 결제 알림도 보내야 한다면 KakakoTalkSender가 추가될 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Service
public class OrderService {
private final EmailSender emailSender;
private final KakaoTalkSender kakaoTalkSender;

public OrderService(final EmailSender emailSender, final KakaoTalkSender kakaoTalkSender) {
this.emailSender = emailSender;
this.kakaoTalkSender = kakaoTalkSender;
}

public Order order(final User user, final OrderRequest orderRequest) {
Order order = doOrder(user, orderRequest); // 결제

if (order.isFailed()) {
throw new OrderFailException();
}

// 결제 내역에 대한 알림을 보낸다.
emailSender.sendOrderEmail(user, order); // 이메일
kakaoTalkSender.sendOrderNotification(user, order); // 카톡

return order;
}
}

이렇듯 OrderService에 기능이 추가될 때 마다 dependency가 늘어나게 되고 component간의 결합도가 높아진다.

하지만 결제라는 로직에 결제 내역 알림 기능이 논리적으로 필요한가?
물론 일반적으로 결제를 하면 결제 내역이 문자나 이메일로 오긴하지만, 결제 자체는 알림과는 무관한 도메인이다.
또 만약 알림에서 문제가 나면 연쇄적으로 결제 기능에도 문제가 생길 수 있다.

결제를 하나의 이벤트라고 본다면, 이 이벤트가 발생하면 이벤트 리스너가 메일이나, 카톡 알림을 보내는 방식을 생각해 볼 수 있을 것이다.
이렇게 이벤트 리스닝 방식을 취하면 결제결제 내역 알림 이 두 기능간의 결합도를 낮출 수 있다.

이번 기획 포스팅에서는 위의 예제를 통해 스프링 이벤트 기능에 대해 간단하게 알아보도록 하겠다.

Share