EventBus与SpringEvent的区别是什么
EventBus与SpringEvent的区别是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
10年积累的成都网站制作、成都网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有浑南免费网站建设让你可以放心的选择与我们合作。
Guava EventBus
Guava EventBus实现是观察者模式,用法很简单,先上代码。
/** * Desc: 事件对象 */@Data@NoArgsConstructor@AllArgsConstructorpublic class HelloEvent { private String eventName;} @Data@NoArgsConstructorpublic class WorldEvent extends HelloEvent { private int eventNo; public WorldEvent(String name, int no) { setEventName(name); setEventNo(no); }} /** * Desc: 事件监听器,可以监听多个事件。处理方法添加 @Subscribe 注解即可。 */public class GeventListener { /** * 监听 HelloEvent 类型及其父类型(Object)的事件 */ @Subscribe public void processEvent(HelloEvent event){ System.out.println("process hello event, name:" + event.getEventName()); } /** * 监听 WorldEvent 类型及其父类型(HelloEvent 和 Object)的事件 */ @Subscribe public void processWorldEvent(WorldEvent event) { System.out.println("process world eventV1, no:" + event.getEventNo() + ", name:" + event.getEventName()); } /** * 注册多个监听器 监听同一事件 * @param event */ @Subscribe public void processWorldEventV2(WorldEvent event) { System.out.println("process world eventV2, no:" + event.getEventNo() + ", name:" + event.getEventName()); } @Subscribe public void processObject(Object object) { System.out.println("process common event, class:" + object.getClass().getSimpleName()); }} public class GuavaTest { public static void main(String[] args) { EventBus eventBus = new EventBus(); GeventListener listener = new GeventListener(); eventBus.register(listener); eventBus.post(new HelloEvent("hello")); eventBus.post(new WorldEvent("world", 23333)); }}
结果如下:
//HelloEvent被两个监听器处理(HelloEvent类及Object类的监听器)process hello event, name:helloprocess common event, class:HelloEvent//WorldEvent被四个监听器处理(两个自己的,两个父类的)process world eventV1, no:23333, name:worldprocess world eventV2, no:23333, name:worldprocess hello event, name:worldprocess common event, class:WorldEvent
由上可知:Guava EventBus把类当做事件,是以class为key注册和管理事件的,value是事件监听器的method;事件监听器只处理某一类(及其父类)事件。
事件注册与发布
//com.google.common.eventbus.EventBus#register public void register(Object object) { //key为Class, value为EventSubscriber(Object target, Method method)【集合】。注意这里Multimap 为HashMultimap, 即HashMap
事件隔离
多个EventBus可以隔离事件。
public class AnotherListener { /** * 监听 WorldEvent 类型及其父类型(HelloEvent 和 Object)的事件 */ @Subscribe public void processAnotherWorldEvent(WorldEvent event) { System.out.println("process another world event, no:" + event.getEventNo() + ", name:" + event.getEventName()); }}public class GuavaTest { public static void main(String[] args) { EventBus eventBus = new EventBus(); GeventListener listener = new GeventListener(); eventBus.register(listener); eventBus.post(new HelloEvent("hello")); EventBus anotherEventBus = new EventBus(); AnotherListener anotherListener = new AnotherListener(); anotherEventBus.register(anotherListener); anotherEventBus.post(new WorldEvent("AnotherWorld", 666)); }}
结果是
//eventBus结果与之前相同process hello event, name:hello//anotherEventBus 发布的事件,只被其注册的监听器处理process common event, class:HelloEventprocess another world event, no:666, name:AnotherWorld
适用场景:
按照类区分事件 订阅 事件簇 支持自定义event,可以根据event自己写分发器 事件隔离
spring event
spring 新版事件机制也比较简单,看代码。
/** * 继承 ApplicationEvent 的事件 */@Datapublic class HelloEvent extends ApplicationEvent { private String eventName; public HelloEvent(String eventName) { super(eventName); setEventName(eventName); }}/** * 自定义事件 */@Data@NoArgsConstructor@AllArgsConstructorpublic class CustomerEvent { private String name; private Boolean isCustomer;}/** * 监听器类,spring也支持一个类中监听多个事件 */@Component("springListener")public class SpringListener { /** * 监听所有ApplicationEvent类型 及其子类型 的事件 */ @EventListener public void processApplicationEvent(ApplicationEvent event) { System.out.println("process common event, class:" + event.getClass().getSimpleName()); } /** * 监听 HelloEvent类型 事件 */ @EventListener public void processHelloEvent(HelloEvent event) { System.out.println("process helloEvent, name:" + event.getEventName()); } /** * 监听 CustomerEvent 类型事件,但是需要满足condition条件,即isCustomer=true */ @EventListener(condition = "#event.isCustomer") public void processCustomerEvent(CustomerEvent event) { System.out.println("process customer CustomerEvent, name:" + event.getName()); } /** * 监听 CustomerEvent 类型事件,但是需要满足condition条件,即name="miaomiao" */ @EventListener(condition = "#event.getName().equals('miaomiao')") public void processMiaoMiaoEvent(CustomerEvent event) { System.out.println("process miaomiao's CustomerEvent, name:" + event.getName()); } /** * 支持异步处理事件 */ @Async @EventListener public void processAsyncCustomerEvent(CustomerEvent event) { System.out.println("Async process CustomerEvent, name:" + event.getName()); }}//执行类,测试入口@SpringBootApplication@ComponentScan(basePackages = {"com.example.manyao.async"})public class DemoApplication { public static void main(String[] args) throws TException { SpringApplication.run(DemoApplication.class, args); ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); String[] names = context.getBeanDefinitionNames(); for(int i=0; i 结果是 //以下是spring上下文event,继承自 ApplicationContextEvent。 用于用户参与上下文生命周期的入口。因为是ApplicationEvent子类型,所以,由processApplicationEvent处理。process common event, class:ContextRefreshedEventprocess common event, class:EmbeddedServletContainerInitializedEventprocess common event, class:ApplicationReadyEventprocess common event, class:ContextRefreshedEvent//以下是上下文中的beanspringListenerorg.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalRequiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactory++++++++++//HelloEvent 继承 ApplicationEvent,会被processApplicationEvent处理process common event, class:HelloEvent//监听 HelloEvent类型 的 processHelloEvent 处理process helloEvent, name:helloEvent//非 ApplicationEvent 的事件,则为 PayloadApplicationEventprocess common event, class:PayloadApplicationEvent//isCustomer=true,符合processCustomerEvent处理条件process customer CustomerEvent, name:customer//监听CustomerEvent类型,处理结果Async process CustomerEvent, name:customerprocess common event, class:PayloadApplicationEvent//符合processMiaoMiaoEvent条件process miaomiao's CustomerEvent, name:miaomiaoAsync process CustomerEvent, name:miaomiao//spring 上下文事件process common event, class:ContextClosedEvent spring 上下文事件 上述例子中的 ContextRefreshedEvent,EmbeddedServletContainerInitializedEvent,ApplicationReadyEvent,ContextRefreshedEvent,ContextClosedEvent 等事件,都是spring上下文事件。可以通过监听这些事件,参与到spring生命周期中去。这种无侵入性交互方式,在做平台服务时,是一种很好的方式。 注册监听器 org.springframework.context.event.EventListenerMethodProcessor#processBean 将所有注解EventListener的方法,存入上下文的applicationListeners中。Listener的封装类为ApplicationListenerMethodAdapter(String beanName, Class> targetClass, Method method)。 org.springframework.context.support.AbstractApplicationContext#refresh 中调用 initApplicationEventMulticaster 初始化事件发布管理器applicationEventMulticaster,然后调用registerListeners() 注册监听器。 发布事件 spring 起初只支持 ApplicationEvent类型事件,后来优化之后,支持自定义事件。自定义事件的处理,默认为PayloadApplicationEvent,相当于EventBus的DeadEvent。 //org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object, org.springframework.core.ResolvableType) protected void publishEvent(Object event, ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { //若不是ApplicationEvent类型,则使用PayloadApplicationEvent封装 applicationEvent = new PayloadApplicationEvent 执行事件 @Override public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); //获取事件的监听器集合,并逐个触发执行监听器 for (final ApplicationListener> listener : getApplicationListeners(event, type)) { //异步的话,就放在线程池中执行 Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { @Override public void run() { invokeListener(listener, event); } }); } else { //本线程调用 invokeListener(listener, event); } } } 可以看到,spring的事件机制更复杂,但是功能同样强大。 适用场景: 按照类区分事件 订阅 事件簇 支持自定义event 按照condition过滤同类型事件 看完上述内容,你们掌握EventBus与SpringEvent的区别是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
当前文章:EventBus与SpringEvent的区别是什么
新闻来源:http://pwwzsj.com/article/pcedic.html