이전 블로그는 SpringApplication.run (AuthServiceApplication.class, 인수)를 작성하며 SpringApplication 초기화,이 약 나중에 실행 방법에 기록합니다.
머리말 : 전에이 블로그를 작성 후, 나는이 단계 방법 코드를 혼란에 의해 단계는 코드가 무엇을하고 있는지 모른다보고 클릭을 통해 차례로, 조정은 과거 오랜 시간 동안 보면서 프레임 워크 SpringApplication을 이해하기 위해, 그 발견 , 제 1 및 제는 가장 먼저 이해해야 그 관찰자 패턴 , 때문에 전체적인 프레임 워크는 유연한 플러그 효과를 달성하기 위해 다양한 구성 요소를로드하는 관찰자 것으로 나타났습니다 블로그의 많은, 내보기 및 이해, 접근한다. 옵저버 모드, 자신의 검사가 명확하지 않다 학생들이, 여기에 내가 간단한 예제를주고, 더 이상 설명하기 위해 더 많은 일을하지 않습니다.
(1 개) 공공 클래스는 BaseEvent는 확장 은 EventObject { 2 문자열의 이름을; 3 사 공공 BaseEvent (오브젝트 소스, 문자열 이름) { 5 초 (소스); 6 이 .name을 = 이름; 7 } 8 9 공공 문자열 getName () { 10 반환 이름; 11 } 12 } 13 14 공중 인터페이스 BaseListener은 <T가 연장 BaseEvent>을 연장 {의 EventListener 15 보이드 doEvent (T를 t); 16 } 17 공중 인터페이스 EventPublisher은 <T는 연장 BaseEvent가> { 18 추상 공극이 (T 이벤트) 제작; 19 } 20 대중 클래스 이벤트는 확장 BaseEvent { 21 공공 이벤트 (오브젝트 소스, 문자열 이름) { 22 초 (소스, 이름); 23 } 24 } 25 개 공용 클래스 리스너 구현 BaseListener <이벤트> { 26 (27) 개인 문자열 이름; 28 (29) 공개 리스너 (문자열 이름) { 30 이 본 .name을 = 이름; 31이다 } 32 공용 리스너 () { 33이다 } 34는 @Override에게 35 공공 공극 DoEvent (이벤트 행사) { 36 에서 System.out.println ( " I 수신기 "+ 이 본 .name을 +"는 I은 모니터 "+ event.getName () +" , 이벤트 " ); 37 } 38 인 39 } 40 개 공용 클래스 BaseEventPublisher <T는 (가) 확장 BaseEvent> 유단을EventPublisher { 41 (42) 에서 <BaseListener <T >> listenerList = 새로운 ArrayList를 <> (); 43 44 공중 일람 <BaseListener <T >> getListenerList () { 45 반환 listenerList; 46 } 47 48 @Override 49 공공 공극 공개 (BaseEvent 이벤트) { 50 의 경우 (! CollectionUtils.isEmpty (listenerList)) { 51 대 (BaseListener 리스너 : listenerList) { 52 listener.doEvent ((T) 이벤트); 53 } 54 } 55 } 56 } 57 58 59 BaseEvent eventA는 = 새로운 이벤트 ( "", "eventA" ); 60 BaseEventPublisher 게시자 = 새로운 BaseEventPublisher을 (); 61 BaseListener <이벤트> = listenerA 새로운 수신기 ( "listenerA" ); 62 BaseListener <이벤트> = listenerB 새로운 수신기 ( "listenerB" ); 63 publisher.getListenerList ()에 추가 (listenerA).; 64 . publisher.getListenerList () (listenerB) 추가; 65 publisher.publish (eventA);
우리는 자신의에서 실행 이해할 수있는 방법을 관찰자 모드의 마음.
--------------------
다음은 소스 코드의 이해를보기 위해 내 자신에 대해 쓰기
. (1) 공개 ConfigurableApplicationContext RUN (문자열 ...에 args) { 2 스톱워치 스톱워치 = 새로운 새로운 스톱워치 (), 자체 검사의 사용에 관련 될 수있는 소비되는 시간에 포함되는 동작 코드를 출력하는, 여기에서 설명되지 않을 // 3. stopWatch.start을 () . 4 ConfigurableApplicationContext 컨텍스트 = 널 ] . 5 모음 <SpringBootExceptionReporter> = exceptionReporters 새로운 새로운 ArrayList를 <> () . 6 configureHeadlessProperty () . 7 SpringApplicationRunListeners 리스너 = getRunListeners (인수) // 됨 블로그 위에 배치하기 spring.factories 청취자 8 // 여기 관찰자 모드 시작, listeners.starting은 () . (9) 은 try { 10 ApplicationArguments의 applicationArguments = 새로운 새 DefaultApplicationArguments (인수) . 11 ConfigurableEnvironment 환경 = prepareEnvironment (리스너, applicationArguments는) // 환경 정보 실행 준비 되어 12 configureIgnoreBeanInfo (환경); // 구성 무시 13 인 배너 printedBanner = printBanner (환경); 14 문맥 = createApplicationContext (); // 문맥을 생성 (15) . exceptionReporters을 getSpringFactoriesInstances = (SpringBootExceptionReporter 클래스 , 16 새로운 새클래스 [{ConfigurableApplicationContext. 클래스 } 컨텍스트) . 17 prepareContext (문맥, 환경은 청취자 applicationArguments, printedBanner) // 문맥을 제조 18 인 refreshContext (컨텍스트) // 리프레시 컨텍스트 . 19 AfterRefresh (컨텍스트 applicationArguments) (20)는 스톱워치 .stop (); (21)는 IF ( 이 본 .logStartupInfo) { 22는 새로운 신규 StartupInfoLogger ( 이 본 ; .mainApplicationClass) .logStarted (getApplicationLog (), 스톱워치) 23이다 } 24 listeners.started (컨텍스트) // 컨텍스트 시작 25 callRunners (문맥, applicationArguments가) 모든 스레드가 시작이 실행 통지 // (26)이다 } 27 캐치 (Throwable의 EX를) { 28 handleRunFailure (문맥, EX, exceptionReporters, 리스너) 29 던져 새로운 새로운 IllegalStateException이 (EX), 30 } (31)은 (32) 은 try { 33가된다 (컨텍스트) listeners.running // 실행 34 } 35 캐치 (Throwable의 EX)를 { 36 handleRunFailure (문맥, EX, exceptionReporters, 널 ) 37 드로 새로운 새IllegalStateException이 (예); 38 } 39 리턴 컨텍스트; 40 }
위의 코드는, () listeners.starting, 여덟 번째 행에 대한 이야기에 초점을, 많은 내장이 줄 뒤에 코드와 유사한 코드를 실행하기 때문에
보이드 시작 () { 대 (SpringApplicationRunListener 리스너 : 이 .listeners) { ) (listener.starting; } }
1 공용 무효 시작 () { 2 이 .initialMulticaster.multicastEvent ( 새로운 ApplicationStartingEvent ( 이 .application, 이 .args)); 3 }
initialMulticaster 멀티 채널 방송인. 모든 청취자에게 통지, 방송이 실행됩니다 받았다. 다음과 같이 multicastEvent 코드는
공공 무효 multicastEvent (최종가 ApplicationEvent 이벤트, @Nullable ResolvableType 이벤트 유형) {
ResolvableType 유형 = (이벤트 유형 = null의 이벤트 유형 :!? resolveDefaultEventType (이벤트));
실행기 실행기 getTaskExecutor = ();
대 (만약 ApplicationListener 리스너 <?> getApplicationListeners (이벤트 유형)) {
경우 (! 실행기 = NULL) {
executor.execute (() -> invokeListener (청취자 이벤트));
}
다른 {
invokeListener (리스너, 이벤트);
}
}
}
다음은 invokeListener를 입력
(1) 개인 무효 doInvokeListener (만약 ApplicationListener 리스너가 ApplicationEvent 이벤트) { 2 시도 { 3 listener.onApplicationEvent (이벤트); //划重点 4 } 5 캐치 (ClassCastException이 예) { 6 문자열 MSG = ex.getMessage (); (7) 경우 (MSG == null의 || matchesClassCastMessage (MSG, event.getClass ())) { 8 // 우리가 일반 이벤트 유형을 확인할 수 없습니다 아마도 람다 정의 리스너 9 // ->하자가 예외를 억제하고 단지 디버그 메시지를 기록합니다. 10 로그인 로거 = LogFactory.getLog (getClass ()); 11 의 경우 (logger.isTraceEnabled ()) { 12 logger.trace ( "리스너 비 매칭 이벤트 유형"+ 수신기, 예); 13 } 14 } 15 다른 { 16 던져 예; 17 } 18 } 19 }
listener.onApplicationEvent (이벤트)이 동작을 구현하는 방법 onApplicationEvent 방법 org.springframework.context.ApplicationListener 클래스.
여러 장소, 방송 및 모니터링 메커니즘을 구성 청취자의 자유에 사용 된 전체 프레임 워크. 개별 구성 요소 및 구성 자신의 청취자는, 자유의 확장의 목적을 달성하기 위해.