IoC Container - ApplicationEventPublisher
옵저버 패턴의 구현체로, 이벤트 기반 프로그래밍에 유용한 인터페이스를 제공한다.
Observer pattern
옵저버 패턴엔 행위자, 관찰자가 존재한다.
행위자의 어떤 행동으로 변경 사항이 발생하면 즉시 관찰자에게 알려주는 것이 요점이다.
가장 대표적인 응용 사례는 데이터 바인딩이라고 할 수 있다.
웹 프론트엔드 개발에 가장 많이 사용되는 프레임워크 중 Angular, React 등은 데이터 바인딩을 지원하고 있다.
View가 어떤 데이터를 바라보고 있고, 그 데이터가 변하는 즉시 View도 그 변화를 반영한다.
물론 View가 바뀐 데이터를 반영하는 과정엔 프로그래머의 개입이 필요하지 않다.
Event Publisher / Subscriber
Spring에선 Event를 발생시키는 publisher, Event를 받아서 처리하는 subscriber를 아주 간단하게 구현할 수 있다.
아래와 같이 소스 코드를 작성한다.
- Event
- Event의 정보를 담는 POJO
public class Event {
private int data;
public Event(int data) { this.data = data; }
public int getData() { return data; }
}
- AppRunner
- Spring boot application이 실행된 후 이벤트를 발생시키는 장소
- ApplicationEventPublisher를 주입받아 활용
- ApplicationContext도 publishing 가능
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
private ApplicationEventPublisher publisher;
@Override
public void run(ApplicationArguments args) throws Exception {
// event publishing
publisher.publishEvent(new Event(100));
}
}
- EventHandler
- Event를 처리하는 객체
@EventListener
Annotation을 붙여서 구현- 처리할 객체 (
Event
)를 매개변수로 받는다.
@Component
public class EventHandler {
@EventListener
public void handler(Event event) {
System.out.println(“Event data : “ + event.getData());
}
}
결과
Event data : 100
AppRunner
에서 발생시킨 이벤트를 확인할 수 있다.
Multiple Subscriber
이벤트 처리를 하는 곳이 하나 이상일 수도 있다.
그럴 때는 위의 3번과 같은 방법으로 작성하면 된다.
- AnotherHandler
- 위의 3번과 같은 이벤트를 처리할 객체
@Component
public class AnotherHandler {
@EventListener
public void handler(Event event) {
System.out.println(“Another handler : “ + event.getData());
}
}
결과
Event data : 100
Another handler : 100
Event 처리 순서
위의 방법은 하나의 이벤트를 여러 개의 핸들러에서 처리할 수 있지만 순서는 보장하지 않는다.
순서를 정해주기 위해 @Order
를 활용한다.
AnotherHandler
에만 우선순위를 적용해보자.
- AnotherHandler
- 우선순위 적용
@Component
public class AnotherHandler {
@EventListener
@Order(Ordered.HIGHEST_PRECEDENCE)
public void handler(Event event) {
System.out.println(“Another handler : “ + event.getData());
}
}
결과
Another handler : 100
Event data : 100
의도한 대로 AnotherHandler
가 먼저 동작했다.
Ordered
는 인터페이스로, 두 개의 필드와 1개의 구현체로 구성되어 있다.
두 필드값 HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE 의 값을 비교해보면
숫자가 낮은 값이 높은 우선순위를 가진다는 것을 알 수 있다.
'Java > Spring framework' 카테고리의 다른 글
Spring framework core (8) - Resource (0) | 2020.01.15 |
---|---|
Spring framework core (7) - ResourceLoader (0) | 2020.01.14 |
Spring framework core (5) - Message Source (0) | 2020.01.12 |
Spring framework core (4) - Environment (0) | 2020.01.12 |
Spring framework core (3) - Bean scope (0) | 2020.01.12 |