SpringBoot2.1.x多线程池(ThreadPoolTaskScheduler)无法用@Autowired 注入解决方法,无需用工具类获取Bean
ThreadPool
A simple C++11 Thread Pool implementation
项目地址:https://gitcode.com/gh_mirrors/th/ThreadPool
免费下载资源
·
最近在做的一个SpringBoot项目用到了定时任务管理,就用ThreadPoolTaskScheduler做动态添加修改删除定时任务,但在业务操作时线程池里取不到Bean对象,一直报空指针异常,最后发现注入的方式不对,通过下面这种方式注入是取不到Bean对象的。
@Autowired
private AccountAPIService accountAPIService;
@Bean
public AccountAPIService generalAPIService(APIConfiguration config) {
return new AccountAPIServiceImpl(config);
}
通过下面这种方式注入就可以取到Bean对象了:把对象定义为静态的,然后在set方法里注入
private static AccountAPIService accountAPIService;
@Resource(name = "accountAPIService")
public static void setAccountAPIService(@Qualifier("config") APIConfiguration config) {
TradeController.accountAPIService = new AccountAPIServiceImpl(config);
}
ThreadPoolTaskScheduler:线程池任务调度类,能够开启线程池进行任务调度。下面是实际业务调用代码
import com.auto.trade.entities.SpringCorn;
import com.auto.trade.market.constant.COMMON_API_WRAPPER_STATIC_VALUE;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
/**
* 任务调度线程池配置
* @author QC班长
* @date 20190127
*/
@Configuration
public class ScheduleConfig {
private static final Logger logger = LoggerFactory.getLogger(ScheduleConfig.class);
//ThreadPoolTaskScheduler对象建议用下面这中方式注入,通过bean注解注册-代码更新于20191207
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
return new ThreadPoolTaskScheduler();
}
private static ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Resource
public void setThreadPoolTaskScheduler(ThreadPoolTaskScheduler threadPoolTaskScheduler) {
ScheduleConfig.threadPoolTaskScheduler = threadPoolTaskScheduler;
}
/**
* 存放所有启动定时任务对象,极其重要
*/
private static HashMap<String, ScheduledFuture<?>> scheduleMap = new HashMap<>();
/**
* @param crons 动态设置定时任务方法
* <p>
* 此方法是真正的动态实现启停和时间周期的关键,你可以针对自己的业务来调用,你对库中的动态数据修改后来调用此方法,每个Cron对象必须要包含,执行周期(cron.getCron()),启停状态(cron.getCronStatus()),执行的类(cron.getCronClass())
*/
public void startCron(List<SpringCorn> crons) {
try {
if (crons != null && !crons.isEmpty()) {
//遍历所有库中动态数据,根据库中class取出所属的定时任务对象进行关闭,每次都会把之前所有的定时任务都关闭,根据新的状态重新启用一次,达到最新配置
for (SpringCorn cron : crons) {
ScheduledFuture<?> scheduledFuture = scheduleMap.get(cron.getClass_name());
//一定判空否则出现空指针异常,ToolUtil为自己写的工具类此处只需要判断对象是否为空即可
if ((scheduledFuture != null)) {
scheduledFuture.cancel(true);
}
}
//因为下边存储的是新的定时任务对象,以前的定时任务对象已经都停用了,所以旧的数据没用清除掉,这步可以不处理,因为可以是不可重复要被覆盖
//scheduleMap.clear();
//遍历库中数据,之前已经把之前所有的定时任务都停用了,现在判断库中如果是启用的重新启用并读取新的数据,把开启的数据对象保存到定时任务对象中以便下次停用
for (SpringCorn cron : crons) {
//判断当前定时任务是否有效,COMMON_API_WRAPPER_STATIC_VALUE.CORN_STATUS_TRUE为有效标识
if (cron.getStatus().equals(COMMON_API_WRAPPER_STATIC_VALUE.CORN_STATUS_TRUE)) {
//开启一个新的任务,库中存储的是全类名(包名加类名)通过反射成java类,读取新的时间
ScheduledFuture<?> future = threadPoolTaskScheduler.schedule((Runnable) Class.forName(cron.getClass_name()).newInstance(), new CronTrigger(cron.getCron()));
//这一步非常重要,之前直接停用,只停用掉了最后启动的定时任务,前边启用的都没办法停止,所以把每次的对象存到map中可以根据key停用自己想要停用的
scheduleMap.put(cron.getClass_name(), future);
logger.info("=================================>>>>> {} 定时业务每 {} 秒执行一次====================================", cron.getCron_remark(),cron.getCron());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
GitHub 加速计划 / th / ThreadPool
7.74 K
2.22 K
下载
A simple C++11 Thread Pool implementation
最近提交(Master分支:2 个月前 )
9a42ec13 - 9 年前
fcc91415 - 9 年前
更多推荐
已为社区贡献6条内容
所有评论(0)