Java Spring ApplicationEvent 代码示例解析

2025-06-18 04:50

本文主要是介绍Java Spring ApplicationEvent 代码示例解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、...

一、Spring 事件机制核心概念

1. 事件驱动架构模型

  • 发布-订阅模式:解耦事件生产者和消费者
  • 观察者模式:监听器监听特定事件
  • 事件驱动优势
    • 组件间松耦合
    • 系统扩展性好
    • 支持异步处理
    • 事件溯源支持

2. 核心组件

组件作用实现方式
ApplicationEvent事件基类android自定义事件需继承
ApplicationEventPublisher事件发布接口通过Spring容器注入
ApplicationListener事件监听接口实现接口或使用@EventListener

二、代码示例解析

1. 事件定义 (KnowledgeService.java)

@Getter
public static final class ImportedKnowledgeEvent extends ApplicationEvent {
    private final Knowledge knowledge;
    private final KWDocument document;
    // 构造器1:只有knowledge
    public ImportedKnowledgeEvent(Object source, Knowledge knowledge) {
        super(source);
        this.knowledge = knowledge;
        this.document = null;
    }
    // 构造器2:knowledge + document
    public ImportedKnowledgeEvent(Object source, Knowledge knowledge, KWDocument document) {
        super(source);
        this.knowledge = knowledge;
        this.document = document;
    }
}

关键点

  • 继承ApplicationEvent基类
  • 使用final字段保证事件不可变性
  • 提供多种构造器支持不同场景
  • 使用@Getter(Lombok)提供访问方法

2. 事件发布 (KnowledgeService.java)

@Service
public class KnowledgeService {
    @Autowired
    protected ApplicationEventPublisher eventPublisher;
    public void imports() {
        // 发布简单知识导入事件
        eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge()));
        // 发布知识+文档导入事件
        eventPublisher.publishEvent(new ImportedKnowledgeEvent(this, new Knowledge(), new KWDocument()));
    }
}

发布模式

  • 注入ApplicationEventPublisher
  • 创建事件对象(包含业务数据)
  • 调用publishEvent()发布
  • 支持多种事件类型重载

3. 事件监听 (KnowledgeRagflowService.java)

@Service
public class KnowledgeRagflowService extends KnowledgeService {
    @EventListener
    public void importedKnowledge(KnowledgeService.ImportedKnowledgeEvent event) {
        if (event.getDocument() != null) {
            dealDocument(event.getKnowledge(), event.getDocument());
        } else {
            dealKnowledge(event.getKnowledge());
        }
    }
    private void dealDocument(Knowledge knowledge, Document document) {
        // 处理文档逻辑
    }
    private void dealKnowledge(Knowledge knowledge) {
        // 处理知识逻辑
    }
}

监听器特点

  • 使用@EventListener注解简化实现
  • 方法参数决定监听的事件类型
  • 支持事件内容判断(区分有无document)
  • 私有方法封装具体处理逻辑

三、高级应用技巧

1. 条件监听

@EventListener(condition = "#event.document != null")
public void handleDocumentEvent(ImportedKnowledgeEvent event) {
    // 仅处理包含document的事件
}

2. 异步事件处理

@Async
@EventListener
public void asyncHandleEvent(ImportedKnowledgeEvent event) {
    // 异步处理耗时操作
}

配置要求

  • 主类添加@EnableAsync
  • 配置线程池:
@Configuration
@EnableAsync
public chttp://www.chinasem.cnlass AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize(UtufzYDdwi);
        return executor;
    }
}

3. 监听器执行顺序

@Order(1)
@EventListener
public void firstListener(ImportedKnowledgeEvent event) {
    // 最先执行
}
@Order(2)
@EventListener
public void secondListener(ImportedKnowledgeEvent event) {
    // 其次执行
}

4. 事务绑定事件

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void afterCommitEvent(ImportedKnowledgeEvent event) {
    // 事务提交后执行
}

