java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring ApplicationEvent

Java Spring ApplicationEvent 代码示例解析

作者:兔子蟹子

本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、事务绑定、执行顺序),对Java Spring ApplicationEvent概念相关知识感兴趣的朋友一起看看吧

一、Spring 事件机制核心概念

1. 事件驱动架构模型

2. 核心组件

组件作用实现方式
ApplicationEvent事件基类自定义事件需继承
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;
    }
}

关键点

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()));
    }
}

发布模式

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) {
        // 处理知识逻辑
    }
}

监听器特点

三、高级应用技巧

1. 条件监听

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

2. 异步事件处理

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

配置要求

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        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) {
    // 事务提交后执行
}

事务阶段选项

四、最佳实践

1. 事件设计原则

2. 性能优化

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() {
        // 准备测试事件
        ImportedKnowledgeEvent 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());
}

六、常见问题解决方案

循环事件触发

// 使用标记防止循环
public void imports() {
    if (!EventContext.isEventProcessing()) {
        eventPublisher.publishEvent(...);
    }
}

总结

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

在实际应用中,应结合:

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

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

您可能感兴趣的文章:
阅读全文