Spring的事件和监听器-同步与异步详解
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
:最小的线程数,缺省:1max size
:最大的线程数,缺省:Integer.MAX_VALUEqueue-capacity
:当最小的线程数已经被占用满后,新的任务会被放进queue里面,当这个 queue的capacity也被占满之后,pool里面会创建新线程处理这个任务,直到总线程数达到了max size,这时系统会拒绝这个任务并抛出TaskRejectedException异常(缺省配置的情况下,可以通过rejection-policy 来决定如何处理这种情况)。缺省值为:Integer.MAX_VALUEkeep-alive
:超过core size的那些线程,任务完成后,再经过这个时长(秒)会被结束掉rejection-policy
:当pool已经达到max size的时候,如何处理新任务ABORT
(缺省):抛出TaskRejectedException异常,然后不执行DISCARD
:不执行,也不抛出异常DISCARD_OLDEST
:丢弃queue中最旧的那个任务CALLER_RUNS
:不在新线程中执行任务,而是有调用者所在的线程来执行
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("哈哈哈哈")); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
SpringBoot2 task scheduler 定时任务调度器四种方式
这篇文章主要介绍了SpringBoot2 task scheduler 定时任务调度器四种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-03-03Mapper批量插入Oracle数据@InsertProvider注解
今天小编就为大家分享一篇关于Mapper批量插入Oracle数据@InsertProvider注解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧2019-03-03java多线程返回值使用示例(callable与futuretask)
这篇文章主要介绍了多线程返回值使用示例(callable与futuretask),需要的朋友可以参考下2014-04-04java 中用split分割字符串,最后的空格等不被拆分的方法
下面小编就为大家带来一篇java 中用split分割字符串,最后的空格等不被拆分的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-02-02SpringBoot项目将mybatis升级为mybatis-plus的方法
本文主要介绍了SpringBoot项目将mybatis升级为mybatis-plus的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-01-01IDEA 2020 无法启动的解决办法(启动崩盘)附IDEA 2020 新功能
这篇文章主要介绍了IDEA 2020 无法启动的解决办法(启动崩盘)附IDEA 2020 新功能,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-04-04SpringBoot+JavaMailSender实现腾讯企业邮箱配置
这篇文章主要介绍了SpringBoot+JavaMailSender实现腾讯企业邮箱配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-04-04
最新评论