题记
该方法适用于消息发布消费的场景,支持异步,可以理解为更为解耦的线程池,更灵活的用法可以服务A引用服务B的maven依赖,B发布A消费,感兴趣可以自己试下。目前我用到的场景都是单服务内的异步。
graph TD
Publisher --> event -->listener
上代码
先建立好一个事件对象
其中PurchaseOrderInfo orderInfo就是我们要传递的数据
public class SaveRedundancyEvent extends ApplicationEvent {
private PurchaseOrderInfo orderInfo;
public SaveRedundancyEvent(PurchaseOrderInfo source) {
super(source);
this.orderInfo = source;
}
public PurchaseOrderInfo getOrderInfo() {
return orderInfo;
}
public void setOrderInfo(PurchaseOrderInfo orderInfo) {
this.orderInfo = orderInfo;
}
}
数据生产者|消息发布者
先引入spring的发布对象
@Resource
private ApplicationEventPublisher applicationEventPublisher;
再将刚才的event进行发布
applicationEventPublisher.publishEvent(new SaveRedundancyEvent(orderInfo));
监听者|消息消费者
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
public class EventListener {
@Resource
private SearchOptionService searchOptionService;
@org.springframework.context.event.EventListener
@Async("taskExecutor")
public void listener(SaveRedundancyEvent saveRedundancyEvent) throws InterruptedException {
PurchaseOrderInfo orderInfo = saveRedundancyEvent.getOrderInfo();
// 然后拿着orderInfo做业务处理即可
}
}
线程池配置
上方@Async("taskExecutor")实际就是线程池的配置
@EnableAsync
@Configuration
public class SpringThreadPoolConfig {
@Value("${mythreadpool.maxPoolSize}")
private Integer maxPoolSize;
@Value("${mythreadpool.corePoolSize}")
private Integer corePoolSize;
@Value("${mythreadpool.queueCapacity}")
private Integer queueCapacity;
@Value("${mythreadpool.keepAliveSeconds}")
private Integer keepAliveSeconds;
@Value("${mythreadpool.threadNamePrefix}")
private String threadNamePrefix;
@Value("${mythreadpool.waitForTasksToCompleteOnShutdown}")
private Boolean waitForTasksToCompleteOnShutdown;
@Bean("taskExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数等于系统核数--8核
int availableProcessors = Runtime.getRuntime().availableProcessors();
executor.setCorePoolSize(availableProcessors);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程满了之后由调用者所在的线程来执行
// 拒绝策略:CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 设置默认线程名称
executor.setThreadNamePrefix(threadNamePrefix);
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
//执行初始化
executor.initialize();
return executor;
}
}
具体要配什么参数可以去百度自行修改
mythreadpool:
maxPoolSize: 20
corePoolSize: 8
queueCapacity: 2048
keepAliveSeconds: 60
threadNamePrefix: springThreadPool
waitForTasksToCompleteOnShutdown: true