Spring 4.2框架中注释驱动的事件监听器详解
事件交互已经成为很多应用程序不可或缺的一部分,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();
}
}
请注意,在事件中使用Domain域对象有明显的缺点,在一些场景下不可用。这里只是做代码示例。
顺便说一句,ExternalNotificationSender对象负责发送外部通知给已注册的用户(例如通过电子邮件、短信等方式)。
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。
7、总结
注释驱动的事件监听器是Spring框架4.2版中引入的新特性,它减少了Spring项目的样板代码,使得代码更加灵活,尤其是在小数量事件的需求时体现更为明显。
Spring 4.2框架中注释驱动的事件监听器详解的更多相关文章
- Spring 框架中注释驱动的事件监听器详解
事件交互已经成为很多应用程序不可或缺的一部分,Spring框架提供了一个完整的基础设施来处理瞬时事件.下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器. 1.早期的方式 在早期,组件要 ...
- 在.Net框架中 C# 实现多线程的同步方法详解
本文主要描述在C#中线程同步的方法.线程的基本概念网上资料也很多就不再赘述了.直接接入主题,在多线程开发的应用中,线程同步是不可避免的.在.Net框架中,实现线程同步主要通过以下的几种方式来实现,在M ...
- Laravel5.4框架中视图共享数据的方法详解
本文实例讲述了Laravel5.4框架中视图共享数据的方法.分享给大家供大家参考,具体如下: 每个人都会遇到这种情况:某些数据还在每个页面进行使用,比如用户信息,或者菜单数据,最基本的做法是在每个视图 ...
- spring框架中AOP思想与各种配置详解
Spring中提供两种AOP支持: 1.基于代理的经典AOP 2.Aspectj注解配置AOP 首先我们先了解什么是AOP,AOP(Aspect Oriented Programming ...
- 项目实践之工作流引擎基本文档!Activiti工作流框架中流程引擎API和服务详解
流程引擎的API和服务 流程引擎API(ProcessEngine API)是与Activiti打交道的最常用方式 Activiti从ProcessEngine开始.在ProcessEngine中,可 ...
- 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 MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(五)
这是本系列的最后一篇,主要讲一下FreeMarker模板引擎的基本概念与常用指令的使用方式. 一.FreemMarker基本概念 FreemMarker是一个用Java语言编写的模板引 ...
随机推荐
- AC日记——小行星 洛谷 P2711
题目背景 pid=3437 题目描述 星云中有n颗行星,每颗行星的位置是(x,y,z).每次可以消除一个面(即x,y或z坐标相等)的行星,但是由于时间有限,求消除这些行星的最少次数. 输入输出格式 输 ...
- Java 界面编程【03】事件监听
当你把界面都设计好了,总需要添加相应的执行动作给组件,在JAVA中有相应的时间处理机制,叫做“监听器”,给组件添加相应执行动作的过程叫做“注册”,其中的“监听器”是一个接口,里面包含了相应的执行函数, ...
- 蚂蚁金服CTO程立:金融级分布式交易的技术路径
总结: 强一致的微服务 oceanbase里面的投票选举以及多中心多地部署 单元化市异地多活的基础.支付宝是异地多活和容灾结合,而容灾的基础也是单元化.基于单元化进行单元的调度.部署.容灾. 混合云架 ...
- POJ 3660 Cow Contest 传递闭包+Floyd
原题链接:http://poj.org/problem?id=3660 Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- Noip2017赛前的一些记录
前言 已经退役整整五个月了....选考以后终于又摸上了键盘.... 但是码力已经大不如前了........ 距离比赛也就只有一星期了....那就胡乱的做一些题目吧QAQ 这里是一些根据算法分类的咋杂题 ...
- springboot快速集成swagger
今天技术总监说:小明,我们本次3.0改造,使用swagger2.0作为前后端分离的接口规范,它可以一键生成前后端的API,一劳永逸--小明:??? Spring Boot 框架是目前非常流行的微服务框 ...
- 数字类型(NSInteger,NSUInteger,NSNumber)
在Objective-C中,我们可以使用c中的数字数据类型,int.float.long等.它们都是基本数据类型,而不是对象.也就是说,不能够向它们发送消息.然后,有些时候需要将这些值作为对象使用. ...
- java资源分享、面试题资料、分布式大数据
马士兵大数据_架构师(1) 链接:http://pan.baidu.com/s/1qYTW1m0 密码:lxjd spring Cloud 链接:http://pan.baidu.com/s/1bzG ...
- [LeedCode OJ]#85 Maximal Rectangle
[ 声明:版权全部,转载请标明出处.请勿用于商业用途. 联系信箱:libin493073668@sina.com] 题目链接:https://leetcode.com/problems/maxima ...
- 阿里巴巴为什么主推HSF?比Dubbo有哪些优势?
作者:匿名用户链接:https://www.zhihu.com/question/39560697/answer/187538165来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...