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的启动流程也就有了一个整体的认 ...
随机推荐
- Java 核心系列教程
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 关于Java核心技术学习积累的例子,是初学者及核心技术巩固的最 ...
- python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍
目录 python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍.md 一丶字典 1.字典的定义 2.字典的使用. 3.字典的常用方法. python学习第八讲,python ...
- 【Oracle学习笔记】游标
1. 分类 常见的游标可分为显示游标.隐式游标.静态游标和动态游标四大类: 1.1 显示游标 显式是相对与隐式cursor而言的,就是有一个明确的声明的cursor.显式游标的声明类似如下: delc ...
- 关于PHP打开之后找不到数据库问题的记录
昨天发现了一个奇怪的问题,一直正常使用的某个网站打不开了,这个网站是PHP写的,数据库用的my sql.打开之后就提示密码错误,无法正常打开页面. 由于平时基本上没用过my sql,按照使用sql s ...
- SQL—访问操作(2)
上一篇介绍了数据访问操作的两种方法,接下来把剩下两个操作简单介绍一下: ExecuteNonQuery()的操作:对数据库进行增加.修改.删除 返回类型是 int 代表受影响的行数 返回的结果如果是 ...
- ideal中spring的xml文件没有提示的问题
ideal中spring的xml文件没有提示的问题 今天第一次用ideal来练习spring,发现和视频中老师不一样,我的没有提示.老师的视频里,他写了个<mvc:a 就会有一系列的提示,然 ...
- Java 适配器(Adapter)模式
一.什么是适配器模式: 把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作. 二.适配器模式的分类和结构: 适配器模式有类的适配器模式和对象的适配器模式两种. 1.类的适配器 ...
- zookeeper安装以及遇到的一些坑
最近项目中用到了storm,然后storm中用到了zookeeper,然后今天抽空整理一下zookeeper的安装使用,原来后期再慢慢学习. 本篇文档,操作部分是摘自其他博客,里边的问题分析是自己在实 ...
- MyDAL - .IsExistAsync() 使用
索引: 目录索引 一.API 列表 .IsExistAsync() 用于 单表 / 多表连接 查询 二.API 单表-便捷 方法 举例 1.单表-便捷, 判断是否存在方法 var date = Dat ...
- Linux(Manjaro) -Docker 安装及基本配置
Linux(Manjaro) -Docker 安装及基本配置 基本安装 # Pacman 安装 Docker sudo pacman -S docker # 启动docker服务 sudo syste ...