임시저장 해놓고 안 올렸길래 ..
Spring Event는 스프링에서 제공하는 이벤트 기반 프로그래밍을 지원하기 위한 기능이다.
이벤트는 이벤트를 발행하는 publisher와 이벤트를 처리하는 listener로 나누어진다.
이벤트를 이용하면 코드에 대한 의존성을 분리할 수 있고, 특정 작업 이후에 이벤트를 통해 추가적인 작업 이후에 이벤트를 통해 추가적인 작업을 의존성 없이 진행할 수 있다는 장점이 있다.
로그인 이후 알림을 전송하는 경우 로그인과 알림 발송에 대한 의존성을 분리하는 데 이벤트를 사용할 수 있다.
스프링에서 이벤트의 발행과 구독
- 멀티캐스팅 방식으로 동작한다.
- 동기 방식으로 동작한다.
- 트랜잭션과의 결합이 필요하다면 다른 리스너를 사용해야 한다.
loginEvent 생성
public class LoginEvent {
private final Long memberId;
public LoginEvent(Long memberId){
this.memberId = memberId;
}
public Long getMemberId(){
return memberId;
}
}
@Component
@RequiredArgsConstructor
public class LoginEventPublisher {
private final ApplicationEventPublisher eventPublisher;
public void publishLoginEvent(Long memberId){
eventPublisher.publishEvent(new LoginEvent(memberId));
}
}
@Transactional(readOnly = true)
public LoginResponse login(LoginRequest loginRequest) {
validateLoginRequestFormat(loginRequest);
Member member = findMemberByEmail(loginRequest.memberEmail());
member.checkPassword(loginRequest.memberPassword());
String token = jwtTokenProvider.createToken(member.getId());
loginEventPublisher.publishLoginEvent(member.getId());
return new LoginResponse(token, member.getId(), member.getMemberName(), member.getMemberNickName(),
member.getAnnualIncome(), member.getDeposit());
}
login 할 때 이벤트 발송
이벤트 발행을 위해 EventPublisher 주입 받음
스프링 이벤트는 기본적으로 동기 방식으로 동작하는데, @Async 메소드를 사용하여 비동기 처리를 할 수 있다.
알림 발생 시 예외가 발생하면 AuthService까지 예외가 전파되어 로그인도 롤백된다. 이러한 상황은 의존성이 분리되었다고 보기 어렵다.
의존성 분리 및 비동기 처리를 하기위해 @Async와 @TransactionalEventListenr 를 사용 할 수 있다.
package com.example.investment_api.virtual.notification;
import com.example.investment_api.virtual.notification.service.NotificationService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class LoginEventListener {
private final NotificationService notificationService;
@Async
@EventListener
public void handleLoginEvent(LoginEvent event){
Long memberId = event.getMemberId();
try {
notificationService.sendFluctuationTop3NewsNotification(memberId);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Async를 활성화하기 위해서는 @EnableAsync를 선언해주어야 한다.
그리고 별도의 Config 클래스를 통해 @EnableAsync를 적용한다.
@Configuration
@EnableAsync
public class AsyncConfig {
}
로그에 async-executor-로 시작하는 스레드 이름이 출력되면 비동기 작업이 스레드 풀에서 실행되고 있는 것
비동기 처리 중 발생한 예외는 AsyncUncaughtExceptionHandler를 구현하여 예외 처리가 가능하다.
정리: 스프링 이벤트를 활용한 비동기 처리는 애플리케이션의 성능을 향상시키고, 사용자 경험을 개선하는 데 중요한 역할을 한다.
비동기 이벤트 처리는 애플리케이션의 비즈니스 로직과 이벤트 처리를 분리하여, 시스템의 유연성과 확장성을 높일 수 있다.
참고
[Spring] Spring Event 를 이용한 비동기 이벤트 처리
예제 및 테스트 코드는 github 에서 확인 가능합니다.[Spring] Spring Event 를 이용한 비동기 이벤트 처리Spring Event 는 스프링에서 제공하는 이벤트 기반 프로그래밍을 지원하기 위한 기능입니다.이벤
devoong2.tistory.com
https://yooniversal.github.io/study/post286/
[Spring] @Async를 이용해 Listener에서 비동기로 동작하는 로직 작성하기
yooniversal.github.io
https://velog.io/@yardyard/Spring-EventListener-%EB%B9%84%EB%8F%99%EA%B8%B0
Spring @EventListener & 비동기
각 Service간 비즈니스 로직에 따른 강결합으로 인해서 유지보수간 많은 리소스가 생기는데..??
velog.io
'spring & java' 카테고리의 다른 글
| Security + OAuth 를 활용한 카카오 로그인 처리 (4) | 2025.08.14 |
|---|---|
| 스프링 시큐티리 + JWT 를 이용한 로그인 처리 (2) | 2025.08.03 |
| 쿠키 & 세션 / JWT (1) | 2024.08.22 |
| JPA 영속성 컨텍스트 / 영속성 전이 (0) | 2024.08.13 |
| HTTP method (2) | 2024.08.11 |