欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring的事件和监听器-同步与异步详解

程序员文章站 2022-06-10 13:30:24
目录spring的事件和监听器-同步与异步1、首先新建startworkflowevent.java,2、新建一个监听器startworkflowlistener.java3、创建一个事件发布类eve...

spring的事件和监听器-同步与异步

application下抽象子类applicationcontextevent的下面有4个已经实现好的事件

  • contextclosedevent(容器关闭时)
  • contextrefreshedevent(容器刷新是)
  • contextstartedevent(容器启动时候)
  • contextstoppedevent(容器停止的时候)

同样,这四个事件都继承了applicationevent,如果我们想自定义事件,也可以通过继承applicationevent来实现

1、首先新建startworkflowevent.java,

继承applicationevent抽象类

public class startworkflowevent extends applicationevent {
    //存放构造器送入的值
    private string msg;
    //构造器参数可以随意设置,这里为了方便调试,设置为字符串
    public startworkflowevent (string msg) {
        super(msg);
        this.msg=msg;
    }
    //自定义一个方法,这个方法也可以随意写,这里也是测试用
    public void myevent(){
        system.out.println("********my event**************");
        system.out.println(msg);
        system.out.println("*******************************");
    }
}

2、新建一个监听器startworkflowlistener.java

实现applicationlistener<startworkflowevent>

/**
 * 发起流程事件监听
 */
@component("startworkflowlistener")
public class startworkflowlistener implements applicationlistener<startworkflowevent> {
 
    @autowired
    private oaworkflowhepler oaworkflowhepler;
 
//@async注解异步调用时使用, 异步调用时, 需要在xml配置文件中添加 <task:annotation-driven />
//  @async
    @override
    public void onapplicationevent(startworkflowevent event) {
        oaworkflowhepler.start(event.getmsg());
    }
}

3、创建一个事件发布类eventpublisher.java

/**
 * 发布事件
 */
@component("eventpublisher")
public class eventpublisher {
 
    @autowired
    private applicationcontext applicationcontext;
 
    /**
     * 发布事件
     * @param event
     */
    public void publishevent(applicationevent event) {
        applicationcontext.publishevent(event);
    }
}

4、相关的配置

<task:annotation-driven />配置:

  • executor:指定一个缺省的executor给@async使用。

例子:

<task:annotation-driven executor="asyncexecutor" />

<task:executor />配置参数:

  • id:当配置多个executor时,被@async("id")指定使用;也被作为线程名的前缀。
  • core size:最小的线程数,缺省:1
  • max size:最大的线程数,缺省:integer.max_value
  • queue-capacity:当最小的线程数已经被占用满后,新的任务会被放进queue里面,当这个 queue的capacity也被占满之后,pool里面会创建新线程处理这个任务,直到总线程数达到了max size,这时系统会拒绝这个任务并抛出taskrejectedexception异常(缺省配置的情况下,可以通过rejection-policy 来决定如何处理这种情况)。缺省值为:integer.max_value
  • keep-alive:超过core size的那些线程,任务完成后,再经过这个时长(秒)会被结束掉
  • rejection-policy:当pool已经达到max size的时候,如何处理新任务
  • abort(缺省):抛出taskrejectedexception异常,然后不执行
  • discard:不执行,也不抛出异常
  • discard_oldest:丢弃queue中最旧的那个任务
  • caller_runs:不在新线程中执行任务,而是有调用者所在的线程来执行

spring事件、异步监听

使用事件的模式可以对系统进行解耦,事件源发布一个事件,

事件监听器可以消费这个事件,而事件源不用关注发布的事件有哪些监听器,

这可以对系统进行解耦

Spring的事件和监听器-同步与异步详解

public class mains extends applicationevent {
    public mains(object name) {
        super(name);
        system.out.println(string.format("hi,我是被监听的%s!",name));
    }
}
@component
public class listenermains {
    //@async  // 开启异步就无法使用@order(0)进行排序了
    @order(0)
    @eventlistener(mains.class)
    public void listener(mains mains){
        system.out.println("这是第一个监听类 "+mains.getsource());
    }
    //@async
    @order(1)
    @eventlistener(mains.class)
    public void listener2(mains mains){
        system.out.println("这是第二个监听类 "+mains.getsource());
    }
    //@async
    @order(2)
    @eventlistener(mains.class)
    public void listener3(mains mains){
        system.out.println("这是第三个监听类 "+mains.getsource());
    }
}
public class testcontroller {
    @autowired
    getaccesstoken getaccesstoken;
    @autowired
    applicationeventpublisher publisher;
    @requestmapping("test")
    public object get() {
        publisher.publishevent(new mains("哈哈哈哈"));
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。