도메인 주도 개발 시작하기 이벤트 ch10

김종완·2023년 11월 8일
1

이벤트

이벤트는 도메인의 변화를 나타내는 정보를 의미한다. 혹은, 도메인의 외부와 상호 작용하는 데 사용될 수 있다.

  • 이벤트의 구성 요소
    • 이벤트 생성 주체(엔티티, 밸류, 도메인 객체)
    • 이벤트
    • 이벤트 디스패처(이벤트 퍼블리셔)
    • 이벤트 핸들러(이벤트 구독자)

이벤트의 용도와 장점

  • 이벤트의 용도
    • 도메인의 상태가 바뀔 때 다른 후처리가 필요하면 후처리를 실행하기 위한 트리거로 이벤트를 사용할 수 있다.
    • 서로 다른 시스템 간의 데이터 동기화로 사용할 수 있다.
  • 이벤트의 장점
    • 서로 다른 도메인 로직이 섞이는 것을 방지할 수 있다.
    • 도메인의 외부와 상호 작용하는 데 사용할 수 있다.
    • 도메인의 확장성을 높일 수 있다.

이벤트와 이벤트 핸들러

  • 이벤트
    • 이벤트는 과거에 벌어진 상태 변화나 사건을 의미하므로 이벤트 클래스의 이름을 결정할 때에는 과거 시제를 사용해야 한다는 점을 유의해야 한다.
    • 이벤트를 발생 시키기 위해서 스프링에서는 ApplicationEventPublisher를 사용한다.
    • ApplicationEventPublisher가 제공하는 publishEvent() 메서드를 이용해서 이벤트를 발생시킨다.
# 이벤트 클래스 예시
import org.springframework.context.ApplicationEventPublisher;

public class Events {
	private static ApplicationEventPublisher publisher;
    
    static void setPublisher(ApplicationEventPublisher publisher) {
    	Events.publisher = publisher;
    }
    
    public static void raise(Object event) {
    	if (publisher != null) {
        	publisher.publishEvent(event);
        }
    }
 }
# Configuration 예시
@Configuration
public class EventsConfiguration {
	@Autowired
    private ApplicationContext applicationContext;
    
    @Bean
    public InitializingBean eventsInitializer() {
    	return () -> Events.setPublisher(applicationContext);
    }
# 이벤트 발생 예시
public class Order {
	public void cancel() {
    	verifyNotYetShipped();
        this.state = OrderState.CANCELED;
        Events.raise(new OrderCanceledEvent(number.getNumber()));
    }
    ...
  • 이벤트 핸들러
    이벤트를 처리할 핸들러는 스프링이 제공하는 @EventListener 애너테이션을 사용해서 구현한다. 다음은 OrderCanceledEvent를 처리하기 위한 핸들러를 구현한 코드이다.
import org.springframework.context.event.EventListener;

@Service
public class OrderCanceledEventHandler {
	private RefundService refundService;
    
    public OrderCanceledEventHandler(RefundService refundService) {
    	this.refundService = refundService;
    }
    
    @EventListener(OrderCanceledEvent.class)
    public void handle(OrderCanceledEvent event) {
    	refundService.refund(evnet.getOrderNumber());
    }
 }

위 코드는 주문 취소 이벤트가 발생할 때 환불을 할 수 있도록 하는 코드이다.

profile
개발에 재미를 느끼며 꾸준히 성장하는 개발자 김종완 입니다.

0개의 댓글