优势
解耦对同一种事件有多种处理方式
不干扰主线(main line)
起源
要讲spring的事件通知机制,就要先了解一下spring中的这些接口和抽象类:
ApplicationEventPublisherAware 接口:用来 publish eventApplicationEvent 抽象类,记录了source和初始化时间戳:用来定义Event
ApplicationListener<E extends ApplicationEvent> :用来监听事件
构建自己的事件机制案例
测试案例
测试入口
package com.meituan.spring.testcase.listener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.TimeUnit;
/*** Created by zhangxiaoguang on 16/1/27 下午11:40.
* -----------------------------
* Desc:
*/
public class TestPortal {
public static void main(String[] args) throws InterruptedException {
final ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
String[] definitionNames = applicationContext.getBeanDefinitionNames();System.out.println("==============bean====start=================");
for (String definitionName : definitionNames) {
System.out.println("bean----:" + definitionName);
}
System.out.println("==============bean====end=================");
System.out.println();
final CustomizePublisher customizePublisher = applicationContext.getBean(CustomizePublisher.class);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("开始吃饭:");
MealEvent lunchEvent = new MealEvent("A吃午饭了", MealEnum.lunch);
MealEvent breakfastEvent = new MealEvent("B吃早饭了", MealEnum.breakfast);
MealEvent dinnerEvent = new MealEvent("C吃晚饭了", MealEnum.dinner);
customizePublisher.publish(lunchEvent);
TimeUnit.SECONDS.sleep(1l);
customizePublisher.publish(breakfastEvent);
TimeUnit.SECONDS.sleep(1l);
customizePublisher.publish(dinnerEvent);
TimeUnit.SECONDS.sleep(1l);
System.out.println("他们吃完了!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.setName("meal-thread");
thread.start();
System.out.println(Thread.currentThread().getName() + " is waiting for ....");
thread.join();
System.out.println("Done!!!!!!!!!!!!");
}
}
TestPortal
测试结果

测试成员
MealListener :MealEvent 演员
TroubleListener:TroubleEvent 演员
AllAcceptedListener 演员
MealEnum 道具
TestPortal 入口
CustomizePublisher 导演
成员代码
接受全部事件的演员(很负责任啊)
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* Created by zhangxiaoguang on 16/1/27 下午11:27.
* -----------------------------
* Desc:
*/
@Component
public class AllAcceptedListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println(">>>>>>>>>>>>>>>>event:" + event);
}
}
AllAcceptedListener
导演负责分发事件
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationEventPublisher;import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
/**
* Created by zhangxiaoguang on 16/1/28 上午1:41.
* -----------------------------
* Desc:
*/
@Component
public class CustomizePublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
public void publish(MealEvent event) {applicationEventPublisher.publishEvent(event);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}
CustomizePublisher
负责处理吃饭事件的演员
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;
/**
* Created by zhangxiaoguang on 16/1/27 下午11:27.
* -----------------------------
* Desc:
*/
@Component
public class MealListener implements ApplicationListener<MealEvent> {
@Override
public void onApplicationEvent(MealEvent event) {
System.out.println(String.format(">>>>>>>>>>>thread:%s,type:%s,event:%s",
Thread.currentThread().getName(), event.getMealEnum(), event));
dispatchEvent(event);
}
private void dispatchEvent(MealEvent event) {
switch (event.getMealEnum()) {
case breakfast:
System.out.println(event.getMealEnum() + " to handle!!!");
break;
case lunch:
System.out.println(event.getMealEnum() + " to handle!!!");
break;
case dinner:
System.out.println(event.getMealEnum() + " to handle!!!");
break;
default:
System.out.println(event.getMealEnum() + " error!!!");
break;
}
}
}
MealListener
吃饭消息
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationEvent;
/*** Created by zhangxiaoguang on 16/1/27 下午11:24.
* -----------------------------
* Desc:吃饭事件
*/
public class MealEvent extends ApplicationEvent {
private MealEnum mealEnum;
/*** @param mealContent
* 吃什么
* @param mealEnum
* 早餐还是午餐?
*/
public MealEvent(String mealContent, MealEnum mealEnum) {
super(mealContent);
this.mealEnum = mealEnum;
}
public MealEnum getMealEnum() {
return mealEnum;
}
}
MealEvent
工具
package com.meituan.spring.testcase.listener;
/*** Created by zhangxiaoguang on 16/1/27 下午11:29.
* -----------------------------
* Desc:
*/
public enum MealEnum {
breakfast,
lunch,
dinner
}
MealEnum
令人厌烦的演员
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;
/**
* Created by zhangxiaoguang on 16/1/27 下午11:27.
* -----------------------------
* Desc:
*/
@Component
public class TroubleListener implements ApplicationListener<TroubleEvent> {
@Override
public void onApplicationEvent(TroubleEvent event) {
System.out.println(">>>>>>>>>>>>>>>>event:" + event);
}
}
TroubleListener
令人厌烦的事件
package com.meituan.spring.testcase.listener;
import org.springframework.context.ApplicationEvent;
/*** Created by zhangxiaoguang on 16/1/27 下午11:24.
* -----------------------------
* Desc:令人厌烦的事件
*/
public class TroubleEvent extends ApplicationEvent {
public TroubleEvent(Object source) {
super(source);
}
}
TroubleEvent
总结
详细定制 event 类型的,则相关定制的listener会处理对应的消息,其他listener不会管闲事;
制定顶级 event 类型的,ApplicationEvent的,则会处理所有的事。
Spring中如何配置Hibernate事务 http://www.linuxidc.com/Linux/2013-12/93681.htm
Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm
基于 Spring 设计并实现 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm
Spring-3.2.4 + Quartz-2.2.0集成实例 http://www.linuxidc.com/Linux/2013-10/91524.htm
使用 Spring 进行单元测试 http://www.linuxidc.com/Linux/2013-09/89913.htm
运用Spring注解实现Netty服务器端UDP应用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm
Spring 3.x 企业应用开发实战 PDF完整高清扫描版+源代码 http://www.linuxidc.com/Linux/2013-10/91357.htm
更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2016-03/129001p2.htm
