1.配置一个处理方法线程池
package com.clouderp.purchase.config;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 用于异步线程池
*/
@Configuration
public class ThreadPoolConfiguration {
private static Logger log = LoggerFactory.getLogger(ThreadPoolConfiguration.class);
@Bean(name = "defaultThreadPoolExecutor", destroyMethod = "shutdown")
public ThreadPoolExecutor systemCheckPoolExecutorService() {
return new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(10000),
new ThreadFactoryBuilder().setNameFormat("default-executor-%d").build(),
(r, executor) -> log.error("system pool is full! "));
}
}
2.配置一个异常处理器
package com.clouderp.purchase.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import java.lang.reflect.Method;
/**
* Asyn注解异步调用异常捕获
*/
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
private static Logger log = LoggerFactory.getLogger(CustomAsyncExceptionHandler.class);
@Override
public void handleUncaughtException (Throwable throwable, Method method, Object... obj) {
log.error("Exception message - " + throwable.getMessage() + "Method name - " + method.getName());
for (Object param : obj) {
log.error("Parameter value - " + param);
}
}
}
3.重写AsyncConfigurer中 getAsyncUncaughtExceptionHandler()方法配置自定义异常处理器
package com.clouderp.purchase.config;
import com.clouderp.purchase.handler.CustomAsyncExceptionHandler;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
/**
* @Author Maynard.ran
* 配置异步捕获异常处理器
* @Date 2022/10/24 0024
*/
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Override
@Bean
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
}
4.启动类上添加@EnableAsync注解 开启异步
5.在要异步的方法上添加@Async("defaultThreadPoolExecutor")注解 括号里是线程池名字
package com.clouderp.purchase.service.impl;
import com.clouderp.purchase.dto.WmsIssueRecordDto;
import com.clouderp.purchase.mapper.AsyncInsertWmsRecordMapper;
import com.clouderp.purchase.service.AsyncInsertWmsRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
/**
* @Author Maynard.ran
* @Date 2022/10/24 0024
*/
@Service
@RequiredArgsConstructor
@EnableAsync
public class AsyncInsertWmsRecordServiceImpl implements AsyncInsertWmsRecordService {
private final AsyncInsertWmsRecordMapper asyncInsertWmsRecordMapper;
/***
* public Future<String> insertWmsRecord() 有返回使用
* return new AsyncResult<String>("hello"); 如果是对象则把泛型String改为对象
* 接收的话直接通过返回值.get()方法获取
* @return
*/
@Async("defaultThreadPoolExecutor")
@Override
public void insertWmsRecord(WmsIssueRecordDto wmsIssueRecordDto) {
asyncInsertWmsRecordMapper.insert(wmsIssueRecordDto);
}
}
6.如果同类中调用的话 需要通过代理类来调用否则不生效
通过ApplicationContext.getBean(当前类.class)来获取 如果直接調用的話,调用的是对象本身,spring在初始化的时候已经将对象转为代理对象并存到容器中 所以我们只能通过代理类获取
开启cglib代理,手动获取Spring代理类,从而调用同类下的异步方法。在启动类上加上@EnableAspectJAutoProxy(exposeProxy = true)
注解。