学习使用java编写简单的同步事件处理器

核心代码:

/**
* 事件基类,保存事件相关数据的值对象。
*/
public abstract class Event {

/** 发送事件时间 */
protected Date fireTime;

public Date getFireTime() {
return fireTime;
}

public void setFireTime(Date fireTime) {
this.fireTime = fireTime;
}
}



/**
* 事件监听器,每个监听器绑定特定事件,该事件由泛型指定。
*
* @param
* 特定事件
*/
public abstract class EventListener {

/** 该监听器是否触发一次即注销,默认为否 */
protected boolean runOnce = false;

/**
* 处理事件,由继承类实现。
*
* @param event
* 事件类型,则事件监听器的泛型
* @return 返回true则事件继续触发下一个事件监听器,否则终止事件
*/
public abstract Boolean execute(T event);

public boolean isRunOnce() {
return runOnce;
}

public EventListener runOnce(boolean runOnce) {
this.runOnce = runOnce;
return this;
}

/**
* 通过反射,继承类可以获取泛型事件参数的类型。
*
* @return 泛型事件参数类型
*/
@SuppressWarnings("unchecked")
public Class getEventClass() {
return GenericUtils.getSuperClassGenericType(this.getClass());
}

/**
* 注册事件监听器的快捷方式。
*/
public void register() {
EventManager.register(this);
}

/**
* 注销事件监听器的快捷方式。
*/
public void unre1gister() {
EventManager.unregister(this);
}

}


/**
* 事件管理器,提供静态方法用于注册、注销和发送事件。
*/
public class EventManager {

private static Logger logger = LoggerFactory.getLogger(EventManager.class);

/** 事件类型 - 事件监听器实体映射 */
/** 使用guava包的多值不重复map保存 */
private static Multimap, EventListener> eventHook = Multimaps
.synchronizedMultimap(LinkedHashMultimap
., EventListener> create());

/**
* 注册事件。
*
* @param listener
* 事件监听器
*/
public static void register(EventListener listener) {
Class eventClass = listener.getEventClass();
eventHook.put(eventClass, listener);
if (logger.isDebugEnabled()) {
logger.debug("事件监听器 '" + listener.getClass().getSimpleName()
+ "' 注册事件 '" + eventClass.getSimpleName() + "'");
}
}

/**
* 注销事件。
*
* @param listener
* 事件监听器
*/
public static void unregister(EventListener listener) {
Class eventClass = listener.getEventClass();
eventHook.remove(eventClass, listener);
if (logger.isDebugEnabled()) {
logger.debug("事件监听器 '" + listener.getClass().getSimpleName()
+ "' 注销事件 '" + eventClass.getSimpleName() + "'");
}
}

/**
* 发送特定事件。
*
* @param event
* 事件实体
* @throws Exception
* 反射异常
*/
public static void fire(Event event) throws Exception {
event.setFireTime(new Date());// 记录发送事件时间
Class eventClass = event.getClass();
Collection> listeners = eventHook
.get(eventClass);
if (logger.isDebugEnabled()) {
logger.debug("事件 '" + eventClass.getSimpleName() + "' 监听器数目: "
+ listeners.size());
}
for (Iterator> iterator = listeners
.iterator(); iterator.hasNext();) {// 遍历所有注册该事件的事件监听器
EventListener listener = iterator.next();
// 因为每个事件监听器的execute方法参数由泛型指定
// 所以要通过反射,将事件实体注入并执行事件监听器的execute方法
Method execute = listener.getClass().getMethod("execute",
eventClass);
boolean stop = !(Boolean) execute.invoke(listener, event);
if (logger.isDebugEnabled()) {
logger.debug("事件 '" + eventClass.getSimpleName()
+ "' 触发事件监听器 '" + listener.getClass().getSimpleName()
+ "'");
}
if (listener.isRunOnce()) {
iterator.remove();
if (logger.isDebugEnabled()) {
logger.debug("移除事件监听器 '"
+ listener.getClass().getSimpleName() + "'");
}
}
if (stop) {
if (logger.isDebugEnabled()) {
logger.debug("事件 '" + eventClass.getSimpleName()
+ "' 被事件监听器 '"
+ listener.getClass().getSimpleName() + "' 终止");
}
break;
}
}
}
}


Demo主要代码:

public class FinishTaskEvent extends TaskEvent {

public FinishTaskEvent(Task task) {
this.task = task;
}
}


@Component
public class FinishTaskEventWorkflowHandler extends
EventListener {

@Override
public Boolean execute(FinishTaskEvent event) {
event.getTask().setFinished(true);
return true;
}

}


@Component
public class FinishTaskEventHistoryLogger extends
EventListener {

@Autowired
HistoryRepository historyRepository;

@Override
public Boolean execute(FinishTaskEvent event) {
String taskName = event.getTask().getName();
String assignee = event.getTask().getAssignee();
historyRepository
.addHistory(("用户 '" + assignee + "' 完成任务: " + taskName));
return true;
}
}


单元测试:

@ContextConfiguration("classpath:/applicationContext.xml")
public class EventTest extends AbstractJUnit4SpringContextTests {

@Autowired
private FinishTaskEventWorkflowHandler finishTaskEventWorkflowHandler;
@Autowired
private FinishTaskEventHistoryLogger finishTaskEventHistoryLogger;
@Autowired
private HistoryRepository historyRepository;

@Before
public void setUp() {
EventManager.register(finishTaskEventHistoryLogger);
EventManager.register(finishTaskEventWorkflowHandler);
}

@After
public void tearDown() {
EventManager.unregister(finishTaskEventHistoryLogger);
EventManager.unregister(finishTaskEventWorkflowHandler);
}

@Test
public void testFinishTaskEvent() throws Exception {
Task task1 = new Task("任务1", "用户A");
EventManager.fire(new FinishTaskEvent(task1));
Assert.assertTrue(task1.isFinished());

Task task2 = new Task("任务2", "用户B");
EventManager.fire(new FinishTaskEvent(task2));
Assert.assertTrue(task2.isFinished());

String[] actuals = historyRepository.getHistories().toArray(
new String[2]);
String[] expecteds = new String[] { "用户 '用户A' 完成任务: 任务1",
"用户 '用户B' 完成任务: 任务2" };
Assert.assertArrayEquals(expecteds, actuals);
}
}

你可能感兴趣的:(java,观察者模式,命令模式)