Spring Boot에서 이벤트 처리의 두 가지 방법

Spring Boot의 이벤트 메커니즘을 활용한 두 가지 구독 방식에 대해 설명합니다.

I. 개발 환경

Spring Boot 2.2.1.RELEASE, Maven 3.5.3, IDEA 기반으로 웹 서버를 구성했습니다.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

II. 이벤트 시스템 구현

1. 이벤트 클래스 정의

Spring의 ApplicationEvent를 상속받는 기본 이벤트 클래스입니다.

public class NotificationEvent extends ApplicationEvent {
    private final String content;

    public NotificationEvent(Object source, String content) {
        super(source);
        this.content = content;
    }

    @Override
    public String toString() {
        return "NotificationEvent{content='" + content + "'}";
    }
}

2. 인터페이스 기반 처리

ApplicationListener 인터페이스 구현 방식입니다. Spring 빈으로 등록되어야 합니다.

@Service
public class NotificationHandler implements ApplicationListener<NotificationEvent> {
    @Override
    public void onApplicationEvent(NotificationEvent event) {
        System.out.println("받은 이벤트: " + event);
    }
}

3. 어노테이션 기반 처리

메서드 단위로 @EventListener 어노테이션을 사용하는 방식입니다.

@Component
public class EventConsumer {
    @EventListener
    public void handleEvent(NotificationEvent event) {
        System.out.println("어노테이션 통해 받은 이벤트: " + event);
    }
}

4. 이벤트 발행

ApplicationContext를 통해 이벤트를 발행하는 컴포넌트입니다.

@Service
public class EventDispatcher implements ApplicationContextAware {
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        this.context = ctx;
    }

    public void triggerEvent(String message) {
        context.publishEvent(new NotificationEvent(this, message));
    }
}

5. 테스트 코드

이벤트 발행 및 처리 테스트를 위한 컨트롤러입니다.

@RestController
public class TestController {
    @Autowired
    private EventDispatcher dispatcher;

    @GetMapping("/emit")
    public String testEndpoint(@RequestParam String message) {
        dispatcher.triggerEvent(message);
        return "이벤트 전송 완료";
    }
}

테스트 결과

어노테이션 통해 받은 이벤트: NotificationEvent{content='테스트 메시지'}
받은 이벤트: NotificationEvent{content='테스트 메시지'}

주의 사항 애플리케이션 시작 시점에 이벤트를 발생시키면 어노테이션 방식이 동작하지 않는 경우가 있습니다. 이는 이벤트 등록이 발생보다 늦어질 수 있는 Spring의 라이프사이클 특성 때문입니다. 구체적인 원인은 소스코드 분석을 통해 확인 가능합니다.

태그: spring-boot application-event event-listener-annotation

8월 12일 11:20에 게시됨