一、进行线程池创建
import cn.hutool.core.thread.ThreadFactoryBuilder; import lombok.extern.slf4j.Slf4j; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurerSupport; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import java.lang.reflect.Method; import java.util.concurrent.Executor; /** * 线程池配置(异步线程) */ @Slf4j @Configuration @EnableAsync public class ThreadPoolTaskSchedulerConfig extends AsyncConfigurerSupport { @Bean("threadPoolTaskScheduler") public ThreadPoolTaskScheduler threadPoolTaskScheduler() { //这里使用的为定时任务线程池,替代@Scheduled注解,进行动态定时任务配置 ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setThreadFactory(ThreadFactoryBuilder.create().build()); scheduler.setPoolSize(60); scheduler.setRemoveOnCancelPolicy(true); scheduler.setThreadNamePrefix("TASK-SCHEDULE-"); scheduler.initialize(); return scheduler; } @Override public Executor getAsyncExecutor() { return threadPoolTaskScheduler(); } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (Throwable t, Method m, Object... args) -> { log.error("=============================" + t.getMessage() + "=============================="); log.error("threadPoolTaskScheduler exception Method:" + m.getName()); }; } }
二、创建bean操作对象 提供根据beanName获取,手动注入bean等方法,适用于不被spring管理的类中(thread、callback)
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.stereotype.Component; /** * @author lu_wanli **/ @Component public class SpringHelper implements BeanFactoryPostProcessor, ApplicationContextAware { private static ConfigurableListableBeanFactory beanFactory; /** * 获取 Spring Bean工厂 * * @return beanFactory */ public static ConfigurableListableBeanFactory getBeanFactory() { return beanFactory; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringHelper.beanFactory = beanFactory; } /** * 获取指定name的bean */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); } /** * 获取指定type的Bean */ public static <T> T getBean(Class<T> clz) throws BeansException { return beanFactory.getBean(clz); } /** * 包含Bean * * @param name beanClassName * @return true/false */ public static boolean containsBean(String name) { return beanFactory.containsBean(name); } /** * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) * * @param name beanName * @return boolean */ public static boolean isSingleton(String name) { return beanFactory.isSingleton(name); } private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringHelper.applicationContext = applicationContext; } /** * 动态注入单例bean实例 * * @param beanName bean名称 * @param singletonObject 单例bean实例 * @return 注入实例 */ public static Object registerSingletonBean(String beanName, Object singletonObject) { //将applicationContext转换为ConfigurableApplicationContext ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext; //获取BeanFactory DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory(); //动态注册bean. defaultListableBeanFactory.registerSingleton(beanName, singletonObject); //获取动态注册的bean. return configurableApplicationContext.getBean(beanName); } }
三、创建异步线程的管理类
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /** * 异步任务管理器 * */ public class AsyncManager { /** * 异步操作任务调度线程池 */ private final ThreadPoolTaskExecutor taskExecutor = SpringHelper.getBean("threadPoolTaskExecutor"); /** * 单例模式 */ private AsyncManager() { } private static final AsyncManager ME = new AsyncManager(); public static AsyncManager me() { return ME; } /** * 执行任务 * * @param task 任务 */ public void execute(Runnable task){ taskExecutor.execute(task); } /** * 停止线程池 */ public void shutdown() { taskExecutor.shutdown(); } }
四、在项目关闭时关闭相关线程池资源
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; /** * 关闭线程池资源 */ @Component public class ShutDownManager { private static final Logger logger = LoggerFactory.getLogger(ShutDownManager.class); @PreDestroy public void destory() { shutdownAsyncManager(); } private void shutdownAsyncManager() { try { logger.info("========关闭任务池=========="); AsyncManager.me().shutdown(); } catch (Exception e) { logger.error(e.getMessage(), e); } } }