背景
项目中用到了spring的事件发布,在用完之后,对其中的原理和实现做一些了解和记录。
DEMO
首先新建一个事件
public class DemoEvent extends ApplicationEvent {
private Demo demo;
public TestEvent(Demo demo) {
super(demo);
this.demo = demo;
}
public Demo getDemo(){
return this.demo;
}
}
然后创建一个事件发布者
@Service
public DemoEventPublish{
@Autowired
private ApplicationEventPublisher publisher;
public void publish(Demo demo){
System.out.println("request thread id : " + Thread.currentThread().getId());
publisher.publishEvent(new DemoEvent(demo));
}
}
以及一个事件监听者
@Async
@Component("userEventListener")
public class DemoEventListener implements ApplicationListener<DemoEvent> {
@Override
public void onApplicationEvent(DemoEvent demoEvent) {
System.out.println("response thread id : " + Thread.currentThread().getId());
System.out.println(demoEvent.getDemo());
}
}
上述就是一个最简单的spring事件发布监听的使用,首先在事件发布者处发布事件。接着如果有监听者监听相应的事件,那么监听者就会根据事件执行接下来的业务操作。
探究
在简单的使用之后,让我们简单的了解一下这个东西是如何实现的。
首先看一下他的类图
然后看一下spring是怎么实现他的
首先是事件发布,也就是通知事件中心
入口在这里
@Autowired
private ApplicationEventPublisher publisher;
publisher.publishEvent(new DemoEvent(demo));
publisher调用publishEvent方法,将一个事件提交到事件中心去。
通过找他的实现可以看到它调用的是AbstractApplicationContext中的publishEvent方法
接着看广播器的广播方法。
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
然后通知监听器执行的方法
invokeListener(listener, event);
最后由监听器执行方法
doInvokeListener(listener, event);
总结
如果不配置线程池,或者没有为监听器开启@Async注解的话
将在事件发布后同步执行。
否者将会在线程中异步执行执行。
若配置了线程池,那么可以在线程池中执行。
若开启了@Async注解,那么将会代理listener对象,在执行方法的时候启动线程去调用。