场景:
在项目中经常使用事件发布和监听但是正常情况下这是个同步操作,ApplicationEventPublisher、ApplicationListener<Event>现将其改成异步操作处理方式如下。
实现方式
方式一:使用CompletableFuture类
定义监听事件
public class TaskCopyEvent extends ApplicationEvent {
public TaskCopyEvent(Object source) {
super(source);
}
}
发布事件
在需要的地方注入事件发布器
@Autowired
ApplicationEventPublisher eventPublisher;CompletableFuture.runAsync(() -> {
eventPublisher.publishEvent(new TaskCopyEvent(task));
});
监听事件
@Component
public class TaskCopyListener implements ApplicationListener<TaskCopyEvent> {
@Override
public void onApplicationEvent(TaskCopyEvent event) {
//执行你的具体的逻辑
}
}
方式二:使用@Async注解
需要做如下配置
@Configuration
@EnableAsync
public class AppConfig {}
@Component
public class TaskCopyListener implements ApplicationListener<TaskCopyEvent> {
@Async
@Override
public void onApplicationEvent(TaskCopyEvent event) {
//执行你的具体的异步逻辑
}
}
@Async
@Component
public class TaskCopyListener implements ApplicationListener<TaskCopyEvent> {
@Override
public void onApplicationEvent(TaskCopyEvent event) {
//执行你的具体的异步逻辑
}
}
注意事项
1.@Async 可以放在监听器的方法或者类上
2.@Async 生效的开关要启用,
传统是在xml中配置,
<
task:annotation-driven
executor
=
"asyncExecutor"
/>
<
task:executor
id
=
"asyncExecutor"
pool-size
=
"2-4"
queue-capacity
=
"10"
/>
也可以用基于注解的配置方式
@Configuration
@EnableAsync
public class AppConfig {}
3.确保配置类中的注解或监听器中的注解在spring的扫描范围内
总结
两种异步的出发点不同,
CompletableFuture是直接将事件发布的操作放到异步操作中,
而@Async是将监听操作从而实现了异步。