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의 라이프사이클 특성 때문입니다. 구체적인 원인은 소스코드 분석을 통해 확인 가능합니다.