您的位置:首页 > 编程语言 > Java开发

Java for Web学习笔记(八九):消息和集群(4)定制发布和订购

2017-11-11 10:50 507 查看

SimpleApplicationEventMulticaster

本学习一方面进一步了解Spring对publish/subcribe的支持,另一方面也是为了后面如何利用webSocket在集群中传递事件的小例子作准备。spring将发布的消息称为event,通过消息广播器发布消息并发送到响应的订阅中。消息广播器可以理解为app内部的broker。Spring提供了SimpleApplicationEventMulticaster,实现了ApplicationEventMulticaster接口,将事件广播到已经登记的listener中。先看看javadoc对SimpleApplicationEventMulticaster的说明:

Simple implementation of the ApplicationEventMulticaster interface.

Multicasts all events to all registered listeners, leaving it up to the listeners to ignore events that they are not interested in. Listeners will usually perform corresponding instanceof checks on the passed-in event
object.

By default, all listeners are invoked in the calling thread. This allows the danger of a rogue listener blocking the entire application, but adds minimal overhead. Specify an alternative task executor to have listeners
executed in different threads, for example from a thread pool.

参考阅读:http://www.baeldung.com/spring-events

实现异步监听事件

在上次学习中,可以很简单地通过在listener的触发方法上加入@Async,使得subscribe实现异步处理,如果事件多,需要在很多的方法上都加上异步的字样,我们可以如javadoc所说,指定一个任务executor来让listener在其他线程中执行。也就是说,我们需要给出自定义的ApplicationEventMulticaster。在Root上下文中:

//【学习1】这个Bean的名字必须是applicationEventMulticaster,如果我们的方法取了其他名字,即非applicationEventMulticaster(),可以采用name的方式指定
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster customMulticaster(){
SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
//【学习2】指定一个任务executor来进行后台处理
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}

我们发布了某个Event,被两个Listener监听到,相关的log如下,实现了不同

10:47:51.199 [SimpleAsyncTaskExecutor-12] [INFO ] AuthenticationInterestedParty:20 onApplicationEvent() - Authentication event from context /adfsjjflsdjfljsedljfljf received in context /chapter18.
10:47:51.199 [SimpleAsyncTaskExecutor-13] [INFO ] LoginInterestedParty:21 onApplicationEvent() - Login event for context /adfsjjflsdjfljsedljfljf received in context /chapter18.

进一步了解

我们自定义一个类MyMulticaster,继承SimpleApplicationEventMulticaster,来进一步了解。相应地,在配置中,要将applicationEventMulticaster设置为自定义的类:

@Bean
public ApplicationEventMulticaster applicationEventMulticaster(){
SimpleApplicationEventMulticaster eventMulticaster = new MyMulticaster();
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}

我们重点看看MyMulticaster,重写了三个方法:

public class MyMulticaster extends SimpleApplicationEventMulticaster{
private static final Logger log = LogManager.getLogger();

@Override
public void multicastEvent(ApplicationEvent event) {
log.traceEntry("【这里是个坑】实际上没有触发到此方法(Spring版本4.3.11.RELEASE),需特别注意。");
super.multicastEvent(event);
}

@Override
public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
log.traceEntry("发布时调用,eventType可以为null,此运行在发布所在线程,此处可以用于集群消息发布,添加通过网络发布给其他模块。");
super.multicastEvent(event, eventType);
}

@Override
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
log.traceEntry("触发接收事件时调用,如设置了taskExecutor,则异步运行");
super.invokeListener(listener, event);
}
}

相关链接:
我的Professional Java for Web Applications相关文章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