spring学习笔记(16)趣谈spring 事件机制[2]:多监听器流水线式顺序处理

简介: <div class="markdown_views"><p>上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条<strong>作业调度流水线</strong>,它不能异步,必须按照先后次序执行不同的任务才能得到我们的最终结果。 <br>需求示例:现在假如华中科技大学的小白想

上一篇我们使用到的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;
    }
}

关于上述配置可参考我的上一篇文章《spring学习笔记(13)趣谈spring 事件:实现业务逻辑解耦,异步调用提升用户体验》

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<? extends ApplicationEvent> 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<? extends ApplicationEvent> 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<? extends ApplicationEvent> eventType) {
        return eventType == AuditEvent.class;
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return sourceType == XiaoBai.class;
    }

}

在这里,我们的实例为了方便演示而简化配置。我们的发布源支持类型是小白,根据更实际的需求,我们可以让小白继承Student类,然后让sourceType只要是Student的子类即可,这样就能满足任何继承了Student的学生都能申报了。
在实现了SmartApplicationListener的监听器中,我们通过重写GetOrder方法来修改不同监听器的顺序,优先级越小,则越先被调用。通过配置不同的优先级,且让监听器之间阻塞调用。我们就能实现流水线式的有序事件调用,这在实际应用场景中还是蛮有意义的

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

<bean id="schoolListener" class="test.event2.SchoolListener" />
<bean id="provinceListener" class="test.event2.ProvinceListener" />
<bean id="countryListener" class="test.event2.CountryListener" />

<bean id="xiaoBai" class="test.event2.XiaoBai" /><!-- 测试时注入使用 -->

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仓库https://github.com/jeanhao/spring下的event2文件夹下载

目录
相关文章
|
6月前
|
Java 测试技术 Docker
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
260 0
|
2月前
spring-state-machine监听器
spring-state-machine监听器
14 0
|
2月前
|
Java 调度 开发工具
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
179 0
|
4月前
|
Java Spring 容器
spring讲解笔记:spring框架学习的要点总结
spring讲解笔记:spring框架学习的要点总结
|
4月前
spring-state-machine监听器
spring-state-machine监听器
21 0
|
5月前
|
设计模式 前端开发 Java
一篇文章让使你的Spring Mvc学习入门,还不来了解吗?
一篇文章让使你的Spring Mvc学习入门,还不来了解吗?
|
6月前
|
druid Java 关系型数据库
Spring Boot 学习研究笔记(二十一) Springboot中druid数据库连接池使用
Spring Boot 学习研究笔记(二十一) Springboot中druid数据库连接池使用
144 0
|
6月前
|
Java 应用服务中间件 nginx
Spring Boot 学习研究笔记(二十)-docker部署SpringBoot使用nginx配置域名
Spring Boot 学习研究笔记(二十)-docker部署SpringBoot使用nginx配置域名
196 0
|
6月前
|
运维 监控 Java
Spring Boot 学习研究笔记(十八) 添加log4j2日志文件
Spring Boot 学习研究笔记(十八) 添加log4j2日志文件
|
6月前
|
SQL 安全 Java
Spring Boot 学习研究笔记(十七) -Spring boot JPA的复杂查询
Spring Boot 学习研究笔记(十七) -Spring boot JPA的复杂查询

热门文章

最新文章