添加guava框架,实现异步处理。
一、添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
二、注册为组件Bean
import com.google.common.eventbus.AsyncEventBus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* web 配置类
*
* @author Creator
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* AsyncEventBus注册
*/
@Bean
public AsyncEventBus asyncEventBus() {
// 创建一个核心3线程,最大10线程的线程池,配置DiscardPolicy策略,抛弃当前任务
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,10,60, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.DiscardPolicy());
return new AsyncEventBus(threadPoolExecutor);
}
}
三、添加事件处理监听器
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* 异步监听处理器
*/
@Component
public class AsyncEventListener {
/**
* 日志
*/
private final static Logger logger = LoggerFactory.getLogger(AsyncEventListener.class);
@Autowired
private AsyncEventBus asyncEventBus;
@Autowired
private ILoginLogService loginLogService;
/**
* 注册这个监听器
*/
@PostConstruct
public void register(){
asyncEventBus.register(this);
}
/**
* 具体业务处理(此处比如向库中添加登录日志)
* sysLoginLogPO: 登录日志表对应实体(替换成自己的传参实体即可)
*/
@Subscribe
public void addLoginLog(SysLoginLogPO sysLoginLogPO) {
logger.info("添加登录日志:sysLoginLogPO=" + sysLoginLogPO);
// 执行具体添加日志操作
loginLogService.insert(sysLoginLogPO);
}
/**
* 其他需要异步的业务方法
*/
@Subscribe
public void XXX(XXXXPO xxxxpoPO) {
logger.info("日志:xxxxpoPO=" + xxxxpoPO);
// 执行具体添加日志操作 TODO
}
}
四、业务层调用
@Autowired
private AsyncEventBus asyncEventBus;
/**
* 业务处理方法(业务封装)
*/
public void doAddLoginLog(){
SysLoginLogPO sysLoginLogPO = new SysLoginLogPO();
// 提交异步处理, 会执行AsyncEventListener中的 addLoginLog 方法,根据参数类型匹配
asyncEventBus.post(sysLoginLogPO);
}
五、guava同spring集成
可以参考 https://blog.csdn.net/yxp20092010/article/details/46537333
注意:上面链接的这个文章实现出来的是默认的同步,如果需求要使用异步,那么参考如下修改:
EventBusAdapter extends EventBus 一定要改为继承 AsyncEventBus 类,
然后添加一个构造方法,如下:
public class EventBusAdapter extends AsyncEventBus implements InitializingBean {
private List<EventAbstract> eventBusListener;
// 默认构造方法
public EventBusAdapter (Executor executor, List<EventAbstract> eventBusListener) {
super(executor);
this.eventBusListener = eventBusListener;
}
@Override
public void afterPropertiesSet() throws Exception {
for(EventAbstract eventAbstract : eventBusListener){
this.register(eventAbstract);
}
}
}
spring配置修改:
<!-- spring thread pool executor -->
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="5" />
<!-- 允许的空闲时间 -->
<property name="keepAliveSeconds" value="200" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="10" />
<!-- 缓存队列 -->
<property name="queueCapacity" value="20" />
<!-- 对拒绝task的处理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
<!-- EventBusListener 定义 -->
<util:list id="eventBusListener" value-type="com.qyou.EventAbstract">
<bean class="com.qyou.SendFailMailHandler "/>
<bean class="com.qyou.SendSuccessSMSHandler "/>
</util:list>
<!-- EventBusAdapter适配器 -->
<bean id="eventBusAdapter" class="com.qyou..EventBusAdapter">
<constructor-arg name="eventBusListener" ref="eventBusListener"/>
<constructor-arg name="executor" ref="taskExecutor"/>
</bean>