밤빵's 개발일지
[TIL]20241205 Event Publisher 본문
Spring의 Event Publisher는 애플리케이션에서 이벤트를 비동기적으로 처리할 수 있도록 도와주는 기능으로, 시스템의 결합도를 낮추고, 유연한 확장성을 가능하게 해준다. 이번 개발일지에서는 Event Publisher에 대해 처음 접한 초보 개발자로써 이 개념을 이해하고 적용했다.
Event Publisher
Event Publisher는 특정 이벤트가 발생했을 때 이를 다른 객체에게 알리는 역할을 한다. 이벤트를 발생시키는 쪽과 처리하는 쪽을 느슨하게 연결해서, 서로의 존재를 알지 못해도 상호작용이 가능하게 한다. 이런 점은 대규모 애플리케이션에서 모듈 간의 결합도를 낮추고 유지보수성을 높이는 데 큰 장점을 제공한다. 예를 들어, 회원 가입 시 이메일 알림을 보내야 한다고 가정했을 때, 일반적으로 회원 가입 로직과 이메일 전송 로직을 하나의 코드에 작성할 수도 있지만, 이렇게 하면 코드의 결합도가 높아져 유지보수에 어려움이 생긴다. Event Publisher를 사용하면 회원 가입 시 이벤트를 발생시키고, 이메일 전송은 별도의 리스너가 이를 처리하도록 할 수 있다.
Event Publisher의 사용 방법
Spring에서 Event Publisher를 사용하기 위해서는 몇 가지 단계를 거쳐야 한다.
간단한 회원 가입 이벤트라면,
1. 이벤트 클래스 생성
이벤트는 단순히 데이터 전달 역할을 하고, 관련 정보를 담는 클래스를 생성한다.
public class UserRegisteredEvent {
private final String userEmail;
public UserRegisteredEvent(String userEmail) {
this.userEmail = userEmail;
}
public String getUserEmail() {
return userEmail;
}
}
2. 이벤트 퍼블리셔 구현
이벤트를 발생시키는 클래스는 ApplicationEventPublisher를 사용하여 이벤트를 퍼블리시할 수 있다.
@Service
public class UserService {
private final ApplicationEventPublisher eventPublisher;
@Autowired
public UserService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void registerUser(String email) {
// 사용자 등록 로직
System.out.println("사용자가 등록되었습니다: " + email);
// 이벤트 발생
UserRegisteredEvent event = new UserRegisteredEvent(email);
eventPublisher.publishEvent(event);
}
}
3. 이벤트 리스너 구현
이벤트를 처리할 리스너를 구현한다. 이벤트가 발생했을 때 자동으로 호출된다.
@Component
public class UserRegisteredEventListener {
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) {
System.out.println("이메일 전송: " + event.getUserEmail());
}
}
4. 비동기 처리 설정 (선택)
이벤트 리스너는 기본적으로 동기적으로 동작하지만, 비동기 처리를 통해 메인 로직의 성능을 향상시킬 수 있다. Spring에서 비동기로 이벤트를 처리하려면 @EnableAsync와 @Async 어노테이션을 사용한다.
@Configuration
@EnableAsync
public class AsyncConfig {
}
@Component
public class UserRegisteredEventListener {
@Async
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) {
// 이메일 알림 전송 로직 "비동기 처리"
System.out.println("비동기로 이메일 전송: " + event.getUserEmail());
}
}
- @EnableAsync: Spring 애플리케이션에서 비동기 처리를 활성화하기 위해 사용하는 어노테이션으로, 이 어노테이션을 사용하면 @Async가 붙은 메서드가 별도의 스레드에서 실행될 수 있게 된다.
- @Async: 메서드에 이 어노테이션을 붙이면 해당 메서드는 비동기로 실행된다. 비동기 메서드는 호출 즉시 새로운 스레드에서 실행되며, 호출자는 해당 메서드의 완료를 기다리지 않고 다음 로직을 수행할 수 있다.
Event Publisher의 장점
- 결합도 감소: 이벤트를 발생시키는 클래스와 이를 처리하는 클래스 간의 결합도가 낮아진다. 서로 직접적인 의존성을 가지지 않기 때문에 변경이 발생해도 영향이 최소화된다.
- 확장성: 새로운 이벤트 처리 로직을 추가하고 싶다면, 기존 코드를 수정하지 않고 새로운 리스너를 추가하기만 하면 된다. 회원 가입 시 이메일 외에도 SMS 알림을 보내고 싶다면 새로운 리스너만 추가하면 된다.
- 비동기 처리: 이벤트 리스너를 비동기로 설정하면, 메인 로직이 완료된 후 백그라운드에서 별도로 이벤트를 처리할 수 있어 성능 향상에 도움이 된다.
- 명확한 책임 분리: 이벤트 발생과 처리 로직을 분리함으로써 각 클래스가 자신의 역할에 집중할 수 있다. 코드의 가독성을 높이고 유지보수성을 향상시킨다.
Event Publisher 적용 시 주의사항
- 비동기 이벤트 처리의 예외 처리: 비동기 이벤트 처리 시 발생한 예외는 호출자에게 전달되지 않기 때문에, 예외 처리 로직을 별도로 구현해야 한다. 이를 위해 try-catch 블록을 사용하거나, AsyncUncaughtExceptionHandler를 통해 비동기 메서드에서 발생한 예외를 처리할 수 있다.
- 이벤트 남용 방지: 모든 로직을 이벤트로 처리하려고 하면 오히려 시스템이 복잡해지고, 디버깅이 어려워질 수 있다. 이벤트는 적절한 경우에만 사용해야 한다.
Spring의 Event Publisher는 시스템의 결합도를 낮추고 확장성을 높이는 데 유용하다. 이번 개발일지를 작성하면서 회원 가입 시 이벤트를 발생시키고, 이를 통해 이메일 알림을 보내는 과정을 직접 구현했다. Event Publisher를 활용하면 모듈 간의 의존성을 최소화하고, 새로운 기능을 손쉽게 추가할 수 있어 앞으로의 프로젝트에서도 활용해볼 만한 가치가 있다고 느꼈다. 또한 비동기 처리를 통해 성능을 최적화하고, 책임 분리를 통해 코드의 유지보수성을 높이는 것이 중요하다는 걸 다시 한번 깨닫게 되었다.
'개발Article' 카테고리의 다른 글
[TIL]20241207 Enum은 왜 쓰는걸까? (2) | 2024.12.07 |
---|---|
[TIL]20241206 equals()와 hashCode()를 재정의 해야하는 이유? (2) | 2024.12.06 |
[TIL]20241204 DTO와 Entity 간 변환 방식 고민하기 (0) | 2024.12.04 |
[TIL]20241202 TDD 적용하고 기능 구현 하기 (0) | 2024.12.02 |
[TIL]20241201 Redis 적용을 위한 공부... (2) | 2024.12.01 |