当前位置:首页 > 数码 > Event-业务解耦的神器-大幅优化可裁减性-Spring (event翻译)

Event-业务解耦的神器-大幅优化可裁减性-Spring (event翻译)

admin4个月前 (05-14)数码18

一、前言

licationContext中的事情处置是经过ApplicationEvent类和ApplicationListener接口提供的。假设将成功了ApplicationListener接口的bean部署到容器中,则每次将ApplicationEvent颁布到ApplicationContext时,都会通知到该bean,这简直是典型的观察者形式。设计的初衷就是为了系统业务逻辑之间的解耦,提高可裁减性以及可保养性。

Spring中提供了以下的事情:

二、ApplicationEvent与ApplicationListener运行

1.成功

自定义事情类,基于ApplicationEvent成功裁减:

publicclassDemoEventextendsApplicationEvent{privatestaticfinallongserialVersionUID=-2753705718295396328L;privateStringmsg;publicDemoEvent(Objectsource,Stringmsg){super(source);this.msg=msg;}publicStringgetMsg(){returnmsg;}publicvoidsetMsg(Stringmsg){this.msg=msg;}}

定义Listener类,成功ApplicationListener接口,并且注入到IOC中。等颁布者颁布事情时,都会通知到这个bean,从而到达监听的成果。

@ComponentpublicclassDemoListenerimplementsApplicationListener<DemoEvent>{@OverridepublicvoidonApplicationEvent(DemoEventdemoEvent){Stringmsg=demoEvent.getMsg();System.out.println("bean-listener收到了publisher颁布的信息:"+msg);}}

要颁布上述自定义的event,须要调用ApplicationEventPublisher的publishEvent方法,咱们可以定义一个成功ApplicationEventPublisherAware的类,并注入IOC来启动调用:

@ComponentpublicclassDemoPublisherimplementsApplicationEventPublisherAware{privateApplicationEventPublisherapplicationEventPublisher;@OverridepublicvoidsetApplicationEventPublisher(ApplicationEventPublisherapplicationEventPublisher){this.applicationEventPublisher=applicationEventPublisher;}publicvoidsendMsg(Stringmsg){applicationEventPublisher.publishEvent(newDemoEvent(this,msg));}}

客户端调用publisher:

@RestController@RequestMapping("/event")publicclassDemoClientimplementsApplicationContextAware{privateApplicationContextapplicationContext;@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{this.applicationContext=applicationContext;}@GetMapping("/publish")publicvoidpublish(){DemoPublisherbean=applicationContext.getBean(DemoPublisher.class);bean.sendMsg("颁布者发送信息......");}}

输入结果:

bean-listener收到了publisher颁布的信息:颁布者发送信息......

2.基于注解

咱们可以不用成功AppplicationListener接口,在方法上经常使用@EventListener注册事情。假设你的方法应该侦听多个事情,并不经常使用任何参数来定义,可以在@EventListener注解上指定多个事情。

重写DemoListener类如下:

publicclassDemoListener{@EventListener(value={DemoEvent.class,TestEvent.class})publicvoidprocessApplicationEvent(DemoEventevent){Stringmsg=event.getMsg();System.out.println("bean-listener收到了publisher颁布的信息:"+msg);}}

3.事情过滤

假设宿愿经过必定的条件对事情启动过滤,可以经常使用@EventListener的condition属性。以下实例中只要event的msg属性是my-event时才会启动调用。

@EventListener(value={DemoEvent.class,TestEvent.class},condition="#event.msg=='my-event'")publicvoidprocessApplicationEvent(DemoEventevent){Stringmsg=event.getMsg();System.out.println("bean-listener收到了publisher颁布的信息:"+msg);}

此时,发送合乎条件的信息,listener才会侦听到publisher颁布的信息。

bean-listener收到了publisher颁布的信息:my-event

4.异步事情监听