事务阶段选项

  • AFTER_COMMIT(默认):事务成功提交后
  • AFTER_ROLLBACK:事务回滚后
  • AFTER_COMPLETION:事务完成后(提交或回滚)
  • BEFORE_COMMIT:事务提交前

四、最佳实践

1. 事件设计原则

  • 单一职责:一个事件只携带一种业务变更
  • 不可变性:事件发布后内容不可修改
  • 上下文完整:包含所有必要业务数js
  • 命名规范:使用过去时态(如ImportedKnowledgeEvent

2. 性能优化

  • 同步/异步选择

Java Spring ApplicationEvent 代码示例解析

  • 批量处理:对高频事件进行批量合并
  • 事件过滤:在监听器内部添加条件判断

3. 错误处理

@EventListener
public void handleEvent(ImportedKnowledgeEvent event) {
    try {
        // 业务处理
    } catch (Exception e) {
        // 1. 记录错误日志
        // 2. 发布错误处理事件
        // 3. 重试机制(如Spring Retry)
    }
}

4. 测试策略

@SpringBootTest
class KnowledgeEventTest {
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @MockBean
    private KnowledgeRagflowService ragflowService;
    @Test
    void shouldTriggerListenerWhenPublishEvent() {
        // 准备测试事件
        ImportedKnowledgeChina编程Event event = new ImportedKnowledgeEvent(this, new Knowledge());
        // 发布事件
        eventPublisher.publishEvent(event);
        // 验证监听器调用
        verify(ragflowService, timeout(1000)).importedKnowledge(event);
    }
}

五、典型应用场景

  • 业务状态变更通知

    • 知识导入完成通知
    • 文档处理状态更新
  • 跨模块协作

    • 知识导入后触发索引更新
    • 文档处理完成后通知搜索服务

系统生命周期事件

@EventListener
public void onApplicationReady(ContextRefreshedEvent event) {
    // 应用启动完成后初始化资源
}

审计日志记录

@EventListener
public void auditLog(ImportedKnowledgeEvent event) {
    log.info("Knowledge imported: {}", event.getKnowledge().getId());
}
  • 业务流程编排

Java Spring ApplicationEvent 代码示例解析

六、常见问题解决方案

  • 监听器未触发

    • 检查事件类型是否匹配
    • 确认监听器在Spring容器中
    • 验证事件是否成功发布

循环事件触发

// 使用标记防止循环
public void imports() {
    if (!EventContext.isEventProcessing()) {
        eventPublisher.publishEvent(...);
    }
}
  • 事件数据过大

    • 改为传递引用ID而非整个对象
    • 使用DTO精简数据
    • 添加@Lazy注解延迟加载
  • 监听器执行顺序问题

    • 使用@Order明确顺序
    • 拆分事件避免依赖

总结

Spring ApplicationEvent 提供了强大的事件驱动编程模型,通过示例中的KnowledgeServiceKnowledgeRagflowService展示了:

  • 如何定义包含业务数据的事件
  • 多种事件发布方式
  • 使用@EventListener简化监听器实现
  • 根据事件内容执行不同处理逻辑

在实际应用中,应结合:

  • 异步处理提升性能
  • 事务绑定确保数据一致性
  • 条件过滤优化事件处理
  • 完善错误处理机制

遵循"高内聚、低耦合"原则,合理使用事件驱动架构,可以显著提升系统的扩展性和可维护性。

到此这篇关于Java Spring ApplicationEvent 代码示例解析的文章就介绍到这了,更多相关Spring ApplicationEvent 内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Java Spring ApplicationEvent 代码示例解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155106

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

Python如何去除图片干扰代码示例

《Python如何去除图片干扰代码示例》图片降噪是一个广泛应用于图像处理的技术,可以提高图像质量和相关应用的效果,:本文主要介绍Python如何去除图片干扰的相关资料,文中通过代码介绍的非常详细,... 目录一、噪声去除1. 高斯噪声(像素值正态分布扰动)2. 椒盐噪声(随机黑白像素点)3. 复杂噪声(如伪

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja