Spring 의 사건 감청 메커니즘 예시 상세 설명
최근 에 회 사 는 광고 시스템 을 재 구성 하고 있 는데 그 중에서 핵심 적 인 포장 공 은 광고 시스템 에서 호출 된다.즉,apk 포장 에 대한 호출 과 포장 이 완 료 된 후의 리 셋 은 해당 하 는 인 터 페 이 스 를 광고 시스템 에 제공 해 야 한다.따라서 apk 패키지 의 핵심 프로 세 스 와 도 킹 광고 시스템 의 업무 디 결합 을 위해 spring 의 이벤트 감청 특성 을 이용 하여 수 요 를 만족 시 켰 습 니 다.다음은 spring 의 이벤트 메커니즘 에 관 한 내용 을 설명 합 니 다.
우선 스프링 사건 은 이벤트 발표 자(EventPublisher),이벤트 감청 자(EventListener)로 나 뉘 며,이벤트 방송 자(이것 은 스프링 실현 과 관련 된 것 이 며,이 절 은 토론 하지 않 음)도 포함 된다.spring 이벤트 체 제 를 사용 하려 면 이벤트 발표 자 와 감청 자 를 사용자 정의 해 야 합 니 다.
1.관찰자 모드
Spring 의 이벤트 감청(이벤트 구동 이 라 고도 함)은 관찰자 모델 의 실현 으로 비교적 흔히 볼 수 있 는 게시-구독 모델 이 있다.일반적으로 저 희 는 메시지 큐 를 이용 하여 서로 다른 시스템 간 의 디 결합 을 실현 합 니 다.예 를 들 어 사용자 등록 이 완료 되면 메시지 큐 에 메 시 지 를 발표 한 다음 에 이 topic 의 서브 시스템(예 를 들 어 메 일 서비스,포인트 서비스)을 구독 하여 발표 한 메 시 지 를 받 은 후에 해당 하 는 처 리 를 할 수 있 습 니 다.이렇게 하 는 장점 은 등록 서비스 에서 다른 서비스의 코드 를 결합 시 키 는 것 을 피 하 는 것 이 고 서브 시스템 의 업 무 를 수행 하 는 것 은 비동기 적 으로 실행 되 고 서로 영향 을 주지 않 는 다 는 것 이다.아래 그림 은 전형 적 인 관찰자 모델 의 구조 이다.
다음은 상기 관찰자 모드 의 자바 간단 한 실현:
(1)Subject.java
package observerPattern;
import java.util.ArrayList;
import java.util.List;
/**
* Created by jy on 2018/11/28.
*/
public abstract class Subject {
//
private List<Observer> list = new ArrayList<>();
//
public void attach(Observer observer){
list.add(observer);
System.out.println(" ");
}
//
public void detach(Observer observer){
list.remove(observer);
System.out.println(" ");
}
//
public void notifyObservers(String state){
for (int i = 0; i < list.size(); i++) {
list.get(i).update(state);
}
}
}
(2)Observer.java
package observerPattern;
/**
* Created by jy on 2018/11/28.
*/
public interface Observer {
//
public void update(String state);
}
(3)ConcreteSubject.java
package observerPattern;
/**
* Created by jy on 2018/11/28.
*/
public class ConcreteSubject extends Subject{
//
private String state;
public String getState() {
return state;
}
public void change(String state){
this.state = state;
System.out.println(" :"+state);
this.notifyObservers(state);
}
}
(4)ConcreteObserver.java
package observerPattern;
/**
* Created by jy on 2018/11/28.
*/
public class ConcreteObserver implements Observer {
//
private String observerState;
@Override
public void update(String state) {
//
observerState = state;
System.out.println(" :"+observerState);
}
}
(5)Main.java
package observerPattern;
/**
* Created by jy on 2018/11/28.
*/
public class Main {
public static void main(String[] args) {
//
ConcreteSubject concreteSubject = new ConcreteSubject();
//
ConcreteObserver concreteObserver = new ConcreteObserver();
//
concreteSubject.attach(concreteObserver);
//
concreteSubject.change("2");
}
}
결과:main 방법 을 실행 한 후에 우 리 는 콘 솔 출력 결 과 를 볼 수 있 습 니 다.이 는 실제 관찰자 의 상 태 는 실제 주제 의 상태 변화 에 따라 달라 집 니 다.2.스프링 사건 감청
spring 도 이벤트 구동 모델 에 지원 을 제공 합 니 다.이 모델 은 주로 세 부분 으로 구성 되 어 있 습 니 다.
(1) 이벤트(ApplicationEvent):jdk 의 EventObject 를 계승 하여 spring 프로젝트 에서 ApplicationEvent 를 계승 하여 자신의 이 벤트 를 정의 할 수 있 습 니 다.
spring 용기 내부 에 서 는 applicationEvent 에 대해 다음 과 같은 몇 가지 실현 이 있 으 며,이름 을 통 해 사건 이 묘사 한 행 위 를 잘 알 수 있 습 니 다.
(2)발표 자(ApplicationEventPublisher):이 인 터 페 이 스 를 실현 하면 spring 구성 요소 가 사건 을 발표 하 는 능력 을 가 질 수 있 습 니 다.
응용 프로그램 Context 가 이 인 터 페 이 스 를 실현 한 것 을 볼 수 있 습 니 다.따라서 spring 구성 요 소 는 응용 프로그램 ContextAware 인 터 페 이 스 를 실현 하고 응용 프로그램 Context 를 주입 한 다음 에 응용 프로그램 Context 의 PublishEvent()방법 으로 사건 전 파 를 실현 할 수 있 습 니 다.
물론 ApplicationEventPublisher 인 터 페 이 스 를 직접 실현 하고 PublisheEvent()방법 을 다시 쓰 면 사건 전 파 를 실현 할 수 있다.
원본 코드 를 읽 은 결과 AbstractApplication Context 류 에서 관찰자 의 증가,get,등록 등 방법 을 정의 했다.다음 코드 의 addapplicationListener()는 applicationEvent Multicaster 클래스 에서 유지 하 는 set 에 listener 를 추가 합 니 다.이 set 는 게시 자의 모든 관찰자(listener)를 저장 합 니 다.
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
//listener applicationEventMulticaster
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
//
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
AbstractApplication Context 에서 PublishEvent:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
//.....
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); //
//....
}
구체 적 으로 이 벤트 를 발표 하 는 방법 은 위 에서 언급 한 ApplicationEvent Multicaster 라 는 유형의 클래스 에서 이 루어 집 니 다.AbstractApplicationContext 에 서 는 ConfigurableListableBeanFactory 에서 이 종 류 를 불 러 오 려 고 합 니 다.존재 하지 않 으 면 new Simple ApplicationEvent Multicaster 를 기본 으로 합 니 다.
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { //
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); // SimpleApplicationEventMulticaster
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
Simple Application Event Multicaster 가 어떻게 사건 을 방송 하 는 지 보 세 요.코드 를 통 해 알 수 있 듯 이 온라인 풀 이 비어 있 지 않 은 상황 에서 특정한 유형의 사건 을 비동기 적 으로 발표 합 니 다.
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
//....
invokeListener 방법 을 마지막 으로 클릭 하면 listener 의 onApplicationEvent()를 호출 하여 이벤트 발 표를 실현 한 것 을 발견 합 니 다.
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
//....
}
}
(3)이벤트 구독 자(ApplicationListener):이 인 터 페 이 스 를 실현 하면 ApplicationListener 가 발표 한 특정한 이 벤트 를 감청 할 수 있 습 니 다.ApplicationListener 라 는 인 터 페 이 스 를 실현 하고 onApplicationEvent()방법 을 다시 써 서 들 은 ApplicationEvent 를 처리 합 니 다.여 기 는 특정한 유형의 사건 을 감청 할 수 있 습 니 다.
3.주 해 를 바탕 으로 하 는 사건 감청
spring 도 발표 자 와 감청 자 에 게 해당 하 는 주석 지원 을 제공 합 니 다.해당 하 는 관찰자 류 의 대응 방법 에@EventListener 를 추가 하면 됩 니 다.
게시 자 에 대해 서 는 service 에서@Autowired 를 통 해 applicationEventPublisher 를 직접 주입 할 수 있 습 니 다.
4.소결
글 은 주로 spring 에서 이벤트 구동 모델 을 소개 했다.주로 관찰자 모델 의 사상 을 활용 한 다음 에 spring 에서 사건 발표 체 제 를 소개 했다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.