Spring 소스 코드 - 감청 이벤트 ApplicationListener 와 ApplicationEvent 소스 코드 분석
Spring 에서 ApplicationListener 와 ApplicationEvent 는 전형 적 인 이벤트 구동 모델 이다. 즉, 우리 가 흔히 말 하 는 발표 - 구독 모델 이다.사실 저 희 는 개발 과정 에서 이런 발표 - 구독 모델 모델 을 자주 사용 합 니 다. 구독 모델 을 발표 하 는 것 은 보통 한 쌍 의 대상 관계 에 사 용 됩 니 다. 예 를 들 어 다음 과 같은 사례 에서 저 희 는 이런 발표 - 구독 모델 을 사용 할 수 있 습 니 다.
사례: 사용자 등록 이 성공 한 후에 종종 다른 일 을 해 야 한다.
1. 포인트 추가
2. 확인 메 일 보 내기
3. 게임 계 정 이 라면 게임 선물 을 증정 할 수 있 습 니 다.
4. 색인 사용자 데이터
상기 사례 에서 만약 에 우리 가 업 무량 이 많 지 않 을 때 스프링 의 발표 - 구독 모드 를 직접 사용 하면 해결 할 수 있다. 각각 네 개의 감청 기 를 등록 하고 각각 네 가지 절 차 를 감청 하 며 모든 감청 기 는 독립 적 으로 한 가지 일 을 할 수 있다.이런 모델 을 사용 하면 코드 를 결합 시 킬 수 있 고 다 중 스 레 드 의 장점 과 결합 하여 성능 을 제공 할 수 있다.
1. 우선, 다음 Spring 의 게시 - 구독 모드 를 초보 적 으로 사용 합 니 다. 다음은 테스트 코드 입 니 다.
먼저 설정 파일 에 MyListen 과 MyListen 2 모니터 의 Bean 을 설정 합 니 다.
MyListen.java
package cn.edu.his.pay.listen;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class MyListen implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent arg0) {
if(arg0 instanceof MyEvent) {
MyEvent event = (MyEvent)arg0;
System.out.println(this.getClass().getName() + event.getParam1());
System.out.println(this.getClass().getName() + event.getParam2());
System.out.println(this.getClass().getName() + event.getSource());
}
}
}
MyListen2.java
package cn.edu.his.pay.listen;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class MyListen2 implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent arg0) {
if(arg0 instanceof MyEvent) {
MyEvent event = (MyEvent)arg0;
System.out.println(this.getClass().getName() + event.getParam1());
System.out.println(this.getClass().getName() + event.getParam2());
System.out.println(this.getClass().getName() + event.getSource());
}
}
}
MyEvent.java
package cn.edu.his.pay.listen;
import org.springframework.context.ApplicationEvent;
public class MyEvent extends ApplicationEvent {
public String param1;
public String param2;
public MyEvent(Object source,String param1,String param2) {
super(source);
this.param1 = param1;
this.param2 = param2;
}
public Object getSource() {
return super.getSource();
}
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}
public String getParam2() {
return param2;
}
public void setParam2(String param2) {
this.param2 = param2;
}
}
Test.java
@Test
public void test() {
// context
MyEvent event = new MyEvent("source","param1","param2");
context.publishEvent(event);
}
출력 결과
cn.edu.his.pay.listen.MyListenparam1
cn.edu.his.pay.listen.MyListenparam2
cn.edu.his.pay.listen.MyListensource
cn.edu.his.pay.listen.MyListen2param1
cn.edu.his.pay.listen.MyListen2param2
cn.edu.his.pay.listen.MyListen2source
위 테스트 코드 결 과 를 보면 마 이 이벤트 (테마) 를 사용자 정의 하여 컨 텍스트 에 게시 할 수 있 습 니 다. 이 럴 때 모니터 구독 (관찰자) 만 있 으 면 테마 정 보 를 받 아 자신의 업 무 를 완성 할 수 있 습 니 다.
2. 그리고 스프링 이 어떻게 구독 을 했 는 지 생각해 볼 필요 가 있 습 니 다.지금 우 리 는 Spring 소스 코드 를 결합 하여 분석 할 것 이다.
스프링 이 초기 화 할 때 뭐 했 는 지 볼 까요?입구: AbstractApplication Context \ # registerListeners.
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 lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
위의 코드 를 통 해 알 수 있 듯 이 용기 가 초기 화 될 때 모든 애플 리 케 이 션 Listener 인터페이스 클래스 beanName 을 애플 리 케 이 션 Listener Beans 집합 에 먼저 등록 합 니 다. 모든 모니터 를 등록 한 셈 입 니 다.
그 다음 에 테 마 를 발표 할 때 context. publishEvent (event) 는 무엇 을 했 는 지 다시 한 번 살 펴 보 겠 습 니 다.입구: AbstractApplicationContext \ # publishEvent (ApplicationEvent event).
@Override
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {
listener.onApplicationEvent(event);
}
}
}
위의 코드 를 통 해 알 수 있 듯 이 이벤트 (테마) 를 발표 할 때 getapplicationListeners (이벤트) 를 통 해 모든 모니터 (관찰자) 를 가 져 왔 습 니 다. 사실은 이전 Spring 시작 때 applicationListener Beans 집합 에 등록 하면 됩 니 다.모든 감청 기 (관찰자) 를 꺼 내 서 감청 기 (관찰자) onApplicationEvent 방법 을 반복 해서 호출 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.