当前位置: 首页 > news >正文

信息化建设 网站新品发布会的作用

信息化建设 网站,新品发布会的作用,台州椒江区建设局网站,手机网站框架一、背景 在开发工作中#xff0c;我们常常会遇到这样一种情况#xff1a;完成一项任务后#xff0c;需要向其他模块广播消息或通知#xff0c;以触发其他事件的处理。逐个发送请求固然可行#xff0c;但更好的方式是采用事件监听#xff0c;它是设计模式中的发布-订阅模…一、背景 在开发工作中我们常常会遇到这样一种情况完成一项任务后需要向其他模块广播消息或通知以触发其他事件的处理。逐个发送请求固然可行但更好的方式是采用事件监听它是设计模式中的发布-订阅模式和观察者模式的一种实现。 观察者模式简单来说就是一种角色扮演你在做某件事时有人在一旁观察你。当这个人观察到你有兴趣的特定事件发生时他们会根据这个事件做一些其他的事情。但请注意任何想要观察你的人都必须先到你这儿进行登记否则你将无法通知到他们或者他们没有资格来观察你。 在Spring容器中我们可以监听并触发各种事件。通常有两种方法可以实现这一目标使用ApplicationListener接口和使用EventListener注解。这两种方法都能帮助我们更好地管理和响应应用程序中的各种事件。 二、简介 2.1 用途 为了实现一个能够监听应用程序事件的监听器方法我们可以使用特定的注解来标记该方法并定义其支持的事件类型。 如果监听器方法只支持单一的事件类型我们可以将其参数声明为该事件类型的唯一实例。例如如果我们的监听器方法只监听ApplicationEvent实例则可以将其参数声明为ApplicationEvent类型。 如果监听器方法支持多种事件类型我们可以使用注解的classes属性来指定一个或多个支持的事件类型。这样该方法就可以监听到在classes属性中指定的任何事件类型。 2.2 事件处理条件 可以通过 condition 属性指定一个SpEL表达式如果返回 “true”, “on”, “yes”, or “1” 中的任意一个则事件会被处理否则不会。 2.3 处理器 在Spring框架中EventListener注解的处理是通过内部的EventListenerMethodProcessor类进行的。这个类负责寻找带有EventListener注解的方法并在适当的时候触发它们。 当使用Java配置时EventListenerMethodProcessor会自动注册到Spring容器中。你只需要在带有EventListener注解的方法上添加Component或Service等注解Spring就会自动检测并注册这个方法。 2.4 返回值 被标注的方法可以没有返回值也可以有返回值。当有返回值是其返回值会被当作为一个新的事件发送。如果返回类型是数组或集合那么数组或集合中的每个元素都作为一个新的单独事件被发送。 2.5 异常处理 同步监听器抛出的所有checked异常都会被封装成 UndeclaredThrowableException 因为事件发布者只能处理运行时异常unchecked异常。 2.6 异步监听器 当需要异步处理监听器时可以在监听器方法上再增加另外的一个Spring注解 Async但需要注意以下限制 监听器报错不会传递给事件发起者因为双方已经不在同一个线程了。 异步监听器的非空返回值不会被当作新的事件发布。如果需要发布新事件需要注入 ApplicationEventPublisher后手动发布。 2.7 监听器排序 如果同一个事件可能会被多个监听器监听处理那么我们可以使用 Order 注解对各个监听器进行排序。 2.8 源码 Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface EventListener {/*** Alias for {link #classes}.*/AliasFor(classes)Class?[] value() default {};/*** 可以处理的事件类型*/AliasFor(value)Class?[] classes() default {};/*** SpEL表达式判断是否满足处理条件*/String condition() default ;/*** 可以给监听器指定一个id默认是方法的全限定名如mypackage.MyClass.myMethod()*/String id() default ;}三、示例详解 3.1 单一事件监听器 发布事件 Service public class EventPublisher {private ApplicationEventPublisher eventPublisher;Autowiredpublic void setEventPublisher(ApplicationEventPublisher eventPublisher) {this.eventPublisher eventPublisher;}public void publishPersonSaveEvent(){PersonSaveEvent saveEvent new PersonSaveEvent();saveEvent.setId(1);saveEvent.setName(i余数);saveEvent.setAge(18);eventPublisher.publishEvent(saveEvent);} }监听事件 Slf4j Service public class EventListenerService {EventListenerpublic void handleForPersonSaveEvent(PersonSaveEvent saveEvent){log.info(saveEvent - {}, saveEvent);} }结果验证 saveEvent - PersonSaveEvent(id1, namei余数, age18)3.2 使用classes实现多事件监听器 发布事件 在上一个示例的基础上再多加一个PersonUpdateEvent事件。 public void publishPersonUpdateEvent(){PersonUpdateEvent updateEvent new PersonUpdateEvent();updateEvent.setId(1);updateEvent.setName(i余数);updateEvent.setAge(19);eventPublisher.publishEvent(updateEvent); }监听事件 EventListener(classes {PersonSaveEvent.class, PersonUpdateEvent.class}) public void handleForPersonSaveAndUpdateEvent(Object event){log.info(multi handle event - {}, event); }验证结果 可以监听到多个事件 multi handle event - PersonSaveEvent(id1, namei余数, age18) multi handle event - PersonUpdateEvent(id1, namei余数, age19)3.3 使用condition筛选监听的事件 发布事件 public void publishPersonSaveEvent(){PersonSaveEvent saveEvent new PersonSaveEvent();saveEvent.setId(1);saveEvent.setName(i余数);saveEvent.setAge(18);eventPublisher.publishEvent(saveEvent);PersonSaveEvent saveEvent2 new PersonSaveEvent();saveEvent2.setId(2);saveEvent2.setName(i余数);saveEvent2.setAge(18);eventPublisher.publishEvent(saveEvent2); }监听事件 EventListener(condition #root.event.getPayload().getId() 1) public void handleByCondition(PersonSaveEvent saveEvent){log.info(只处理id等于1的 - {}, saveEvent); }结果验证 id为2的事件不满足条件所以不会执行。 只处理id等于1的 - PersonSaveEvent(id1, namei余数, age18)3.4 有返回值的监听器 3.4.1 返回一个单一对象 发布事件 public void publishPersonSaveEvent(){PersonSaveEvent saveEvent new PersonSaveEvent();saveEvent.setId(1);saveEvent.setName(i余数);saveEvent.setAge(18);eventPublisher.publishEvent(saveEvent); }监听事件 EventListener public void handleForPersonUpdateEvent(PersonUpdateEvent updateEvent){log.info(handle update event - {}, updateEvent); }EventListener public PersonUpdateEvent handleHaveReturn(PersonSaveEvent saveEvent){log.info(handle save event - {}, saveEvent);PersonUpdateEvent updateEvent new PersonUpdateEvent();updateEvent.setId(saveEvent.getId());updateEvent.setName(saveEvent.getName());updateEvent.setAge(saveEvent.getAge());return updateEvent; }验证结果 可以看到我们监听到了2个事件PersonSaveEvent是我们主动发布的事件PersonUpdateEvent 是 handleHaveReturn 方法的返回值会被 Spring 自动当作一个事件被发送。 handle save event - PersonSaveEvent(id1, namei余数, age18) handle update event - PersonUpdateEvent(id1, namei余数, age18)3.4.2 返回一个集合 将监听器稍作修改使其返回一个集合。 EventListener public ListPersonUpdateEvent handleHaveReturn(PersonSaveEvent saveEvent){log.info(handle save event - {}, saveEvent);ListPersonUpdateEvent events new ArrayList();PersonUpdateEvent updateEvent new PersonUpdateEvent();updateEvent.setId(saveEvent.getId());updateEvent.setName(saveEvent.getName());updateEvent.setAge(saveEvent.getAge());events.add(updateEvent);PersonUpdateEvent updateEvent2 new PersonUpdateEvent();BeanUtils.copyProperties(updateEvent, updateEvent2);events.add(updateEvent2);return events;}查看结果可以发现集合中的每个对象都被当作一个单独的事件进行发送。 handle save event - PersonSaveEvent(id1, namei余数, age18) handle update event - PersonUpdateEvent(id1, namei余数, age18) handle update event - PersonUpdateEvent(id1, namei余数, age18)3.4.3 返回一个数组 和返回值为集合一样数组中的每个对象都被当作一个单独的事件进行发送。 3.4.4 异步监听器 创建两个监听器一个同步一个异步异步监听器就是在方法上加一个 Async 标签即可你可以指定线程池。 EventListener public void handleForPersonSaveEvent(PersonSaveEvent saveEvent){log.info(handle event - {}, saveEvent); }Async EventListener public void handleForPersonSaveEventAsync(PersonSaveEvent saveEvent){log.info(async handle event - {}, saveEvent); }从执行结果可以看出异步线程是 task-1不是主线程 main即异步是生效的。 INFO 3851 --- [ main] i.k.s.e.listener.EventListenerService : handle event - PersonSaveEvent(id1, namei余数, age18) INFO 3851 --- [ task-1] i.k.s.e.listener.EventListenerService : async handle event - PersonSaveEvent(id1, namei余数, age18)3.5 监听器异常处理 3.5.1 同步异常处理 使用 SimpleApplicationEventMulticaster 处理同步监听器抛出异常。 先定义一个ErrorHandler: Slf4j Component public class MyErrorHandler implements ErrorHandler {Overridepublic void handleError(Throwable t) {log.info(handle error - {}, t.getClass());} }将自定义ErrorHandler绑定到 SimpleApplicationEventMulticaster。 Slf4j Service public class EventListenerService {Autowiredprivate SimpleApplicationEventMulticaster simpleApplicationEventMulticaster;Autowiredprivate MyErrorHandler errorHandler;PostConstructpublic void init(){simpleApplicationEventMulticaster.setErrorHandler(errorHandler);}Order(1)EventListenerpublic void handleForPersonSaveEvent(PersonSaveEvent saveEvent) throws AuthException {log.info(handle event - {}, saveEvent);throw new AuthException(test exception);} } 结果可以看到捕获的异常是 UndeclaredThrowableException。 handle event - PersonSaveEvent(id1, namei余数, age18) handle error - class java.lang.reflect.UndeclaredThrowableException3.5.2 异步异常处理 使用 SimpleAsyncUncaughtExceptionHandler 来处理 Async 抛出的异常。 Configuration public class AsyncConfig implements AsyncConfigurer {Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new SimpleAsyncUncaughtExceptionHandler();} }监听器代码人为的抛出一个异常。 Async EventListener public void handleForPersonSaveEvent(PersonSaveEvent saveEvent) throws AuthException {log.info(handle event - {}, saveEvent);throw new AuthException(test exception); }结果: SimpleAsyncUncaughtExceptionHandler捕获到了 Async 方法抛出的异常 INFO 4416 --- [ task-1] i.k.s.e.listener.EventListenerService : handle event - PersonSaveEvent(id1, namei余数, age18) ERROR 4416 --- [ task-1] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void xxxx.handleForPersonSaveEvent(xxxx.PersonSaveEvent) throws javax.security.auth.message.AuthException3.6 监听器排序 如果同时有多个监听器监听同一个事件默认情况下监听器的执行顺序是随机的如果想要他们按照某种顺序执行可以借助Spring的另外一个注解 Order 实现。 创建三个监听器并使用Order 排好序。 Order(1) EventListener public void handleForPersonSaveEvent(PersonSaveEvent saveEvent){log.info(handle event1 - {}, saveEvent); }Order(2) EventListener public void handleForPersonSaveEvent2(PersonSaveEvent saveEvent){log.info(handle event2 - {}, saveEvent); }Order(3) EventListener public void handleForPersonSaveEvent3(PersonSaveEvent saveEvent){log.info(handle event3 - {}, saveEvent); }从执行结果可以看到确实是按照Order中指定的顺序执行的。 handle event1 - PersonSaveEvent(id1, namei余数, age18) handle event2 - PersonSaveEvent(id1, namei余数, age18) handle event3 - PersonSaveEvent(id1, namei余数, age18)四、总结 在Spring框架中EventListener注解用于标识监听器方法可以监听Spring ApplicationEvent或其他任意对象的事件。 当一个方法被标注为EventListener时它就被视为一个事件监听器可以接收和响应特定类型的事件。这个方法可以在事件发布时被调用以处理该事件。在Spring框架中EventListenerMethodProcessor负责寻找和调用带有EventListener注解的方法。 EventListener注解可以设置两个属性value和classes用于指定监听器监听的事件类型。如果value和classes没有设置值那么被标注的方法必须有一个且只能有一个参数。如果value或classes设置了值单个Class值表示监听器可以不用设置参数多个Class值则要求被标注的方法一定不要设置参数。这是因为在监听事件时通过反射监听方法处理事件事件转换成方法参数时若类型不一致可能会发生类型转换异常。 此外还有一个注解TransactionalEventListener它继承了EventListener的功能并添加了新的特性。这个注解可以用于在事务处理期间监听事件并且可以根据需要自动回滚事务。 总的来说EventListener是一种非常有用的技术可以帮助我们更好地管理和响应应用程序中的事件。在Spring框架中我们可以使用EventListener注解来方便地创建和注册事件监听器从而实现更高效的事件处理和控制。
http://www.zqtcl.cn/news/329656/

