Spring 框架中注释驱动的事件监听器详解
事件交互已经成为很多应用程序不可或缺的一部分,Spring框架提供了一个完整的基础设施来处理瞬时事件。下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器。
1、早期的方式
在早期,组件要从Spring事件获知自定义域事件中获取通知,那么组件必须实现ApplicationListener接口并覆写onApplicationEvent方法。
@Component
class OldWayBlogModifiedEventListener implements ApplicationListener<OldWayBlogModifiedEvent> { @Override
public void onApplicationEvent(OldWayBlogModifiedEvent event) {
externalNotificationSender.oldWayBlogModified(event);
}
}
上面的代码工作正常,但是它会针对每一个事件都创建一个新类,从而造成代码瓶颈。
另外,我们的事件类继承了ApplicationEvent类——Spring应用中的事件基类。
class OldWayBlogModifiedEvent extends ApplicationEvent {
public OldWayBlogModifiedEvent(Blog blog) {
super(blog);
}
public Blog getBlog() {
return (Blog)getSource();
}
}
2、注释驱动的事件监听器
Spring 4.2框架值得注意的一点,用注释@EventListener注解任意的Spring组件。
@EventListener
public void blogModified(BlogModifiedEvent blogModifiedEvent) {
externalNotificationSender.blogModified(blogModifiedEvent);
}
Spring会为事件创建一个ApplicationListener实例,并从方法参数中获取事件的类型。一个类中被事件注释的方法数量没有限制,所有相关的事件句柄都会分组到一个类中。
3、有条件的事件处理
为了使注释@EventListener的功能更强大,Spring 4.2支持用SpEL表达式表达事件类型的方式。假设以下是事件类:
public class BlogModifiedEvent {
private final Blog blog;
private final boolean importantChange;
public BlogModifiedEvent(Blog blog) {
this(blog, false);
}
public BlogModifiedEvent(Blog blog, boolean importantChange) {
this.blog = blog;
this.importantChange = importantChange;
}
public Blog getBlog() {
return blog;
}
public boolean isImportantChange() {
return importantChange;
}
}
要注意,在实际应用中可能不会有本文这样的层次结构的事件。
还要注意,用Groovy编写会更加简单。
使用条件参数来阐述事件,重要的变化是:
@EventListener(condition = "#blogModifiedEvent.importantChange")
public void blogModifiedSpEL(BlogModifiedEvent blogModifiedEvent) {
externalNotificationSender.blogModifiedSpEL(blogModifiedEvent);
}
4、宽松事件类型的层次结构
Spring 4.2之前的版本,ApplicationEventPublisher只有在ApplicationEvent事件后发布其继承对象的能力。而在Spring 4.2版开始,此接口已经扩展到支持任意对象类型。在这种情况下,对象被封装到PayloadApplicationEvent和通过发送。
//base class with Blog field - no need to extend `ApplicationEvent`
class BaseBlogEvent {}
class BlogModifiedEvent extends BaseBlogEvent {}
//somewhere in the code
ApplicationEventPublisher publisher = (...); //injected
publisher.publishEvent(new BlogModifiedEvent(blog)); //just plain instance of the event
这一变化使得发布事件更容易。然而另一方面它可以导致事件跟踪变得更加困难,特别是在大型应用程序中。
5、响应发布事件
注释@EventListener还有一点需注意,在非空返回类型时,Spring会自动发布返回的事件。
@EventListener
public BlogModifiedResponseEvent blogModifiedWithResponse(BlogModifiedEvent blogModifiedEvent) {
externalNotificationSender.blogModifiedWithResponse(blogModifiedEvent);
return new BlogModifiedResponseEvent(
blogModifiedEvent.getBlog(), BlogModifiedResponseEvent.Status.OK);
}
6、异步事件处理
注释@EventListener还可以与注释@Async进行组合使用,以提供异步事件处理的机制。下面的代码中,指定的事件监听器既不会阻塞主要的代码执行,又不会被其它的监听器处理。
@Async //Remember to enable asynchronous method execution
//in your application with @EnableAsync
@EventListener
public void blogAddedAsync(BlogAddedEvent blogAddedEvent) {
externalNotificationSender.blogAdded(blogAddedEvent);
}
为了使工作能够得到异步执行,通常还需在Spring项目的上下文中使用注释@EnableAsync。
或者xml文件:
<!-- 开启异步调用@Async注解-->
<task:annotation-driven executor="myTaskExecutor"/>
<task:executor id="myTaskExecutor" pool-size="5"/>
7、总结
注释驱动的事件监听器是Spring框架4.2版中引入的新特性,它减少了Spring项目的样板代码,使得代码更加灵活,尤其是在小数量事件的需求时体现更为明显。
Spring 框架中注释驱动的事件监听器详解的更多相关文章
- Spring 4.2框架中注释驱动的事件监听器详解
事件交互已经成为很多应用程序不可或缺的一部分,spring框架提供了一个完整的基础设施来处理瞬时事件.下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器. 1.早期的方式 在早期,组件要 ...
- spring框架中AOP思想与各种配置详解
Spring中提供两种AOP支持: 1.基于代理的经典AOP 2.Aspectj注解配置AOP 首先我们先了解什么是AOP,AOP(Aspect Oriented Programming ...
- Spring框架中不同类型的事件
ContextRefreshedEvent,ApplicationContext初始化或者被更新是会触发,ConfigurableApplicationContext接口中的refresh()方法被调 ...
- 在.Net框架中 C# 实现多线程的同步方法详解
本文主要描述在C#中线程同步的方法.线程的基本概念网上资料也很多就不再赘述了.直接接入主题,在多线程开发的应用中,线程同步是不可避免的.在.Net框架中,实现线程同步主要通过以下的几种方式来实现,在M ...
- 项目实践之工作流引擎基本文档!Activiti工作流框架中流程引擎API和服务详解
流程引擎的API和服务 流程引擎API(ProcessEngine API)是与Activiti打交道的最常用方式 Activiti从ProcessEngine开始.在ProcessEngine中,可 ...
- Laravel5.4框架中视图共享数据的方法详解
本文实例讲述了Laravel5.4框架中视图共享数据的方法.分享给大家供大家参考,具体如下: 每个人都会遇到这种情况:某些数据还在每个页面进行使用,比如用户信息,或者菜单数据,最基本的做法是在每个视图 ...
- thinkphp框架中“关联操作”的完整定义详解
在复杂的关联操作中,如果要给关联定义增加可选的属性,我们可以采用完整定义的方式. 完整定义的格式是: protected $_link = array( '关联表名1' => arr ...
- ssh框架中struts.xml 的配置参数详解
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...
- Tomcat与Spring中的事件机制详解
最近在看tomcat源码,源码中出现了大量事件消息,可以说整个tomcat的启动流程都可以通过事件派发机制串起来,研究透了tomcat的各种事件消息,基本上对tomcat的启动流程也就有了一个整体的认 ...
随机推荐
- Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!
在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也终于发布了最新的版本.该版本距离上一次发布,过去了整整4个月!下面就随我一起看看,这个大家期待已久的版本都有哪些 ...
- Ambiguous HTTP method Actions require an explicit HttpMethod binding for Swagger 2.0
异常内容 NotSupportedException: Ambiguous HTTP method for action . Actions require an explicit HttpMetho ...
- [转]How to: Create a Report Server Database (Reporting Services Configuration)
本文转自:https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms157300%28v%3dsql.10 ...
- 如何编写最佳的Dockerfile
译者按: Dockerfile 的语法非常简单,然而如何加快镜像构建速度,如何减少 Docker 镜像的大小却不是那么直观,需要积累实践经验.这篇博客可以帮助你快速掌握编写 Dockerfile 的技 ...
- Where Can I Download Full Installers for WebLogic Server
Where can I download full installers for the different versions of WebLogic Server (WLS)? Full insta ...
- Odoo / PS Cloud12版本中,产品变体功能如何使用
场景: 产品:陶瓷马克杯 产品颜色变体:红色.蓝色.白色 产品尺寸变体:10CM.12CM.15CM 每个变体都有不同价格维度 odoo / PS Cloud 专业实施开发 EMAIL:1715860 ...
- Android远程桌面助手(B1391)
ARDC(B1391), Download:https://files.cnblogs.com/files/we-hjb/ARDC%28B1391%29_EN.7z Android远程桌面助手(B13 ...
- Glide的 java.lang.RuntimeException: Expected instanceof GlideModule, but found:X.GlideModule@2e4554f
问题一 在添加过混淆规则后,App打包的时候,发现报错了 java.lang.RuntimeException: Expected instanceof GlideModule, but found: ...
- 使用Android服务,实现报警管理器和广播接收器
介绍 几乎在所有平台上都有很多进程运行背景,它们被称为服务.可能在Android平台中有一些服务可以执行长时间运行的操作,这些操作在处理时不需要用户交互. 在本文中,借助预定义的Android警报服务 ...
- JVM内存结构,运行机制
三月十号,白天出去有事情出去了一天,晚上刚到食堂就接到阿里电话, 紧张到不行,很多基础的问题都不知道从哪里说了orz: 其中关于JVM内存结构,运行机制,自己笔记里面有总结的,可当天还是一下子说不出来 ...