본문 바로가기
Spring

Event를 발행해 느슨한 결합을 가져보자

by zkdlu 2021. 3. 27.

도메인 모델간에 강한 의존성을 갖게 되면 트랜잭션의 범위가 커지고 시스템이 복잡해지는 경우가 발생합니다. 이를 해결하기 위해 Spring에서는 이벤트를 발행하고 핸들링하는 방법을 제공해줍니다.

 

시나리오

주문을 하면 주문 완료 Sms를 발송한다.

@RequiredArgsConstructor
@Service
public class OrderService {
    private final OrderRepository orderRepository;
    private final SmsClient smsClient;

    public void placeOrder(OrderRequest orderRequest) {
        Order order = new Order(orderRequest.getOrderId());
        order.place();
        orderRepository.save(order);

        smsClient.send("문자 발송~");
    }
}

주문이 이루어지면 주문 완료 메시지를 보내기 위해 OrderService는 SmsClient에 의존을 갖게되고 이는 추후 변경 및 유지보수에 악영향이 발생하게 됩니다.

 

이를 Spring에서 제공하는 Application Event를 사용해 해결해보겠습니다.

Event를 사용하기 위해서는 다음 3가지가 필요합니다.

  1. Event
  2. Event Publisher
  3. Event Listener
@Getter
public class OrderEvent extends ApplicationEvent {
    private long orderId;

    public OrderEvent(Object source, long orderId) {
        super(source);
        this.orderId = orderId;
    }
}

이벤트를 정의합니다.

@RequiredArgsConstructor
@Service
public class OrderService {
    private final OrderRepository orderRepository;
    private final ApplicationEventPublisher eventPublisher;

    public void placeOrder(OrderRequest orderRequest) {
        Order order = new Order(orderRequest.getOrderId());
        order.place();
        orderRepository.save(order);

        eventPublisher.publishEvent(new OrderEvent(this, orderRequest.getOrderId()));
    }
}

주문이 일어나면 해당 주문 번호에 해당하는 주문 이벤트를 발행합니다.

@RequiredArgsConstructor
@Component
public class OrderEventHandler {
    private final SmsClient smsClient;

    @EventListener
    public void send(OrderEvent orderEvent) {
        smsClient.send(orderEvent.getOrderId() + "번 주문");
    }
}

ApplicationEventPublisher가 발행한 이벤트를 처리할 핸들러를 만들어줍니다.

 

 

최종적으로 기존의 강한 의존 관계를 느슨하게 만들 수 있습니다.

 

https://github.com/zkdlu

 

zkdlu - Overview

Backend Developer . zkdlu has 54 repositories available. Follow their code on GitHub.

github.com