博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring学习笔记(16)趣谈spring 事件机制[2]:多监听器流水线式顺序处理
阅读量:6209 次
发布时间:2019-06-21

本文共 4420 字,大约阅读时间需要 14 分钟。

上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条作业调度流水线,它不能异步,必须按照先后次序执行不同的任务才能得到我们的最终结果。

需求示例:现在假如华中科技大学的小白想要为它的智能机器人作品申报国家创新奖,需要经过学校、省级创新科研机构、国家创新科研机构逐层审核。我们尝试通过事件来实现,核心就在监听器实现SmartApplicationListener接口。示例如下:

1. 配置事件发布者小白:

public class XiaoBai implements ApplicationContextAware {
private ApplicationContext applicationContext;//底层事件发布者 public void reportWorks(){
//申报作品 AuditEvent auditEvent = new AuditEvent(this); applicationContext.publishEvent(auditEvent); //小白获取期待已久的最终结果 System.out.println("最终审核结果:" + auditEvent.getStatus() + "——" + auditEvent.getAdvice()); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; }}

关于上述配置可参考我的上一篇文章

2. 配置审核事件源

public class AuditEvent extends ApplicationEvent {
private Boolean status ; //当前申报状态 private String work;//申报作品 private String advice;//当前申报意见 public AuditEvent(Object source) { super(source); status = true;//初始窗台 advice = "尚未审核"; } //ignore getter and setter }

3. 配置事件监听器

我们实现需求的核心部分来了,先上代码

/******************学校审核监听器******************/public class SchoolListener implements  SmartApplicationListener  {
@Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice()); ((AuditEvent)event).setStatus(true); ((AuditEvent)event).setAdvice("学校审核意见:有创意,非常棒!"); } @Override public int getOrder() { return 1;//获取学校监听(审核)的优先级 } @Override//这是我们的监听器智能所在之一,能够根据事件类型动态监听 public boolean supportsEventType(Class
eventType) { return eventType == AuditEvent.class; } @Override//这是我们的监听器智能所在之二,能够根据事件发布者类型动态监听 public boolean supportsSourceType(Class
sourceType) { return sourceType == XiaoBai.class; }}/******************省级审核监听器******************/public class ProvinceListener implements SmartApplicationListener {
@Override public void onApplicationEvent(ApplicationEvent event) { if(((AuditEvent)event).getStatus()){
//如果上层审核通过 System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice()); ((AuditEvent)event).setStatus(true); ((AuditEvent)event).setAdvice("省级审核意见:还行,通过吧!"); } } @Override public int getOrder() { return 2; } @Override public boolean supportsEventType(Class
eventType) { return eventType == AuditEvent.class; } @Override public boolean supportsSourceType(Class
sourceType) { return sourceType == XiaoBai.class; }}/******************国家级审核监听器******************/public class CountryListener implements SmartApplicationListener {
@Override public void onApplicationEvent(ApplicationEvent event) { if(((AuditEvent)event).getStatus()){
//如果上层审核通过 System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice()); ((AuditEvent)event).setStatus(true); ((AuditEvent)event).setAdvice("国家审核意见:一般般,勉强通过吧!"); } } @Override public int getOrder() { return 3; } @Override public boolean supportsEventType(Class
eventType) { return eventType == AuditEvent.class; } @Override public boolean supportsSourceType(Class
sourceType) { return sourceType == XiaoBai.class; }}

在这里,我们的实例为了方便演示而简化配置。我们的发布源支持类型是小白,根据更实际的需求,我们可以让小白继承Student类,然后让sourceType只要是Student的子类即可,这样就能满足任何继承了Student的学生都能申报了。

在实现了SmartApplicationListener的监听器中,我们通过重写GetOrder方法来修改不同监听器的顺序,优先级越小,则越先被调用。通过配置不同的优先级,且让监听器之间阻塞调用。我们就能实现流水线式的有序事件调用,这在实际应用场景中还是蛮有意义的

5. 在IOC容器中注册监听器

6. 测试方法

public class MainTest {
public static void main(String args[]) throws InterruptedException{ ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:test/event2/event.xml"); XiaoBai xiaobai = (XiaoBai) ac.getBean("xiaoBai"); xiaobai.reportWorks();//小白要开始申报项目啦 }}

调用测试代码,我们得到运行结果:

获取当前的申报状态为:true——尚未审核
获取当前的申报状态为:true——学校审核意见:有创意,非常棒!
获取当前的申报状态为:true——省级审核意见:还行,通过吧!
最终审核结果:true——国家审核意见:一般般,勉强通过吧!

于是,小白的作品终于评上了国家创新科技奖了,这让他高兴了好一阵子。

源码下载

本实例源码可到我的github仓库下的event2文件夹下载

转载地址:http://yakja.baihongyu.com/

你可能感兴趣的文章
IIS应用程序池_缓存回收
查看>>
gradle 将依赖打入Jar包的方法
查看>>
phantomjs - node.js parse child process output line by line (spawn) - Stack Overflow
查看>>
Android网络通信Volley框架源代码浅析(三)
查看>>
iphone label相关的圆角处理(转)
查看>>
史上最笨拙最丑陋结果又最滑稽的C代码
查看>>
HDUOJ1002A + B Problem II
查看>>
svn: “sqlite: attempt to write a readonly database”
查看>>
仅在TabControl中的Tab中添加右键菜单
查看>>
javascript如何从tr中分别获得每个td的元素
查看>>
设计模式(一)工厂模式Factory(创建型)
查看>>
DIOCP 运作核心探密
查看>>
天津人民优步司机当周奖励政策 (8.3-8.9)
查看>>
POJ2481让人无语
查看>>
&和&&的区别
查看>>
oracle用户管理的完全恢复6:控制文件损坏(控制文件前后内容改变)
查看>>
Android之Widget
查看>>
跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
查看>>
vb.net中让控件内容为空(Control类)
查看>>
编程之美 set 9 字符串移位包含问题
查看>>