業務事件模型的實現

  在實際業務開發過程當中,很常常應用到觀察者模式。大體的處理流程是說在模塊初始化的時候,註冊若干觀察者,而後它們處理本身感興趣的內容。當某一個具體的事件發生的時候,遍歷觀察者隊列,而後」觀察者「們就根據以前約定的具體狀況,處理本身關注的事件。其實觀察者模式本人認爲更確切的說法應該是:事件通知模型。那麼如今,咱們就用傳統的Java語言來實現一下(具體能夠查看代碼的註釋,寫的挺詳細了)。java

  業務事件定義以下:spring

/**
 * @filename:BusinessEvent.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件定義
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

public class BusinessEvent {

    // 某種具體的業務事件的數據內容
    private Object businessData;

    // 某種具體的業務事件的事件類型
    private String businessEventType;

    public BusinessEvent(String businessEventType, Object businessData) {
        this.businessEventType = businessEventType;
        this.businessData = businessData;
    }

    public Object getBusinessData() {
        return this.businessData;
    }

    public String getBusinessEventType() {
        return this.businessEventType;
    }

}

  接着就是業務事件監聽器的定義了app

/**
 * @filename:BusinessEventListener.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件監聽器定義
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

public interface BusinessEventListener {
    
    //事件接口定義
    public void execute(BusinessEvent event);

}

  業務事件,總要有個管理者吧,那如今就實現一個框架

/**
 * @filename:BusinessEventManagement.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件管理器定義
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//業務事件管理器
public class BusinessEventManagement {

    private Map<String, List<BusinessEventListener>> map = new HashMap<String, List<BusinessEventListener>>();

    public BusinessEventManagement() {

    }

    // 註冊業務事件監聽器
    public boolean addBusinessEventListener(String BusinessEventType,BusinessEventListener listener) {
        List<BusinessEventListener> listeners = map.get(BusinessEventType);
        
        if (null == listeners) {
            listeners = new ArrayList<BusinessEventListener>();
        }
        
        boolean result = listeners.add(listener);
        
        map.put(BusinessEventType, listeners);
        
        return result;
    }

    // 移除業務事件監聽器
    public boolean removeBusinessEventListener(String BusinessEventType,BusinessEventListener listener) {
        List<BusinessEventListener> listeners = map.get(BusinessEventType);
if (null != listeners) { return listeners.remove(listener); } return false; } // 獲取業務事件監聽器隊列 public List<BusinessEventListener> getBusinessEventListeners(String BusinessEventType) { return map.get(BusinessEventType); } }

  再來一個事件的發送者,來負責事件的派發ide

/**
 * @filename:BusinessEventNotify.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件發送者
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

import java.util.List;

public class BusinessEventNotify {

    private BusinessEventManagement businessEventManagement;;

    public BusinessEventNotify(BusinessEventManagement businessEventManagement) {
        this.businessEventManagement = businessEventManagement;
    }

    // 事件派發
    public void notify(BusinessEvent BusinessEvent) {
        if (null == BusinessEvent) {
            return;
        }

        List<BusinessEventListener> listeners = businessEventManagement.getBusinessEventListeners(BusinessEvent.getBusinessEventType());

        if (null == listeners) {
            return;
        }

        for (BusinessEventListener listener : listeners) {
            listener.execute(BusinessEvent);
        }
    }
}

  關鍵的來了,下面能夠根據本身的業務規定,註冊若干個事件的監聽器。下面咱們就先註冊兩個監聽器,分別是短信監聽器、彩鈴監聽器,而後執行本身對「感興趣」事件進行的操做。函數

/**
 * @filename:SendSmsListener.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:短信消息監聽器
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

public class SendSmsListener implements BusinessEventListener {

    @Override
    public void execute(BusinessEvent event) {
        System.out.println("監聽器:" + this + "接收到業務事件,業務事件類型是["
                + event.getBusinessEventType() + "] ## 業務事件附帶的數據["
                + event.getBusinessData() + "]");
    }

}
/**
 * @filename:ColorRingListener.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:彩鈴消息監聽器
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

public class ColorRingListener implements BusinessEventListener {

    @Override
    public void execute(BusinessEvent event) {
        System.out.println("監聽器:" + this + "接收到業務事件,業務事件類型是["
                + event.getBusinessEventType() + "] ## 業務事件附帶的數據["
                + event.getBusinessData() + "]");
    }

}

  好了,所有的框架都完成了,那如今咱們把上述模塊完整的調用起來。this

/**
 * @filename:Main.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:主函數
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.businessevent;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        // 註冊監聽器
        BusinessEventManagement businessEventManagement = new BusinessEventManagement();
        
        businessEventManagement.addBusinessEventListener("彩鈴監聽器",new ColorRingListener());
        businessEventManagement.addBusinessEventListener("短信監聽器",new SendSmsListener());

        // 業務事件觸發
        BusinessEventNotify sender = new BusinessEventNotify(businessEventManagement);
        
        sender.notify(new BusinessEvent("彩鈴監聽器", "ReadBusinessEvent"));
        sender.notify(new BusinessEvent("短信監聽器", "WriteBusinessEvent"));
    }

}

  彩鈴監聽器感興趣的事件是讀事件(ReadBusinessEvent),短信監聽器感興趣的事件是寫事件(WriteBusinessEvent)。運行起來以後,發現果真組織的很好。固然有人會說,上面的狀況JDK裏面已經有現成的類(java.util.EventObject、java.util.EventListener)支持了。那下面咱們就根據上面的例子,利用Spring框架來模擬一下事件模型是如何更優雅的應用的。spa

  在Spring裏面,全部事件的基類是ApplicationEvent,那咱們從這個類派生一下,從新定義一下咱們的業務事件。代碼以下code

/**
 * @filename:BusinessEvent.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件定義
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.spring;

import org.springframework.context.ApplicationEvent;

public class BusinessEvent extends ApplicationEvent {
    
    // 某種具體的業務事件的數據內容
    private Object businessData;

    // 某種具體的業務事件的事件類型
    private String businessEventType;

    public BusinessEvent(String businessEventType, Object businessData) {
        super(businessEventType);

        this.businessEventType = businessEventType;
        this.businessData = businessData;
    }

    public Object getBusinessData() {
        return this.businessData;
    }

    public String getBusinessEventType() {
        return this.businessEventType;
    }
}

  一樣的,事件的發送者也要進行一下調整,代碼以下xml

/**
 * @filename:BusinessEventNotify.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:業務事件發送者
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.spring;

import java.util.List;

import newlandframework.spring.BusinessEvent;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class BusinessEventNotify implements ApplicationContextAware {

    private List<String> businessListenerList;
    
    private ApplicationContext ctx;

    public void setBusinessListenerList(List<String> businessListenerList) {
this.businessListenerList = businessListenerList; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.ctx = applicationContext; } public void notify(BusinessEvent businessEvent) { if (businessListenerList.contains(businessEvent.getBusinessEventType())) { BusinessEvent event = new BusinessEvent( businessEvent.getBusinessEventType(), businessEvent.getBusinessData()); ctx.publishEvent(event); return; } } }

  下面咱們就來註冊一下Spring方式的短信、彩鈴監聽器:

/**
 * @filename:SendSmsListener.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:短信消息監聽器
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.spring;

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

public class SendSmsListener implements ApplicationListener {
    
    final String strKey = "SMS";

    public void onApplicationEvent(ApplicationEvent event) {
        // 這裏你能夠截取感興趣的實際類型
        if (event instanceof BusinessEvent) {
            BusinessEvent businessEvent = (BusinessEvent) event;

            if (businessEvent.getBusinessEventType().toUpperCase().contains(strKey)) {
                System.out.println("監聽器:" + this + "接收到業務事件,業務事件類型是["
                        + businessEvent.getBusinessEventType()
                        + "] ## 業務事件附帶的數據[" + businessEvent.getBusinessData()
                        + "]");
            }
        }
    }
}
/**
 * @filename:ColorRingListener.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:彩鈴消息監聽器
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.spring;

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

public class ColorRingListener implements ApplicationListener {

    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof BusinessEvent) {
            BusinessEvent businessEvent = (BusinessEvent) event;
            System.out.println("監聽器:" + this + "接收到業務事件,業務事件類型是["
                    + businessEvent.getBusinessEventType() + "] ## 業務事件附帶的數據["
                    + businessEvent.getBusinessData() + "]");
        }
    }
}

  最後咱們編寫一下Spring的依賴注入的配置文件spring-event.xml,固然事件的監聽器也是在這裏面依賴注入實現自動裝配的。

<?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.5.xsd"
    default-autowire="byName">
    <bean id="smsListener" class="newlandframework.spring.SendSmsListener" />
    <bean id="ringListener" class="newlandframework.spring.ColorRingListener" />
    <bean id="event" class="newlandframework.spring.BusinessEventNotify">
        <property name="businessListenerList">
            <list>
                <value>DealColorRing</value>
                <value>DealSms</value>
            </list>
        </property>
    </bean>
</beans>

  一切準備就緒,如今咱們把上面Spring方式實現的事件模型,完整的串起來,代碼以下:

/**
 * @filename:Main.java
 *
 * Newland Co. Ltd. All rights reserved.
 * 
 * @Description:主函數
 * @author tangjie
 * @version 1.0
 * 
 */

package newlandframework.spring;

import newlandframework.spring.BusinessEvent;

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

public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("newlandframework/spring/spring-event.xml");

        BusinessEventNotify sender = (BusinessEventNotify) ctx.getBean("event");

        sender.notify(new BusinessEvent("DealColorRing", "ReadBusinessEvent"));
sender.notify(new BusinessEvent("DealSms", "ReadBusinessEvent")); } }

  運行的結果以下,很是完美,不是麼?

相關文章
相關標籤/搜索