Backend/SpringBoot

커스텀 Event 발생 -> 수신

Dean83 2025. 9. 2. 11:29

예전에 C# 으로 개발할 때 종종 사용하던 방식이었다. 이후 delegate 나 콜백 활용으로 잘 쓰지는 않았지만, 스프링부트에도 해당 기능이 있기에 사용 할 수 있을때를 대비해 내용을 정리해 둔다. 

 

1. 이벤트 객체 클래스 생성

  • 맴버변수는 private final 이어야 한다.
  • getter 만 있어야 한다
public class TestEventArgs
{
	private final String arg1;
    private final Integer arg2;
    ...
    
    public TestEventArgs(String a1, Integer a2)
    {
    	arg1 = a1;
        arg2 = a2;
    }
    
    public String getArg1()
    {
    	return arg1;
    }
    
    public Integer getArg2()
    {
    	return arg2;
    }
}

 

2. 서비스에서 이벤트 발생 시키기

@Service
public class EventService
{
	private final ApplicationEventPublisher eventPublisher;
    ...
    
     public EventService(ApplicationEventPublisher eventPublisher) {
        ...
        this.eventPublisher = eventPublisher;
    }
    
    @Transactional
    public void TransactionEvent()
    {
    	....
        TestEventArgs arg = new TestEventArgs("test",1);
        eventPublisher.publishEvent(arg);
        ...
    }
    
    public void NormalEvent()
    {
    	....
        TestEventArgs arg = new TestEventArgs("test1",2);
        eventPublisher.publishEvent(arg);
        ...
    }
}
  • ApplicationEventPublisher 는 시스템에서 생성한 빈으로, 그냥 사용하면 된다.
  • 트랜잭션 관련 이벤트이냐, 아니냐에 따라 이벤트 수신부에서 처리 동작이 다르다.
    • 트랜잭선이 완료 혹온 롤백 되었을때 처리가 다르기 때문이다.

3. 이벤트 수신

@Component
public class EventListenerClass
{
	@EventListener
    @Order(1)
    public void eventListenMethod(TestEventArgs event) {
    	String args1 = event.getArgs1();
        ....
    
	}
    
    //특정 조건일때 에만 수신 (예 : 모바일 회원에게만 푸시 해야한다든지)
    @EventListener(condition = "#event.args2 == 1")
    @Order(2)
    public void specialEventListenMethod(TestEventArgs event) {
        ...
    }
    
    
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void afterCommit(TestEventArgs event) {
        ...
    }
    
    /**
     * 트랜잭션 롤백 시 실행
     */
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void handleRegistrationFailure(TestEventArgs event) {
        log.error("오류 메세지", event.getArgs1());
        
    }
    
    @EventListener({TestEventArgs.class, TestEventArgs2.class})
    public void multiEventMethod(Object event) {
        if (event instanceof TestEventArgs) {
            ...
        } else if (event instanceof TestEventArgs2) {
            ...
        }
    }
}
  • @EventListener 를 통해 이벤트 수신이 가능하다
    • 다수의 이벤트를 하나의 함수에서 listen 하는것도 가능하다.
    • Event인자값의 특정 상태에 따라 골라서 수신하는것도 가능하다.
  • @TransactionalEventListener 를 통해 커밋, 롤백시 이벤트를 수신 할 수 있다.
  • @Order(숫자) 를 통해 이벤트 수신 순서를 정해 순서대로 처리할 수 있다.