在Spring中使用@Async的@EventListener

时间:2016-05-12 06:57:05

标签: spring asynchronous event-handling

尝试结合@Async@EventListener注释启用异步事件处理,但我仍然看到侦听器正在发布线程中运行。

您可以在此处找到示例:

@SpringBootApplication
@EnableAsync
class AsyncEventListenerExample {

static final Logger logger = LoggerFactory.getLogger(AsyncEventListenerExample.class);

@Bean
TaskExecutor taskExecutor() {
    return new SimpleAsyncTaskExecutor();
}


static class MedicalRecordUpdatedEvent {

    private String id;

    public MedicalRecordUpdatedEvent(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "MedicalRecordUpdatedEvent{" +
                "id='" + id + '\'' +
                '}';
    }
}

@Component
static class Receiver {

    @EventListener
    void handleSync(MedicalRecordUpdatedEvent event) {
        logger.info("thread '{}' handling '{}' event", Thread.currentThread(), event);
    }

    @Async
    @EventListener
    void handleAsync(MedicalRecordUpdatedEvent event) {
        logger.info("thread '{}' handling '{}' event", Thread.currentThread(), event);
    }

}

@Component
static class Producer {

    private final ApplicationEventPublisher publisher;

    public Producer(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void create(String id) {
        publisher.publishEvent(new MedicalRecordUpdatedEvent(id));
    }

    @Async
    public void asynMethod() {
        logger.info("running async method with thread '{}'", Thread.currentThread());
    }
}

}

和我的测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AsyncEventListenerExample.class)
public class AsyncEventListenerExampleTests {

@Autowired
Producer producer;

@Test
public void createEvent() throws InterruptedException {

    producer.create("foo");

    //producer.asynMethod();


    // A chance to see the logging messages before the JVM exists.
    Thread.sleep(2000);

}
}

但是在日志中我看到@EventListener两个main都在2016-05-12 08:52:43.184 INFO 18671 --- [ main] c.z.e.async2.AsyncEventListenerExample : thread 'Thread[main,5,main]' handling 'MedicalRecordUpdatedEvent{id='foo'}' event 2016-05-12 08:52:43.186 INFO 18671 --- [ main] c.z.e.async2.AsyncEventListenerExample : thread 'Thread[main,5,main]' handling 'MedicalRecordUpdatedEvent{id='foo'}' event 主题中运行。

async

@EnableAsync基础架构初始化为TaskExecutor,异步.h

不确定我做错了什么。你能帮忙吗?

感谢。

使用Spring Boot 1.4.2.M2,所以Spring 4.3.0.RC1

3 个答案:

答案 0 :(得分:3)

Spring Framework 4.3.0.RC1中出现了一个回归,导致您遇到了这个问题。如果您使用SNAPSHOT,您的项目运行正常。

答案 1 :(得分:1)

onTicketUpdatedEvent也在主要的Thread中运行Spring Framework 4.2.4 Release,如下所示。 但是如果没有实现AsyncConfigurer,它将在SimpleAsyncTaskExecutor中运行。

@EnableAsync(proxyTargetClass = true)
@Component
@Slf4j
public class ExampleEventListener implements AsyncConfigurer {

    @Async
    @EventListener
    public void onTicketUpdatedEvent(TicketEvent ticketEvent) {
        log.debug("received ticket updated event");
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(100);
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

答案 2 :(得分:1)

我通过配置task-executor bean解决了我的问题,如下所示。

@Bean(name = "threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setMaxPoolSize(100);
    executor.initialize();
    return executor;
}

@Async("threadPoolTaskExecutor")
@EventListener
public void onTicketUpdatedEvent(TicketEvent ticketEvent) {
    log.debug("received ticket updated event");
}