Spring @EventListener 异步中使用condition的问题及处理

目录
  • @EventListener 异步中使用condition的问题
    • condition 使用例子如
    • 需要对事件用condition进行区分同步异步
    • 修正的做法,是使用两个事件区分即
  • Spring事件的condition使用说明
    • 如下是我的事件处理代码声明
    • 在controller中我如此调用
    • 如下就解决了

@EventListener 异步中使用condition的问题

@EventListener是spring在4.2+推出的更好的使用spring事件架构的方式,并且异步方式也很好设定

但是在spring4.2.7版本上使用eventlistener的condition 的使用需要注意以下情况可能失效:

condition 使用例子如

@EventListener(condition = "#event.isAsync")

1. 需要对同一个事件进行区分同步异步

2. 使用condition来进行过滤

例如:

需要对事件用condition进行区分同步异步

@Async
@EventListener(condition = "#event.isAsync")
public void handleOrderCreatedEventAsync(TestEvent event) {
}  

@EventListener(condition = "#event.isAsync == false")
public void handleOrderCreatedEvent(TestEvent event) {
}

修正的做法,是使用两个事件区分即

@Async
@EventListener
public void handleOrderCreatedEventAsync(TestEventAsync event) {
}  

@EventListener
public void handleOrderCreatedEvent(TestEvent event) {
}

还不清楚,在更高的版本上是否已经有进一步的修正,待以后研究

Spring事件的condition使用说明

在开发中使用了spring的事件机制,但是发现了一个问题:如果多个发布的事件对象是同一个类型,而除了使用了这个事件类型作为参数的事件处理方法还是多个,那就无法区分到底要执行哪个处理方法了,除非你想每个处理方法都执行。

如下是我的事件处理代码声明

@Async
 @EventListener
 public void handleExport(ExportExcelMessage<DTO> exportMsg){
}

这里的业务场景是异步导出Excel。直接用@EventListener来声明事件处理方法。

在controller中我如此调用

publisher.publish(new ExportExcelMessage<>(reqDTO));

ExportExcelMessage是个事件对象,包含事件基本属性,reqDTO就是查询条件数据了。

开始感觉没有问题。后来突然有一个相同类型入参(reqDTO)的导出功能。

这样处理方法就有问题了。出现处理方法的重复执行。

随便上网一查,简单,EventListener直接加condition属性就搞定。网上是这样的;

@EventListener(condition="#exportMsg.source=='xxx'")

其中这个source就是ExportExcelMessage类的的一个属性,用来区分到底是谁发起的事件。

使用SPel表达式,直接引用的方法的参数名,单我试验是不行的,异常显示exportMsg应该是个null。

估计应该能在方法参数上加注解来处理吧,就像Contrller的@WebParam一样,但我一时也没找到。

最后,直接看人家的代码注释,。。。。自己笨的可以了。

如下就解决了

@EventListener(condition = "#root.args[0].source == 'xxx'")

