尝试结合@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
答案 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");
}