そして、次のように春イベントリスナクラス図は:
ここで、java.utilのからのEventListenerとEVENTOBJECT
例
1、イベントを定義
パブリック クラス OrderEvent 延びApplicationEvent { / ** *イベントを作成するため * @paramのソース * / パブリックOrderEvent(オブジェクトソース){ スーパー(ソース); } }
2、イベントをリッスン
/ ** *イベントがOrderEventの関係、ばねが来る * / @Component パブリック クラス SmsListenerに器具を ApplicationListener <OrderEvent> { 公共 ボイドonApplicationEvent(OrderEventイベント){ するSystem.out.println( "SMSを実行" ); } }
3、事件がリリース
@Component パブリック クラスOrderServiceの{ @Resource のApplicationContextのApplicationContext; 公共 無効saveOrder(){ System.out.printlnはは( "注文が正常に保存" ); // 実行リリース[継承:ApplicationEvent} / ** 一般的なイベント: * ApplicationContextEvent、RequestHandledEvent、 ServletRequestHandledEvent、PayloadApplicationEvent * * ApplicationContextEvent 4つの親 ContextStartedEventライフサイクル開始* *のContextRefreshedEventリフレッシュ完了 * ContextClosedEventのライフサイクルが閉じ * ContextStoppedEventのライフサイクル停止 * / OrderEvent orderEvent = 新 OrderEvent( "" ); applicationContext.publishEvent(orderEvent)。 } }
publishEvent分析法でAbstractApplicationContext:
公共 ボイドpublishEvent(ApplicationEventイベント){ publishEvent(イベント、NULL ); } 公共 ボイドpublishEvent(オブジェクトイベント){ publishEvent(イベント、NULL ); } 保護された ボイドpublishEventを(オブジェクト・イベント、@Nullable ResolvableTypeのeventType){ // 必要に応じてApplicationEventとしてイベントを飾る ApplicationEvent applicationEvent。 もし(イベントのinstanceof ApplicationEvent){ applicationEvent = (ApplicationEvent)イベント。 } 他{ applicationEvent = 新しい PayloadApplicationEvent <>(このイベント)。// PayloadApplicationEvent的父类为ApplicationEvent 場合(eventTypeを== NULL ){ のeventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType(); } } // マルチキャストは今、可能であれば-レイジーまたはマルチキャスタが初期化された後 であれば(この .earlyApplicationEvents =!ヌル){//設定<ApplicationEvent> earlyApplicationEvents この.earlyApplicationEvents.add(applicationEvent)。 } 他 { getApplicationEventMulticaster()multicastEvent(applicationEvent、eventTypeを)。 } // ならびに親コンテキストを介してイベントを公開... 場合(この!.parent = NULL ){ 場合(この .parent instanceofのAbstractApplicationContext){ ((AbstractApplicationContext)この.parent).publishEvent(イベントのeventType)。 } 他{ この.parent.publishEvent(イベント)。 } } }
マルチキャストイベントAbstractApplicationContext.refresh()内のコンテキストの初期化:
@Override 公共 ボイドリフレッシュ()スローBeansExceptionは、IllegalStateException { 同期(この.startupShutdownMonitorが){ // さわやかなため、このコンテキストを準備します。 prepareRefresh(); // 内部ビーンファクトリをリフレッシュするためにサブクラスを教えてください。 ConfigurableListableBeanFactoryたBeanFactory = obtainFreshBeanFactory()。 // このコンテキストで使用するために豆の工場を準備します。 prepareBeanFactory(たBeanFactory)。 試す{ //は、コンテキストサブクラスでビーンファクトリの後処理を可能にします。 postProcessBeanFactory(たBeanFactory)。 // コンテキスト内でBeanとして登録された工場出荷時のプロセッサを起動します。 invokeBeanFactoryPostProcessors(たBeanFactory)。 // 豆の作成を傍受豆のプロセッサを登録します。 registerBeanPostProcessors(たBeanFactory)。 // このコンテキストのメッセージソースを初期化します。 initMessageSource(); // このコンテキストのイベントマルチキャスタを初期化します。 initApplicationEventMulticaster(); //は、特定のコンテキストのサブクラス中の他の特別な豆を初期化します。 onRefresh(); // リスナー豆をチェックし、それらを登録します。 registerListeners(); // すべての残りの(非レイジーINIT)シングルトンのインスタンスを生成します。 finishBeanFactoryInitialization(たBeanFactory)。 // 最後のステップ:対応するイベントを公開します。 finishRefresh(); } キャッチ(BeansExceptionのEX){ 場合(logger.isWarnEnabled()){ logger.warn( "例外コンテキスト初期化中に遭遇- " + "キャンセルリフレッシュ試行:" + EX)。 } // 既にリソースをダングリングを避けるためにシングルトンを作成し破壊します。 destroyBeans(); // 「アクティブ」フラグをリセットします。 cancelRefresh(EX); // 呼び出し元に例外を伝播します。 スローEXを。 } 最後に{ // 私たちは以来、Springのコアに共通のイントロスペクションキャッシュをリセット //がこれまでに...もうシングルトンBeanのメタデータを必要としない場合があります resetCommonCaches(); } } } / ** * ApplicationEventMulticasterを初期化します。 どれもコンテキストで定義されていない場合* SimpleApplicationEventMulticasterを使用します。 * @seeorg.springframework.context.event.SimpleApplicationEventMulticaster * / 保護された ボイドinitApplicationEventMulticaster(){ ConfigurableListableBeanFactoryたBeanFactory = getBeanFactory()。 もし(beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)){ この .applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME、ApplicationEventMulticaster。クラス)。 もし(logger.isTraceEnabled()){ logger.trace( + "ApplicationEventMulticaster [使用方法" この.applicationEventMulticaster + "]" )。 } } 他{ この .applicationEventMulticaster = 新しいSimpleApplicationEventMulticaster(たBeanFactory)。 beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME、この.applicationEventMulticaster)。 もし(logger.isTraceEnabled()){ logger.trace( "いいえ'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'豆、使用" + "[" + この .applicationEventMulticaster.getClass()getSimpleName()+ "]"を)。
AbstractApplicationContextがSimpleApplicationEventMulticasterにapplicationEventMulticasterを初期化された後、リスナーに対してブロードキャストApplicationContextのイベントを開始しました。
@Override 公共 のボイド multicastEvent(最終ApplicationEventイベント、@Nullable ResolvableType eventTypeを){ ResolvableTypeタイプ =(eventTypeを=!ヌル?のeventType:resolveDefaultEventType(イベント)); 以下のための(最終的な <?> ApplicationListener リスナー:getApplicationListeners(イベントタイプ)){ エグゼキュータ = getTaskExecutor()。 もし(エグゼキュータ!= NULL ){ てexecutor.execute(() - > invokeListener(リスナー、イベント))。 } 他{ invokeListener(リスナー、イベント); } } } / ** *指定されたイベントで与えられたリスナーを起動します。 * @paramのリスナーApplicationListenerを呼び出す * @paramを伝播するイベントを現在のイベント * @since 4.1 * / 保護された ボイド invokeListener(ApplicationListener <?> リスナー、ApplicationEventイベント){ のErrorHandlerのErrorHandler = getErrorHandler()。 場合(のErrorHandler!= nullの){ しようと{ doInvokeListener(リスナー、イベント); } キャッチ(ThrowableのERR){ errorHandler.handleError(ERR)。 } } 他{ doInvokeListener(リスナー、イベント)。 } } @SuppressWarnings({ "未チェック"、 "rawtypes" }) プライベート ボイドdoInvokeListener(ApplicationListenerリスナー、ApplicationEventイベント){ 試み{ listener.onApplicationEvent(イベント)。 } キャッチ(れるClassCastException EX){ 文字列MSG =ex.getMessage(); 場合(msgが== nullの || matchesClassCastMessageは(MSG、event.getClassは())){ // 我々は、一般的なイベントタイプを解決できませんでしたおそらくラムダ定義のリスナー // - >は、のが例外を抑制してみましょうし、ちょうどログインデバッグメッセージ。 ログロガー= LogFactory.getLog(のgetClass())。 もし(logger.isDebugEnabled()){ logger.debug( "リスナーのための非マッチング・イベント・タイプ:" + リスナー、EX)。 } } 他{ スローEXと、 } } }