root.args就是参数的数组,直接用下标取就好了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈SpringBoot中的@Conditional注解的使用

    概述 Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot 是根据配置文件中的内容,决定是否创建 bean,以及如何创建 bean 到 Spring 容器中,而 Spring boot 自动化配置的核心控制,就是 @Conditional 注解. @Conditional 注解是 Spring 4.0 之后出的一个注解,与其搭配的一个接口是 Condition,@Conditional 注解会根据具体的条件决定是否

  • Spring实战之缓存使用condition操作示例

    本文实例讲述了Spring实战之缓存使用condition操作.分享给大家供大家参考,具体如下: 一 配置文件 <?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  • 使用Spring事件机制实现异步的方法

    当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法. 事件本身 事件是一个自定义的类,需要继承Spring提供的ApplicationEvent. @Data public class MyEvent extends ApplicationEvent { private String msg; public MyEvent(Object source, String msg) { super(source); this.msg =

  • 基于SpringBoot核心原理(自动配置、事件驱动、Condition)

    前言 SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本非常低,但是学习其实现原理的成本大大增加,需要先了解熟悉Spring原理.如果还不清楚Spring原理的,可以先查看博主之前的文章,本篇主要分析SpringBoot的启动.自动配置.Condition.事件驱动原理. 正文 启动原理 SpringBoot启动非常简单,因其内置了Tomcat,所以只需要通过下面几种方式启动即可: @SpringBootApplication(scanBas

  • Spring TransactionalEventListener事务未提交读取不到数据的解决

    目录 一.背景 二.问题分析 2.1.mysql隔离级别 2.2.问题原因分析 三.解决问题方案 3.1.方式一 3.2.方式二 四.使用案例 一.背景 业务处理过程,发现了以下问题,代码一是原代码能正常执行,代码二是经过迭代一次非正常执行代码 代码一:以下代码开启线程后,代码正常执行 ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQ

  • Spring @EventListener 异步中使用condition的问题及处理

    目录 @EventListener 异步中使用condition的问题 condition 使用例子如 需要对事件用condition进行区分同步异步 修正的做法,是使用两个事件区分即 Spring事件的condition使用说明 如下是我的事件处理代码声明 在controller中我如此调用 如下就解决了 @EventListener 异步中使用condition的问题 @EventListener是spring在4.2+推出的更好的使用spring事件架构的方式,并且异步方式也很好设定 但是

  • 浅谈Java中spring 线程异步执行

    多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了Java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说如何使用spring来处理并发事务: 1.了解 TaskExecutor接口 Spring的TaskExecutor接口等同于java.util.concurrent.Executor接口. 实际上,它存在的主要原因是为了在使用线程池的时候,将对Java5的依赖抽象出来. 这个接口只有一个方法exe

  • 浅谈Spring @Async异步线程池用法总结

    本文介绍了Spring @Async异步线程池用法总结,分享给大家,希望对大家有帮助 1. TaskExecutor spring异步线程池的接口类,其实质是Java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程. 2. SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作.只适用于不需要多线程的地方 3. Conc

  • 深入理解spring boot异步调用方式@Async

    本文主要给大家介绍了关于spring boot异步调用方式@Async的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 1.使用背景 在日常开发的项目中,当访问其他人的接口较慢或者做耗时任务时,不想程序一直卡在耗时任务上,想程序能够并行执行,我们可以使用多线程来并行的处理任务,也可以使用spring提供的异步处理方式@Async. 2.异步处理方式 调用之后,不返回任何数据. 调用之后,返回数据,通过Future来获取返回数据 3.@Async不返回数据 使用@EnableAsyn

  • 详解Spring Boot 异步执行方法

    最近遇到一个需求,就是当服务器接到请求并不需要任务执行完成才返回结果,可以立即返回结果,让任务异步的去执行.开始考虑是直接启一个新的线程去执行任务或者把任务提交到一个线程池去执行,这两种方法都是可以的.但是 Spring 这么强大,肯定有什么更简单的方法,就 google 了一下,还真有呢.就是使用 @EnableAsync 和 @Async 这两个注解就 ok 了. 给方法加上 @Async 注解 package me.deweixu.aysncdemo.service; public int

  • spring boot异步(Async)任务调度实现方法

    在没有使用spring boot之前,我们的做法是在配置文件中定义一个任务池,然后将@Async注解的任务丢到任务池中去执行,那么在spring boot中,怎么来实现异步任务的调用了,方法更简单. 我们还是结合前面 spring boot整合JMS(ActiveMQ实现) 这篇博客里面的代码来实现. 一.功能说明 消费者在监听到队列里面的消息时,将接收消息的任务作为异步任务处理. 二.代码修改 消费者1: package com.chhliu.springboot.jms; import or

  • Spring Boot JPA中java 8 的应用实例

    上篇文章中我们讲到了如何在Spring Boot中使用JPA. 本文我们将会讲解如何在Spring Boot JPA中使用java 8 中的新特习惯如:Optional, Stream API 和 CompletableFuture的使用. Optional 我们从数据库中获取的数据有可能是空的,对于这样的情况Java 8 提供了Optional类,用来防止出现空值的情况.我们看下怎么在Repository 中定义一个Optional的方法: public interface BookRepos

  • Spring Boot使用Spring的异步线程池的实现

    前言 线程池,从名字上来看,就是一个保存线程的"池子",凡事都有其道理,那线程池的好处在哪里呢? 我们要让计算机为我们干一些活,其实都是在使用线程,使用方法就是new一个Runnable接口或者新建一个子类,继承于Thread类,这就会涉及到线程对象的创建与销毁,这两个操作无疑是耗费我们系统处理器资源的,那如何解决这个问题呢? 线程池其实就是为了解决这个问题而生的. 线程池提供了处理系统性能和大用户量请求之间的矛盾的方法,通过对多个任务重用已经存在的线程对象,降低了对线程对象创建和销毁

  • Spring @Cacheable注解中key的使用详解

    目录 Spring @Cacheable注解中key使用 下面是几个使用参数作为key的示例 condition属性指定发生的条件 @CachePut @CacheEvict allEntries属性 beforeInvocation属性 @Caching 使用自定义注解 @Cacheable 拼接key Spring @Cacheable注解中key使用 key属性是用来指定Spring缓存方法的返回结果时对应的key的.该属性支持SpringEL表达式.当我们没有指定该属性时,Spring将

  • SpringBoot中的Condition包下常用条件依赖注解案例介绍

    目录 一.@ConditionalOnClass() Spring中存在指定class对象时,注入指定配置 1.首先引入pom依赖 2.实体类测试对象 3.定义@ConditionalOnClass()配置类 4.启动类测试 二.注入指定配置 1.首先引入pom依赖 2.实体类测试对象 3.定义@ConditionalOnMissingClass()配置类 4.启动类测试 三.加载指定配置 1.首先引入pom依赖 2.实体类测试对象 2.1 引入条件判断实体类 3.定义@ConditionalO

随机推荐