우선 이벤트에 관하여 이해를 해야 스프링에서 제대로 이용하여 데이터를 주고 받을 수 있을 것입니다.
이벤트는 크게 2가지로 구분 됩니다.
이벤트 publisher
와 event listener
입니다. 스프링에만 있는것이 아니라 자바에서 기본적으로 제공하는 형식입니다.
이벤트
는 메서드 호출과 사뭇 다릅니다. 메서드 호출
은 정해진 조건에서, 정해놓은 메서드를 실행하지만, 이벤트
는 임의의 조건에서 불특정 다수의 리스너를 호출하게 됩니다.
따라서 스프링에 존재하는 리스너 들에게 특정한 사건이 발생마다 메서드를 실행하고 싶다면 이벤트를 사용하면 됩니다.
ApplicationEventPublisher
는 이벤트 발생시 이벤트 모델
을 스프링내에 존재하는 리스너
에게 전달하는 역할을 수행합니다.
@Service
public class 서비스1{
private final ApplicationEventPublisher applicationEventPublisher;
public 서비스1(ApplicationEventPublisher applicationEventPublisher){
this.applicationEventPublisher = applicationEventPublisher;
}
...
public void 메서드(매개변수){
applicationEventPublisher.publishEvent(new 이벤트(this,매개변수));
}
...
}
스프링의 DI
로 ApplicationEventPublisher 객체를 주입 받을 수 있습니다.
ApplicationEventPublisher.publishEvent(new 이벤트객체(this,매개변수,..))
로 이벤트를 발생시켜 이벤트 객체를 이벤트 리스너들에게 전달할 수도 있습니다.
이벤트 클래스는 다름이 아니라 ApplicatoinEvent
클래스를 상속받은 클래스입니다.
@Getter
public class 이벤트클래스 extends ApplicationEvent{
private 타입 매개변수;
...
public 이벤트클래스(Object source,타입 매개변수){
super(source);
this.매개변수 = 매개변수;
}
...
}
이벤트 클래스는 생성자로 Object source
를 생성자로 포함하여 super(source)
를 호출하여 ApplicationEvent
상위 클래스에게 source를 전달해야 합니다. 이외에 추가적인 매개변수도 받을 수 있습니다.
ApplicationEventPublisher
에게 ApplicationEvent
를 상속받은 이벤트 클래스를 받는 리스너는 @EventListener
애너테이션을 포함하는 메서드 입니다.
@Async
@EventListener
public 리턴타입 이벤트리스너(이벤트클래스 이벤트){
타입 변수 = 이벤트.get매개변수();
...
}
@Async
에너테이션은 비동기적으로 처리하기 위해 사용하는 애너테이션 입니다.
이벤트 리스너는 퍼블리셔가 보낸 이벤트 클래스를 매개변수로 받아서 사용할 수 있습니다.
이외에도 이벤트 클래스에 기능을 구현하면 해당 이벤트 클래스의 기능도 사용할 수 있습니다.
메서드는 기본적으로 동기적으로 작동합니다. 다른 해야할 일이 있더라도 다른 작업을 기다려야 하는 낭비가 발생할 수 있습니다. 비동기적으로 처리한다는 것은 할일을 하면서 요청이 올때만 잠시 하던일을 멈춤으로써 자원의 낭비를 최소화 시킬 수 있는 장점이 있습니다.
Spring에서는 @Async
에너테이션을 메서드에 추가하면 손쉽게 비동기 메서드를 만들 수 있습니다.
하지만 @Async
메서드가 포함된 클래스를 빈 객체로 관리하는 @Configuration
설정정보 클래스에 @EnableAsync
를 추가 해주어야만 @Async
에너테이션을 사용할 수 있으므로 주의해야 합니다.
@Service
public class 서비스{
...
@Async
@EventListener
public 타입 이벤트리스너(이벤트클래스 이벤트){
...
}
...
}
스프링에서 이벤트를 발생시키고 해당 이벤트를 받아 처리하는 로직을 배웠습니다. 함수 호출과는 다르게 Event라는 개념 자체가 임의적으로 불특정 다수에게 일어나므로 비동기적으로 동작한다고 볼 수 있겠습니다. 그에 따라 벤트를 받아 처리하는 리스너도 비동기적으로 작동해야 자원의 낭비를 최소화 할 수 있으므로 비동기적으로 처리하는 설정도 알아보았습니다.
private!