前面提到的都是同步处置事情,那假设咱们宿愿某个特定的侦听器异步去处置事情,如何做?

经常使用@Async注解可以成功类内方法的异步伐用,这样方法在执行的时刻,将会在独立的线程中被执行,调用者无需期待它的成功,即可继续其余的操作。

@EventListener@AsyncpublicvoidprocessApplicationEvent(DemoEventevent){Stringmsg=event.getMsg();System.out.println("bean-listener收到了publisher颁布的信息:"+msg);}

经常使用异步监听时,有两点须要留意:

三、好处及运行场景

ApplicationContext在运转期会智能检测到一切成功了ApplicationListener的bean,并将其作为事情接纳对象。当咱们与spring高低文交互触发publishEvent方法时,每个成功了ApplicationListener的bean都会收到ApplicationEvent对象,每个ApplicationListener可以依据须要只接纳自己感兴味的事情。

这样做有什么好处呢?

在传统的名目中,各个业务逻辑之间耦合性比拟强,controller和service间都是关联相关,但是,经常使用ApplicationEvent监听publisher这种形式,类间相关是什么样的?咱们不如画张图来看看。

DemoPublisher和DemoListener两个类间并没有间接关联,解除了传统业务逻辑两个类间的关联相关,将耦合降到最小。这样在前期降级、保养时难度大大降落了。

ApplicationEvent经常使用观察者形式成功,那什么时刻适宜经常使用观察者形式呢?观察者形式也叫颁布-订阅形式,例如,微博的订阅,咱们订阅了某些微博账号,当这些账号颁布信息时,咱们都会收到通知。

大幅优化可裁减性

总结来说,定义对象间的一种一对多的依赖相关,当一个对象的形态出现扭转时,一切依赖于它的对象都失掉通知并被智能降级,从而成功广播的成果。

四、源码浏览

Spring中的事情机制流程:

经过上图就能较明晰的知道当一个事情源发生事情时,它经过事情颁布器ApplicationEventPublisher颁布事情,而后事情广播器ApplicationEventMulticaster会去事情注册表ApplicationContext中找到事情监听器ApplicationListnener,并且一一执行监听器的onApplicationEvent方法,从而成功事情监听器的逻辑。

到来ApplicationEventPublisher的publishEvent方法外部:

