Spring5参考指南:事件Event
文章目录
Spring提供了很方便的事件的处理机制,包括事件类ApplicationEvent和事件监听类ApplicationListener。 他实现的是设计者模式,如果实现了ApplicationListener接口的bean部署到Spring容器中,则每次ApplicationEvent发布到ApplicationContext时,都会通知该bean。
从Spring4.2开始,提供了基于注解的事件,即事件对象不一定要从ApplicationEvent来扩展。Spring会自动将其封装成一个事件对象。
下面是Spring的标准事件描述:
| Event | 解释 |
|---|---|
| ContextRefreshedEvent | 在初始化或刷新ApplicationContext时发布(例如,通过在ConfigurableApplicationContext接口上使用refresh()方法)。这里,“初始化”意味着加载所有bean,检测并激活后处理器bean,预先实例化单例,并且ApplicationContext对象准备好使用。只要上下文未关闭,只要所选的ApplicationContext实际上支持此类“热”刷新,就可以多次触发刷新。例如,XMLWebApplicationContext支持热刷新,但GenericApplicationContext不支持。 |
| ContextStartedEvent | 在可配置的ApplicationContext接口上使用start()方法启动ApplicationContext时发布。这里,“启动”意味着所有生命周期bean都会收到一个显式的启动信号。通常,此信号用于在显式停止后重新启动bean,但也可以用于启动尚未配置为自动启动的组件(例如,初始化时尚未启动的组件)。 |
| ContextStoppedEvent | 在可配置的ApplicationContext接口上使用stop()方法停止ApplicationContext时发布。这里,“停止”意味着所有生命周期bean都会收到一个明确的停止信号。停止的上下文可以通过start()调用重新启动。 |
| ContextClosedEvent | 在可配置的ApplicationContext接口上使用close()方法关闭ApplicationContext时发布。这里,“关闭”意味着所有的单例beans都被销毁了。封闭的环境达到了生命的尽头。无法刷新或重新启动。 |
| RequestHandledEvent | 一个特定于Web的事件,告诉所有bean HTTP请求已被服务。此事件在请求完成后发布。此事件仅适用于使用Spring的DispatcherServlet的Web应用程序。 |
基于继承的Event
你也可以自定义事件,下面是一个继承ApplicationEvent的例子:
public class BlackListEvent extends ApplicationEvent {
private final String address;
private final String content;
public BlackListEvent(Object source, String address, String content) {
super(source);
this.address = address;
this.content = content;
}
}
若要发布自定义ApplicationEvent,在ApplicationEventPublisher上调用PublishEvent()方法。通常可以通过实现ApplicationEventPublisherAware接口来实现,如下所示:
public class EmailService implements ApplicationEventPublisherAware {
private List<String> blackList;
private ApplicationEventPublisher publisher;
public void setBlackList(List<String> blackList) {
this.blackList = blackList;
}
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void sendEmail(String address, String content) {
if (blackList.contains(address)) {
publisher.publishEvent(new BlackListEvent(this, address, content));
return;
}
}
}
在配置时,Spring容器检测到EmailService实现了ApplicationEventPublisherAware,并自动调用setApplicationEventPublisher()。实际上,传入的参数是Spring容器本身。您正在通过其applicationEventPublisher接口与应用程序上下文进行交互。
要接收定制的applicationEvent,可以创建一个实现applicationListener的类,并将其注册为SpringBean。下面的示例显示了这样的类:
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
}
这里使用了ApplicationListener 的BlackListEvent泛型。意味着onApplicationEvent()方法可以保持类型安全,避免任何向下强制转换的需要。
但请注意,默认情况下,事件侦听器同步接收事件。这意味着publishEvent()方法将一直阻塞,直到所有侦听器完成对事件的处理。
下面是注册和配置bean的例子:
<bean id="emailService" class="example.EmailService">
<property name="blackList">
<list>
<value>known.spammer@example.org</value>
<value>known.hacker@example.org</value>
<value>john.doe@example.org</value>
</list>
</property>
</bean>
<bean id="blackListNotifier" class="example.BlackListNotifier">
<property name="notificationAddress" value="blacklist@example.org"/>
</bean>
Spring的事件机制是为同一应用程序上下文中SpringBean之间的简单通信而设计的。对于更复杂的企业集成需求,可以使用Spring Integration的AMQP模型来处理。
基于注解的Event
从Spring4.2开始,您可以使用EventListener注解在托管bean的任何公共方法上注册事件侦听器。BlackListNotifier程序可以改写如下:
public class BlackListNotifierAnnotation {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
@EventListener
public void processBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
}
如果您的方法应该监听多个事件,或者您想要定义它而不使用任何参数,那么也可以在注解本身上指定事件类型。以下示例显示了如何执行此操作:
@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
public void handleContextStart() {
}
还可以使用定义spEL表达式的注解的条件属性添加其他运行时筛选,该表达式应与实际调用特定事件的方法相匹配。
下面的例子显示了如何重写通知程序,以便仅在事件的内容属性等于my-event时调用:
@EventListener(condition = "#blEvent.content == 'my-event'")
public void processBlackListSPELEvent(BlackListEvent blEvent) {
// notify appropriate parties via notificationAddress...
}
下表列出了上下文可用的项,以便您可以将它们用于条件事件处理:
| name | Location | 描述 | 例子 |
|---|---|---|---|
| Event | root object | 真实的ApplicationEvent | #root.event |
| Arguments array | root object | 调用目标的参数 | #root.args[0] |
| Argument name | evaluation context | 任何方法参数的名称。如果由于某种原因,名称不可用(例如,因为没有调试信息),参数名称也可以在 #a<#arg>下使用,其中#arg表示参数索引(从0开始)。 | #blEvent or #a0 (也可以使用 #p0 or #p<#arg>) |
异步侦听器
如果希望特定的侦听器异步处理事件,可以重用常规的@Async支持。下面是@Async的例子:
@Async
@EventListener
public void processBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
Listeners排序
如果需要先调用一个监听器,然后再调用另一个监听器,则可以将@order注解添加到方法声明中,如下所示:
@EventListener
@Order(12)
public void processBlackListEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
本文的例子可以参考: event
更多教程请参考flydean的博客
Spring5参考指南:事件Event的更多相关文章
- Spring5参考指南:IOC容器
文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...
- Spring5参考指南:基于注解的容器配置
文章目录 @Required @Autowired @primary @Qualifier 泛型 @Resource @PostConstruct和@PreDestroy Spring的容器配置可以有 ...
- Spring5参考指南:容器扩展
文章目录 BeanPostProcessor自定义bean BeanFactoryPostProcessor自定义配置元数据 使用FactoryBean自定义实例化逻辑 Spring提供了一系列的接口 ...
- Spring5参考指南:Bean的生命周期管理
文章目录 Spring Bean 的生命周期回调 总结生命周期机制 startup和Shutdown回调 优雅的关闭Spring IoC容器 Spring Bean 的生命周期回调 Spring中的B ...
- Spring5参考指南:Bean作用域
文章目录 Bean作用域简介 Singleton作用域 Prototype作用域 Singleton Beans 中依赖 Prototype-bean web 作用域 Request scope Se ...
- Spring5参考指南:依赖注入
文章目录 依赖注入 依赖注入的配置详解 depends-on lazy-init 自动装载 方法注入 依赖注入 依赖注入就是在Spring创建Bean的时候,去实例化该Bean构造函数所需的参数,或者 ...
- Spring5参考指南:Bean的创建
文章目录 Spring容器中的Bean Bean的命名 Bean的实例化 Spring容器中的Bean Bean在Spring中就是一个业务组件,我们通过创建各种Bean来完成最终的业务逻辑功能. 在 ...
- Spring5参考指南:AspectJ高级编程之Configurable
文章目录 遇到的问题 @Configurable 原理 重要配置 遇到的问题 前面的文章我们讲到了在Spring中使用Aspect.但是Aspect的都是Spring管理的Bean. 现在有一个问题, ...
- Spring5参考指南:AOP代理
文章目录 AOP代理 AOP Proxies原理 AOP代理 通常来说Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,可以代理具体的类对象. Spring ...
随机推荐
- mysql--使用left join条件查询时加where条件的问题
场景:为一个活动添加指导文件,每一个活动会对应多种指导文件类型,进入每一个活动的设置指导文件页面后所呈现的指导文件类型相同,查询时,使用指导文件类型表LEFT JOIN指导文件表,要求指导文件类型全部 ...
- 【php】PDO
一.PDO的定义 1.pdo(php data object)是一个数据库的抽象层 二.PDO的特点 1.跨数据库 2.支持预处理 3.支持事务处理 三.PDO的使用 1.基本使用 (1)实例化pdo ...
- linux 配置 python3 CGI
文章更新于:2020-03-04 注1:安装 python 参见: python 的安装使用和基本语法 注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务 ...
- JAVA中的==和equals()的区别
一.先来说说Java的基本数据类型和引用类型 八大基本数据类型:Byte,short,int,long,double,folat,boolean,char,其中占一个字节的是byte,short和ch ...
- Python爬虫利器 cURL你用过吗?
hello,小伙伴们,今天给大家分享的开源项目是一个python爬虫利器,感兴趣的小伙伴看完这篇文章不妨去尝试一下,这个开源项目就是curlconverter,不知道小伙伴们分析完整个网站后去code ...
- template_homepage
homepage用到的方法 使用 {% for ... in ...%} 加 {% endfor %} 实现循环结构 举例: {% for post in posts %} <p style ...
- 数组的连接和截取(contact和slice和splice)
<script> var arr1 = ["a","b","c"]; var arr2 = [1,2,3]; //concat把 ...
- Xcode 6.3.1Mac版 V6.4.Beta3免费下载
Xcode for mac是Mac OS系统以及IOS系统开发者专用于构建 Mac OS X 及 iOS 应用程序的完整工具集 - Xcode 5 的工具经过重新设计,它们的性能更优秀.使用更容易,能 ...
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(八)之Reusing Classes
The trick is to use the classes without soiling the existing code. 1. composition--simply create obj ...
- linux常用命令整理(一)
1.sort(排序) 典型例题:sort -t: -k3n /etc/passwd 以冒号为分隔符根据第三个域的数字大小进行排序(默认分隔符是空格) 2.uniq(去除文件中的连续重复行) 典型例题: ...