프리랜서로 근무하게 된 회사에서 코드 분석 중인데 클래스간 책임을 분리하기 위하여 Spring Event를 사용하고 있었다. 때문에 Spring Event를 알아보지 않고 넘어갈 수가 없어서 정리하려 한다.
Spring Event는 스프링프레임 워크에서 내부적으로 데이터를 전달 하는 방법이다.
예를 들어 결제 후 Log데이터를 기록해야 한다고 생각한다면, 간단히 결제Service에서 LogServcie를 의존하고 있다가 logService.write()로 실행할 수 있지만 구조가 복잡해지고 결제 후 추가로 해야할 작업이 많아진다면 결제Service가 의존하게되는 타 도메인들이 많아지게 되고 책임이 많아 지게 된다.
이 때 클래스간 결합을 느슨하게 하여 클래스의 책임을 좀 더 간결하도록 하기 위해 Spring Event를 생각해 볼 수 있다.
보통 Event를 발행한다고 하면 마치 Queue같은 곳에 메시지를 발행하면 타 도메인에서 구독하고 있다가 컨슘하는 것 처럼 생각할 수 있는데 Spring Event는 Observer Pettern을 기반으로 구현하였다.
이벤트를 통해 전달하고 싶은 정보 클래스.
@Getter
@AllArgsConstructor
public class PopEvent {
private Long id;
}
ApplicationEventPublisher클래스의 publishEvent메서드를 통해 정보를 발행한다.
@Service
@RequiredArgsConstructor
public class EventService {
private final ApplicationEventPublisher applicationEventPublisher;
public void popEvent(Long id) {
PopEvent popEvent = new PopEvent(id);
applicationEventPublisher.publishEvent(popEvent);
}
}
implements ApplicationListener를 사용해서 구독할 수도 있지만 아마 왠만하면 다들 Spring 버전이 높아서 @EventListener 어노테이션을 통해 구독할 정보를 듣고 있으면 더 간단하게 구현이 가능하다.
리스너를 통해 구독 중인 정보의 데이터를 가져다 쓰면 끗!
@Getter
@Component
public class Listener {
@EventListener(value = PopEvent.class)
public void doSomething(PopEvent event) {
System.out.println("event.getId() = " + event.getId());
}
}
Spring Event를 통해 클래스간의 결합도를 낮추고 클래스의 책임을 더 명확하게 할 수 있지만 발행클래스와 구독클래스가 항상 정상작동한다고 보장하지 않는다.