Spring 4.2框架中注释驱动的事件监听器详解

简介: Spring 4.2框架中注释驱动的事件监听器详解 事件交互已经成为很多应用程序不可或缺的一部分,Spring框架提供了一个完整的基础设施来处理瞬时事件。下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器。

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项目的样板代码,使得代码更加灵活,尤其是在小数量事件的需求时体现更为明显。

目录
相关文章
|
21天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
21天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
11天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
557 8
|
9天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
9天前
|
存储 NoSQL Java
Spring Session框架
Spring Session 是一个用于在分布式环境中管理会话的框架,旨在解决传统基于 Servlet 容器的会话管理在集群和云环境中的局限性。它通过将用户会话数据存储在外部介质(如数据库或 Redis)中,实现了会话数据的跨服务器共享,提高了应用的可扩展性和性能。Spring Session 提供了无缝集成 Spring 框架的 API,支持会话过期策略、并发控制等功能,使开发者能够轻松实现高可用的会话管理。
Spring Session框架
|
16天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
27 2
|
16天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
25天前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
104 1
|
29天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
58 2
|
1月前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
99 2
下一篇
无影云桌面