相关文章:

  • 南昌购物网站制作国外免费网站空间
  • 网站地图模版企业做网站etp和源程序
  • 电子商务企业网站的推广方式外贸长尾关键词挖掘网站
  • 靓号网建站网站商城html模板
  • 广东顺德网站建设wordpress 我爱搜罗网
  • 基金网站建设需求书昆明网站制作工具
  • 京东网上购物商城官方网站国外网站页头设计图片
  • 芯片设计公司排名安卓优化大师app
  • 如何进行网站域名解析网站开发的工作方法
  • 专门做衣服的网站有哪些南宁企业官网seo
  • 网站 建设 内容中铁建设集团有限公司招聘官网
  • 个人电脑做服务器网站cn域名注册流程
  • 网站开发的思维导图哪些网站是react做的
  • 住房和城乡建设部网站注册进度常德建设局网站
  • 网站导购话术怎么做免费的产品图片网站
  • 网站设计外文文献建建设网站公司
  • 打开网站说建设中是什么问题网站开发收税
  • 海口建设厅网站grimhelm wordpress
  • 如何快速提升网站pr淮北房产网
  • 微网站和微信广州营销型网站建设团队
  • 企业网站制作托管微信建站网站
  • h5网站如何做排名济南网站建设选聚搜网络
  • 网站建设 手机wordpress 仿煎蛋主题
  • 织梦可以仿所有网站吗电子商务网站建设臧良运课后答案
  • 怎样创建个人购物网站wordpress没有外观
  • 衡水手机网站建设公司计算机大专学历有用吗
  • 有哪些网站做的很好桐乡市建设局官方网站
  • 做公众号和网站一样吗免费正能量网站下载ww
  • 使用帝国做软件下载网站源码顺义区做网站的公司
  • 网站用什么颜色成都网站建设公司服务