spring 异步处理导出 @Async @EnableAspectJAutoProxy 上下文
1启动类加上注解
@Configuration
@EnableAsync
@EnableAspectJAutoProxy(exposeProxy = true)
如:

2、
使用@Async 放在 @service类下面的方法上。
注意,主线程和异步方法在同一个类里面, 需要手动获取bean代理,AopContext.currentProxy, 同时主线程加上注解@Transactional, 如果不加这个注解,即使启动类加了EnableAspectJAutoProxy也不会起作用。
r如:
// 异步处理
((EvaluationTaskMonitorServiceImpl) AopContext.currentProxy()).newCreateStudentExportData(
pageQueryParam, map, evaluationRoleName, user, scopeCodes
, fileName, userAgent, characterEncoding, os, attachmentProcessCode);


注意:如果主线程和异步方法不在同一个类里面,直接加@Async在需要异步的类的方法上就可以,不需要手动获取代理
3、如果异步方法里面使用了上下文,httprequest或者httpResponse, 那么是获取不到的。需要加一个线程类,再手动使用。


点击查看代码
package com.ly.education.teaching.assessment.server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class AsyncConfiguration {
private static final Logger logger = LoggerFactory.getLogger(AsyncConfiguration.class);
@Bean(name = "taskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数:线程池创建时候初始化的线程数
taskExecutor.setCorePoolSize(10);
// 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
taskExecutor.setMaxPoolSize(20);
// 缓冲队列:用来缓冲执行任务的队列
taskExecutor.setQueueCapacity(50);
// 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
taskExecutor.setKeepAliveSeconds(60);
// 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
taskExecutor.setThreadNamePrefix("HiTask-");
// 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
//taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
taskExecutor.initialize();
//解决使用@Async注解,获取不到上下文信息的问题 这样http的就能获取到了
taskExecutor.setTaskDecorator(runnable -> {
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
return ()->{
try {
// 我们set 进去 ,其实是一个ThreadLocal维护的.
RequestContextHolder.setRequestAttributes(requestAttributes);
runnable.run();
} finally {
// 最后记得释放内存
RequestContextHolder.resetRequestAttributes();
}
};
});
return taskExecutor;
}
class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
logger.error("MethodName={},Throwable={}",method.getName(),throwable.toString());
}
}
}
点击查看代码
// @Async 的方法使用http上下文是获取不到的,需加AsyncConfiguration这个类,使用RequestContextHolder方式获取
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request1 = attrs.getRequest();
HttpServletResponse response1 = attrs.getResponse();

posted on 2025-06-19 14:04 HeavenTang 阅读(76) 评论(0) 收藏 举报
浙公网安备 33010602011771号