protectedvoidpublishEvent(Objectevent,@NullableResolvableTypeeventType){if(this.earlyApplicationEvents!=null){this.earlyApplicationEvents.add(applicationEvent);}else{//getApplicationEventMulticaster().multicastEvent(applicationEvent,eventType);}}

多播事情方法:

@OverridepublicvoidmulticastEvent(finalApplicationEventevent,@NullableResolvableTypeeventType){ResolvableTypetype=(eventType!=null?eventType:resolveDefaultEventType(event));Executorexecutor=getTaskExecutor();//遍历一切的监听者for(ApplicationListener<?>listener:getApplicationListeners(event,type)){if(executor!=null){//异步伐用监听器executor.execute(()->invokeListener(listener,event));}else{//同步伐用监听器invokeListener(listener,event);}}}

invokeListener:

protectedvoidinvokeListener(ApplicationListener<?>listener,ApplicationEventevent){ErrorHandlererrorHandler=getErrorHandler();if(errorHandler!=null){try{doInvokeListener(listener,event);}catch(Throwableerr){errorHandler.handleError(err);}}else{doInvokeListener(listener,event);}}

doInvokeListener:

privatevoiddoInvokeListener(ApplicationListenerlistener,ApplicationEventevent){try{//这里是事情出现的中央listener.onApplicationEvent(event);}catch(ClassCastExceptionex){......}}

点击ApplicationListener接口onApplicationEvent方法的成功,可以看到咱们重写的方法。

五、总结

Spring经常使用反射机制,失掉了一切承袭ApplicationListener接口的监听器,在Spring初始化时,会把监听器都智能注册到注册表中。

Spring的事情颁布十分便捷,咱们来总结一下:

最后,颁布-订阅形式可以很好的将业务逻辑启动解耦(上图验证过),大大提高了可保养性、可裁减性。


springevent可以跨服务监听。 根据查询相关信息springevent监听范围1、定义事件ApplicationEvent2、定义监听ApplicationListener接口,要么在方法上添加EventListener注解。 3、发布事件,调用()或者()。 比如用户注册成功以后,系统要给用户发送一封邮件,同时还要给用户发放优惠券,为了跟注册流程解耦,可以在注册成功以后发出一个事件,让其他服务来监听。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: SpringEvent

“Event-业务解耦的神器-大幅优化可裁减性-Spring (event翻译)” 的相关文章

概念-Spring-AOP-实现原理和应用-中的 (概念股股票)

概念-Spring-AOP-实现原理和应用-中的 (概念股股票)

什么是AOP? AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,其主要目的是将横切关注点(cross-cutting concern)从主要业务...

Spring-释放数据传输潜力的数据压缩技术-微服务 (springboot启动)

Spring-释放数据传输潜力的数据压缩技术-微服务 (springboot启动)

简介 随着云原生架构的兴起,微服务已成为可扩展和可维护系统的重要构建块。顾名思义,微服务是小型的、独立的服务,它们共同构成一个完整的系统。当使用微服务构建系统时,尤其是那些具有大量数据交换的系统...

比如每日有大量用户访问和数据替换-服务器的带宽需求与网站的访问量密切相关-那么就须要更大的带宽来满足需求-访问量-假设你的网站流量大 (比如每日有大事的句子)

比如每日有大量用户访问和数据替换-服务器的带宽需求与网站的访问量密切相关-那么就须要更大的带宽来满足需求-访问量-假设你的网站流量大 (比如每日有大事的句子)

SpringBeanDefinition元信息定义形式 BeanDefinition是一个蕴含Bean元数据的对象。它形容了如何创立Bean实例、Bean属性的值以及Bean之间的依赖相关。...

极致便当与卓越容错-Topic-Spring-重试-成功-运用-Kafka (极致餐是什么意思)

极致便当与卓越容错-Topic-Spring-重试-成功-运用-Kafka (极致餐是什么意思)

概述 Kafka的弱小性能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条信息的值。可以智能或手动参与该值。假设咱们因为失误而不可处置信息并想重试,咱们可以选用...

Security权限控制框架入门指南-Spring (security)

Security权限控制框架入门指南-Spring (security)

在罕用的后盾治理系统中,通常都会有访问权限控制的需求,用于限度不同人员关于接口的访问才干,假设用户不具有指定的权限,则不能访问某些接口。 本文将用waynboot-mall名目举例,给大家引...

Spring-Webflux-Boot-虚构线程性能逊色于-深化比较 (springboot)

Spring-Webflux-Boot-虚构线程性能逊色于-深化比较 (springboot)

早上看到一篇关于SpringBoot虚构线程和Webflux性能对比的文章,感觉还不错。内容较长,抓重点给大家引见一下这篇文章的外围内容,繁难大家极速浏览。 测试场景 作者驳回了一个尽...

揭秘-的暗藏技艺-AOP-从概念到实用场景-Spring (神秘丂丂是什么意思)

揭秘-的暗藏技艺-AOP-从概念到实用场景-Spring (神秘丂丂是什么意思)

环境:Spring5.3.23 1.引见 当天看Spring文档看到这么一个常识点《ControlFlowPointcuts》都不好翻译 官网原文: Springcontr...

Spring-Boot-Starter原理详解-b-b (springernature)

Spring-Boot-Starter原理详解-b-b (springernature)

SpringBoot Starter 是一种包含了一组特定功能和依赖关系的依赖项,旨在为特定的应用程序场景提供快速集成和开箱即用的功能。主要用于将常用的功能模块打包成一个可重用的依赖项,开发者只需...