发布时间:2022-10-04 文章分类:编程知识 投稿人:王小丽 字号: 默认 | | 超大 打印

一、进行线程池创建

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);
        }
    }
}