본문 바로가기
웹 개발/Back End

이벤트 리스너 사용법

by L3m0n S0ju 2024. 9. 17.

 

 

 

@Getter
@RequiredArgsConstructor
public enum EmailAlarmEventType implements StonEnumMapperType {

    GOODS_OFF_SCHEDULING_STOP_MAIL_ALARM("GOODS_OFF_SCHEDULING_STOP_MAIL_ALARM", "상품 판매 중단에 따른 스케줄링 취소 메일 알림"),
    DEFERRED_USE_LIMIT_MAIL_ALARM("DEFERRED_USE_LIMIT_MAIL_ALARM", "후불 마스터 사용 한도 알림");

    private final String code;
    private final String title;
}

 

첫번째로 이벤트 타입을 Enum 클래스를 생성합니다. 원하는 이벤트 타입을 예시처럼 만들어서 이벤트 리스너를 실행할 때 타입별로 구분하여 원하는 메서드를 실행할 수 있습니다.

 

 

 

@Component
@RequiredArgsConstructor
public class EventListener {

    private final MailService mailService;

    /**
     * 이메일 알람 이벤트 리스너
     *
     * @param eventDto 이메일 알람 전용 DTO
     */
    @TransactionalEventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendEmailAlarm(EmailAlarmEventDto eventDto) {
        switch (eventDto.getEventType()) {
            case GOODS_OFF_SCHEDULING_STOP_MAIL_ALARM:
                handleEventList(eventDto, mailService::sendGoodsOffSchedulingEmail);
                break;
            case DEFERRED_USE_LIMIT_MAIL_ALARM:
                handleEvent(eventDto, mailService::sendDeferredUseLimitEmail);
                break;
            default:
                throw new CoreAppException(CoreAppExceptionCode.UNSUPPORTED_EVENT_TYPE);
        }
    }

    private <T> void handleEventList(CopbizEventDto eventDto, Consumer<T> action) {
        List<T> targetList = (List<T>) eventDto.getTarget();
        targetList.forEach(action);
    }

    private <T> void handleEvent(CopbizEventDto eventDto, Consumer<T> action) {
        T target = (T) eventDto.getTarget();
        action.accept(target);
    }
}

 

이벤트 리스터를 실행할 때 타입에 따른 이벤트를 동작하기 위한 코드입니다. 이벤트가 발생하면 해당 타입의 이벤트가 실행됩니다.

 

 

 

 @Transactional
    public void sendTestEmail(파라미터) {

        if (조건) {
            eventPublisher.publishEvent(EmailAlarmEventDto.of(EmailAlarmEventType.DEFERRED_USE_LIMIT_MAIL_ALARM
                    , DeferredUseLimitAlarmDto.limitExhaustedOf(type, a, b, c)));
        }
    }

 

이벤트를 실행할 때는 발생시키고 싶은 위치에서 eventPublisher.publishEvent에 타입과 파라미터들을 dto에 담아서 넘겨주면 이벤트 리스너가 실행됩니다.

 

 

 

@Getter
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class EmailNotifyEventDto implements CopbizEventDto {
    private MailType eventType;
    private Object target;

    public static EmailNotifyEventDto of(MailType eventType, Object target) {
        return EmailNotifyEventDto.builder()
                .eventType(eventType)
                .target(target)
                .build();
    }
}

 

이벤트 리스너에 파라미터를 넘길 때 Type과 객체를 넘겨서 타입에 해당하는 이벤트를 실행하고 객체를 파라미터로 넘겨주는 식으로 EmailNotifyEventDto를 사용했습니다.

 

 

 

    /**
     * 테스트 알림 메일
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendDeferredUseLimitEmail(DeferredUseLimitAlarmDto alarmDto) {
        ... 생략
        sendWithResponse(emailNotifyRequestDto, MailType.DEFERRED_USE_LIMIT);
    }

 

마지막으로 실행될 메서드에서 원하는 함수를 실행하면 이벤트가 실행될 때 기존 서비스 함수와 독립적으로 실행됩니다.

'웹 개발 > Back End' 카테고리의 다른 글

스프링 배치(Spring Batch)란?  (0) 2025.04.12
Java 헷갈리는 것들 모음  (0) 2024.09.16
마이바티스 사용법  (0) 2024.09.15
@Mapper 사용법(Dto -> 엔티티 매핑)  (0) 2024.09.09
스프링 시큐리티 개념  (0) 2024.05.19

댓글