[email protected]结合线程池实现异步回调
程序员文章站
2022-06-12 19:58:48
...
一、定义自己的线程池,如果直接使用spring的异步标签@Async也可以,不过是使用的spring自己默认的线程池,没执行一次都会新建一个线程,消耗性能。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<context:annotation-config/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:component-scan base-package="com.yunpeng.core.test"/>
<task:annotation-driven executor="callBackTaskExecutor" proxy-target-class="true" />
<!-- 配置线程池 -->
<bean id="callBackTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="4"/>
<!-- 最大线程数 -->
<property name="maxPoolSize" value="10"/>
<!-- 队列最大长度 -->
<property name="queueCapacity" value="50"/>
<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="60"/>
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
</beans>
二、定义增加异步标签地类就可以,重点:加注解的异步方法一定、千万不要和调用的类在一个类中定义,在抽象类中定义,在子类实现和调用,也不会走异步地。so,老老实实的定义一个新的接口类,接口中定义需要异步地方法,然后再实现类上加注解就行。
/**
* 异步回调业务方处理
* @author yunpeng.zhao
* @version $Id AsyncCallbackBiz.java, v 0.1 2018-07-24 上午11:08 yunpeng.zhao Exp $$
*/
public interface AsyncCallbackBiz {
/**
* 异步化处理通知业务方
* 只有成功、失败地订单才回调
* @param requestBean
*/
void doCallBack(OrderRequestBean requestBean);
}
/**
* 异步回调业务方实现类
* @author yunpeng.zhao
* @version $Id BalanceGrowOrderBizImpl.java, v 0.1 2018-07-13 上午11:09 yunpeng.zhao Exp $$
*/
@Service("accountOrderAsyncCallbackBiz")
public class AccountOrderAsyncCallbackBizImpl implements AsyncCallbackBiz {
private static final Logger logger = LoggerFactory.getLogger(AccountOrderAsyncCallbackBizImpl.class);
@Autowired
protected AsyncCallbackInfoService asyncCallbackInfoService;
@Override
@Async("callBackTaskExecutor") //这里加上注解就行,并标注上使用自己地线程池
public void doCallBack(OrderRequestBean requestBean) {
logger.info("异步回调通知业务方开始,通知的业务方请求号:{}",requestBean.getRequestFlowNo());
}
}
在业务类中,直接调用该异步方法即可,执行到该异步方法会自动创建新的线程执行,so easy
/**
* 异步处理业务方回调
* @param requestBean
*/
@Override
public void asyncCallBack(OrderRequestBean requestBean) {
accountOrderAsyncCallbackBiz.doCallBack(requestBean);
}