您的位置:首页 > 其它

业务事件模型的实现

2016-03-20 17:13 337 查看
  在实际业务开发过程中,很经常应用到观察者模式。大致的处理流程是说在模块初始化的时候,注册若干观察者,然后它们处理自己感兴趣的内容。当某一个具体的事件发生的时候,遍历观察者队列,然后”观察者“们就根据之前约定的具体情况,处理自己关注的事件。其实观察者模式本人认为更确切的说法应该是:事件通知模型。那么现在,我们就用传统的Java语言来实现一下(具体可以查看代码的注释,写的挺详细了)。

  业务事件定义如下:

/**
* @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;
}

}


  接着就是业务事件监听器的定义了

/**
* @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);
}

}


  再来一个事件的发送者,来负责事件的派发

/**
* @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() + "]");
}

}


  好了,全部的框架都完成了,那现在我们把上述模块完整的调用起来。

/**
* @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框架来模拟一下事件模型是如何更优雅的应用的。

  在Spring里面,所有事件的基类是ApplicationEvent,那我们从这个类派生一下,重新定义一下我们的业务事件。代码如下

/**
* @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;
}
}


  同样的,事件的发送者也要进行一下调整,代码如下

/**
* @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"));
}
}


  运行的结果如下,非常完美,不是么?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: