Spring에서 ApplicationEvent 객체를 사용하여 특정 이벤트를 발생시키고 이를 구독하는 방식으로 서로 다른 컴포넌트 간 느슨한 결합을 제공할 수 있는 @EventListener에 대해 알아보겠습니다. 👩🏻💻
@EventListener
특정 이벤트가 발생했을 때 이를 구독하고 정의된 메서드를 호출하는 역할을 합니다.
예를 들어, 특정 조건이 발생했을 때 자동으로 알림을 보내거나 데이터를 갱신하는 작업을 비동기 방식으로 처리할 수 있습니다.
이를 통해 모듈 간 결합도를 낮추고 이벤트가 발생하는 시점에만 필요한 작업을 수행할 수 있어 효율적입니다.
사용 예시
예를 들어, 사용자가 가입할 때 가입 성공 후 환영 이메일을 전송하는 이벤트 핸들러를 작성할 수 있습니다.
이벤트 클래스
public class UserRegisteredEvent {
private final String email;
public UserRegisteredEvent(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
이벤트 발행
UserService 클래스에서 ApplicationEventPublisher를 사용해 UserRegisteredEvent를 발행합니다.
@Service
public class UserService {
private final ApplicationEventPublisher publisher;
public UserService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void registerUser(String email) {
// 회원가입 로직 (예: 데이터베이스에 저장)
publisher.publishEvent(new UserRegisteredEvent(email)); // 이벤트 발행
}
}
이벤트 구독
UserRegisteredEvent가 발행되면 @EventListener를 사용해 UserRegisterEvent를 구독하고 특정 작업(이메일 전송)을 실행합니다.
@Component
public class UserEventListener {
@EventListener
public void handleUserRegistration(UserRegisteredEvent event) {
System.out.println("Sending welcome email to " + event.getEmail());
}
}
장점
- 모듈 간 결합도 감소: @EventListener는 이벤트 기반 구조를 통해 클래스 간의 결합도를 낮추어 유지보수와 확장성을 높여줍니다,
- 비동기 처리: 추가적인 설정을 통해 이벤트 핸들러를 비동기로 처리할 수 있어 성능을 최적화할 수 있습니다.
- 유연한 기능 확장: 새로운 이벤트 리스너를 추가함으로써 로직을 변경하지 않고도 다양한 후속 작업을 설정할 수 있습니다.
단점
- 디버깅 어려움: 이벤트 기반 시스템에서는 메서드 호출 흐름이 보이지 않기 때문에 디버깅이 다소 어려울 수 있습니다.
- 코드 복잡성 증가: 이벤트와 리스너가 많아질수록 코드의 흐름이 복잡해져 추적이나 유지보수가 어려워질 수 있습니다.
- 오버헤드: 이벤트 수 많아질 경우 성능 저하가 발생할 수 있으며 특히 동기 방식에서는 전체 프로세스가 느려질 수 있습니다.
🚨 주의사항
- 비동기 처리 시 주의: 비동기 방식으로 설정할 때는 메서드에서 사용하는 객체들이 스레드 안전하게 관리되도록 신경 써야 합니다.
- 트랜잭션 경계 설정: 트랜잭션이 완료되지 않았을 때 이벤트가 발생하면 문제가 생길 수 있으므로, 트랜잭션이 필요한 경우 @TransactionalEventListener를 사용하는 것이 좋습니다.
- 예외 처리: 이벤트 리스너에서 예외가 발생할 경우 전체 애플리케이션에 영향을 미칠 수 있으므로, 적절한 예외 처리가 필요합니다.
'Spring' 카테고리의 다른 글
동시성 문제 해결을 위한 ThreadLocal 이해하기 (1) | 2024.11.02 |
---|---|
[Spring] @EventListener VS @TransactionEventListener (0) | 2024.10.26 |
[Spring] 트랜잭션 상태에 맞춘 이벤트 처리 @TransactionalEventListener (0) | 2024.10.25 |
[Spring] HikariCP 동작 방식 (1) | 2024.09.29 |
[Spring] HikariCP란? (1) | 2024.09.27 |