스프링 이벤트 1 - 프로젝트 세팅

아래 예제는 github에 소스를 올려놓았습니다.


일단 본격적인 스프링 이벤트에 알아보기에 앞서 주문 기능이 있는 프로젝트를 세팅해보자.

프로젝트 생성을 위해 Spring Initializr를 통해 아무런 dependency를 추가하지 않은 Spring Boot 프로젝트를 생성한다.
본인의 경우 최신 RELEASE 버전인 2.1.5 버전을 사용하였다.

※ 주문한 사용자인 User에 대해서는 예제가 복잡해져 String으로 대체합니다.

  1. 주문 도메인 클래스를 생성한다.

주문에 대한 도메인 클래스 Order를 생성한다.
Order는 주문자, 제품, 가격, 주문 성공여부를 갖고있다.
(예제를 단순하게 하기 위해서 ID는 제외했다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Order {
private String orderer;
private String product;
private int price;
private boolean success;

private Order(final String orderer, final String product, final int price, final boolean success) {
this.orderer = orderer;
this.product = product;
this.price = price;
this.success = success;
}

public static Order success(final String user, final String product, final int price) {
return new Order(user, product, price, true);
}

public static Order fail(final String user, final String product, final int price) {
return new Order(user, product, price, false);
}

public String getOrderer() {
return orderer;
}

public String getProduct() {
return product;
}

public int getPrice() {
return price;
}

public boolean isFailed() {
return !this.success;
}
}
  1. 주문 Notifier를 생성한다.

주문에 대해서 알림을 보내는 OrderNotifier를 생성한다.
첫 포스팅에서 예로 들었던 것 처럼 EmailSender, KakaoTalkSender를 생성할 것인데,
주문에 대한 Notifier로 추상화를 할 것이다.

1
2
3
4
// 주문 Notifier를 추상화한 인터페이스 
public interface OrderNotifier {
void sendNotification(final Order order);
}
1
2
3
4
5
6
7
8
9
@Component
public class EmailSender implements OrderNotifier {

@Override
public void sendNotification(final Order order) {
System.out.printf("send email to %s - order (%s: $%d)%n",
order.getOrderer(), order.getProduct(), order.getPrice());
}
}
1
2
3
4
5
6
7
8
9
@Component
public class KakaoTalkSender implements OrderNotifier {

@Override
public void sendNotification(final Order order) {
System.out.printf("send kakaotalk to %s - order (%s: $%d)%n",
order.getOrderer(), order.getProduct(), order.getPrice());
}
}

예제를 단순화하기 위해 콘솔에 프린트 하는 것으로 로직을 대체한다.

  1. 주문 서비스를 통해 주문 기능을 구현한다.

주문 서비스를 생성하기 전에, 사용자의 주문 요청에 대한 DTO인 OrderRequest를 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class OrderRequest {
private final String product;
private final int price;

public OrderRequest(final String product, final int price) {
this.product = product;
this.price = price;
}

public String getProduct() {
return product;
}

public int getPrice() {
return price;
}
}

그리고 이 요청을 통해 주문을 하는 서비스 로직을 만들어보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@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 String user, final OrderRequest orderRequest) {
Order order = doOrder(user, orderRequest);

if (order.isFailed()) {
throw new IllegalStateException("Order failed");
}

emailSender.sendNotification(order);
kakaoTalkSender.sendNotification(order);

return order;
}

private Order doOrder(final String user, final OrderRequest orderRequest) {
String product = orderRequest.getProduct();
int price = orderRequest.getPrice();

if (user.isEmpty()) {
return Order.fail(user, product, price);
}

return Order.success(user, product, price);
}
}

위 코드와 같이 OrderServiceEmailSender, KakaoTalkSender를 의존하고 있으며,
주문이 이뤄졌으면 알림을 보낸다.

  1. 주문하기 호출

위 서비스 로직을 호출하기 위해 main class에 호출 로직을 추가하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
System.out.println();

OrderService orderService = run.getBean(OrderService.class);

String user = "Chris";
OrderRequest orderRequest = new OrderRequest("Galaxy Tab S4", 4);

orderService.order(user, orderRequest);
}
}

이제 이를 실행하면 아래와 같이 콘솔에 EmailSenderKakaoTalkSender에서 출력한 로그를 확인할 수 있다.

이제 다음 부터는 스프링의 이벤트 기능을 사용하여 OrderServiceEmailSenderKakaoTalkSender 결합도를 낮춰보도록 하겠다.

Share