Springイベントメカニズム


Javaはイベントメカニズムを提供し、springを使用する場合、通常のjavaイベント操作をbeanとしてbeanコンテナに統合することができますが、springが統合されたイベントサポートを使用するより便利な方法があります.
Springのイベントサポートを使用する場合は、次のオブジェクトに注目する必要があります.
      1.ApplicationEvent:EventObjectから継承され、springのアプリケーション内のイベントの親であり、カスタムイベントに継承される必要があります.
      2.ApplicationListener:EventListener、springのアプリケーションのリスナーが実現しなければならないインタフェースを継承し、カスタムのリスナーがそのonApplicationEventメソッドを実現する必要がある
      3.A p p r i c ationEventPublisherAware:springのcontextでイベントをパブリッシュできるクラスを実装するために必要なインタフェースです.このインタフェースには、ApplicationEventPublisherを設定する方法が定義されており、ApplicationContextによって呼び出されて設定されています.自分で実装したアプリケーションEventPublisherAwareサブクラスでは、アプリケーションEventPublisherプロパティの定義が必要です.
      4.ApplicationEventPublisher:springのイベントパブリッシャインタフェースで、イベントをパブリッシュするインタフェースメソッドpublishEventを定義します.このインタフェースはApplicationContextによって実装されるため、springのApplicationContextインスタンスはイベントをパブリッシュする機能を有する(publishEventメソッドはAbstractApplicationContextで実装される).使用する場合、アプリケーションEventPublisherの参照をアプリケーションEventPublisherの実装に定義するだけで、springコンテナはアプリケーションEventPublisherへの注入を完了します.
Springのbean構成では、イベントはイベントソースによって発行されるため、beanがspringコンテナによって管理されるように登録する必要はありません.したがってspringの構成では、カスタマイズされたApplicationEventListenerとpublisherAware(すなわち、アプリケーションEventPublisherAwareインタフェースを実装したパブリケーションクラス)を構成するだけで、ApplicationEventPublisherの管理と注入はコンテナによって行われます.
スプリングベースのイベントは、以下のように簡単に実現されます.
1.アプリケーションイベントの定義
package com.nuc.event;

import org.springframework.context.ApplicationEvent;
/**
 *   Spring      , java         ,           , 
 *             ,  ApplicationEvent     EventObject 。
 */
public class MethodExecutionEvent extends ApplicationEvent {

    private static final long serialVersionUID = 2565706247851725694L;
    private String methodName;
    private MethodExecutionStatus methodExecutionStatus;
    
    public MethodExecutionEvent(Object source) {
        super(source);
    }
    
    public MethodExecutionEvent(Object source, String methodName, MethodExecutionStatus methodExecutionStatus) {
        super(source);
        this.methodName = methodName;
        this.methodExecutionStatus = methodExecutionStatus;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public MethodExecutionStatus getMethodExecutionStatus() {
        return methodExecutionStatus;
    }

    public void setMethodExecutionStatus(MethodExecutionStatus methodExecutionStatus) {
        this.methodExecutionStatus = methodExecutionStatus;
    }
}

2.アプリケーションEventListenerの定義
package com.nuc.listener;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;
/**
 * Spring         , java              ,      ApplicationListener  
 * ApplicationListener       EventListener,    EventListener
 *           onApplicationEvent     ,   EventListener        。
 */

public class MethodExecutionEventListener implements ApplicationListener {

    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof MethodExecutionEvent) {
           if (MethodExecutionStatus.BEGIN
                    .equals(((MethodExecutionEvent) event)
                            .getMethodExecutionStatus())) {
                System.out.println("It's beginning");
            }
            if (MethodExecutionStatus.END.equals(((MethodExecutionEvent) event).getMethodExecutionStatus())) {
                System.out.println("It's ending");
            }
        }
    }
}

3.アプリケーションEventPublisherAwareの定義
package com.nuc.publisher;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

import com.nuc.event.MethodExecutionEvent;
import com.nuc.event.MethodExecutionStatus;

public class MethodExecutionEventPublisher implements
        ApplicationEventPublisherAware {

    private ApplicationEventPublisher eventPublisher;
    
    public void methodToMonitor() {
        MethodExecutionEvent beginEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.BEGIN);
        this.eventPublisher.publishEvent(beginEvent);
        //TODO
        MethodExecutionEvent endEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.END);
        this.eventPublisher.publishEvent(endEvent);
    }
    
    public void setApplicationEventPublisher(
            ApplicationEventPublisher applicationEventPublisher) {
        this.eventPublisher = applicationEventPublisher;
    }
}

4.bean構成の定義
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
	default-autowire="byName">
	<bean id="methodExecListener" class="com.nuc.listener.MethodExecutionEventListener"></bean>
	<bean id="evtPublisher" class="com.nuc.publisher.MethodExecutionEventPublisher"></bean>	
</beans>

5.イベントの使用
package com.nuc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.nuc.publisher.MethodExecutionEventPublisher;

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        MethodExecutionEventPublisher publisher = (MethodExecutionEventPublisher)context.getBean("evtPublisher");
        publisher.methodToMonitor();
    }
}

インプリメンテーションから、基本的なjavaイベントを使用するプロセスとほぼ一致し、ここではカスタムパブリッシャーを必要とせず、springインプリメンテーションを使用して提供されるイベントパブリケーションインプリメンテーションを実装するのとは異なります.もちろん、ここではアプリケーションEventPublisherAwareを導入しています.