Spring

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

zkdlu 2021. 3. 27. 20:54

도메인 모델간에 강한 의존성을 갖게 되면 트랜잭션의 범위가 커지고 시스템이 복잡해지는 경우가 발생합니다. 이를 해결하기 위해 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