Spring的事件和-同步与异步详解
⽬录
Spring的事件和-同步与异步
1、⾸先新建StartWorkflowEvent.java,
2、新建⼀个StartWorkflowListener.java
3、创建⼀个事件发布类EventPublisher.java
4、相关的配置
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.Msg());
}
}
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,这时系统会拒绝这个任务并抛出
springframework事务TaskRejectedException异常(缺省配置的情况下,可以通过rejection-policy 来决定如何处理这种情况)。缺省值为:Integer.MAX_VALUE
keep-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("这是第⼀个监听类 "+Source());
}
//@Async
@Order(1)
@EventListener(Mains.class)
public void listener2(Mains mains){
System.out.println("这是第⼆个监听类 "+Source());
}
//@Async
@Order(2)
@EventListener(Mains.class)
public void listener3(Mains mains){
System.out.println("这是第三个监听类 "+Source());
}
}
public class TestController {
@Autowired
GetAccessToken getAccessToken;
@Autowired
ApplicationEventPublisher publisher;
@RequestMapping("test")
public Object get() {
publisher.publishEvent(new Mains("哈哈哈哈"));
}
}
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。