SpringBoot扫描数据库配置的定时任务,根据cron定时刷新数据库数据保证任务数据最新...

整体设计思路:

数据库 任务配置TASK表:REPEAT 字段表示是否需要重复执行,当不重复时CRON为具体时间点,只会执行一次

 

Task实体类和Mapper.xml 根据数据库字段自行创建。

废话不多说,直接上代码。

package com.yfjz.config;

import com.yfjz.model.AppData;
import com.yfjz.model.Task;
import com.yfjz.service.AppDataService;
import com.yfjz.service.BaseService;
import com.yfjz.utils.Constant;
import com.yfjz.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;

import java.util.*;

/**
* @Author: zxh
* @Description: 扫描数据库配置的定时任务,根据cron执行;支持定时任务动态添加修改
* @Date: 2018/11/19 10:44
* @Version: 1.0
*/
@Configuration
@EnableScheduling
public class ScheduleConfig extends BaseService implements SchedulingConfigurer {

private ThreadPoolTaskScheduler threadPoolTaskScheduler;

private static List<Task> tasks;

private static boolean initialized = false;

private static ContextLifecycleScheduledTaskRegistrar taskRegistrar;

private final AppDataService appDataService;

@Autowired
public ScheduleConfig(AppDataService appDataService) {
this.appDataService = appDataService;
}


/**
* @Description: 每隔一小时 扫描一次任务配置,重构定时任务时,把线程池中的任务关闭
* @Param: [] 0 0/10 * * * ? 0 0 0/1 * * ?
* @return: void
* @Date: 2018/11/19 13:38
*/
@Scheduled(cron = "0 0 0/1 * * ?")
public void bTask() {
try {
if (initialized) {
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown( false );
threadPoolTaskScheduler.shutdown();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
tasks = taskMapper.selectAllTask( new HashMap<>() );
configureTasks( tasks );
}

}

@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
if (tasks == null) {
bTask();
} else {
configureTasks( tasks );
}
}

/**
* @Description: 并行任务調用,多线程处理
* @Param: [tasks]
* @return: void
* @Date: 2018/11/19 13:22
*/
private void configureTasks(List<Task> tasks) {

threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize( 100 );//线程池大小
threadPoolTaskScheduler.setThreadNamePrefix( "configureTasks-" );
threadPoolTaskScheduler.setAwaitTerminationSeconds( 60 );//线程等待時間
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown( true );//等待所有任務執行完在銷毀
threadPoolTaskScheduler.initialize();
initialized = true;

if (taskRegistrar != null)
taskRegistrar.destroy();
taskRegistrar = new ContextLifecycleScheduledTaskRegistrar();
taskRegistrar.setTaskScheduler( threadPoolTaskScheduler );
for (Task task : tasks) {
Runnable runnable = new Runnable() {
@Override
public void run() {
List<AppData> list = appDataMapper.selectAllAppData( task.getAppId() );
if (!StringUtils.isEmpty( task.getCron() ) && task.getRepeat().equals( "1" )) {
savaAppData( list, task );
} else if (task.getRepeat().equals( "0" )) {
if (isLong( task.getCron() )) {
long num = System.currentTimeMillis() - Long.valueOf( task.getCron() );
Timer timer = new Timer();
timer.schedule( new TimerTask() {
@Override
public void run() {
savaAppData( list, task );
}
}, num );
}
}
}
};
Trigger trigger = new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
CronTrigger cronTrigger = new CronTrigger( task.getCron() );
return cronTrigger.nextExecutionTime( triggerContext );
}
};
TriggerTask triggerTask = new TriggerTask( runnable, trigger );
taskRegistrar.setTriggerTasksList( Collections.singletonList( triggerTask ) );
taskRegistrar.afterSingletonsInstantiated();
}
}

private void savaAppData(List<AppData> list, Task task) {
if (list.size() > 0) {
String[] name = list.get( 0 ).getName().split( "_" );
if (name.length > 0) {
AppData appData = new AppData();
appData.setId( getMaxSequences( Constant.DBTP_APP_DATA_SEQ ) );
appData.setName( getAppNo( name[0], name[1] ) );
appData.setAppId( task.getAppId() );
appData.setStatus( "0" );
appData.setUserId( task.getApp().getUserId() );
appDataMapper.insertSelective( appData );
try {
//根据应用执行表ID查询对应的最新的一条服务作业表,看状态是否为2 已执行
if (!list.get( 0 ).getStatus().equals( "2" )) {
appDataService.runJob( appData.getId(), task.getApp().getProcessId(), task.getApp().getUserId(), task.getApp().getEntityId() );
}

} catch (Exception e) {
e.printStackTrace();
}
}
} else {
AppData appData = new AppData();
appData.setId( getMaxSequences( Constant.DBTP_APP_DATA_SEQ ) );
appData.setName( task.getApp().getName() + "_00001" );
appData.setAppId( task.getAppId() );
appData.setStatus( "0" );
appData.setUserId( task.getApp().getUserId() );
appDataMapper.insertSelective( appData );
try {
appDataService.runJob( appData.getId(), task.getApp().getProcessId(), task.getApp().getUserId(), task.getApp().getEntityId() );

} catch (Exception e) {
e.printStackTrace();
}
}
}

public static boolean isLong(String str) {
if (null == str || str.length() == 0) {
return false;
}

for (int i = str.length(); --i >= 0; ) {
int c = str.charAt( i );
if (c < 48 || c > 57) {
return false;
}
}

return true;
}

public static String getAppNo(String appName, String appNo) {
String newAppNo = "_1";
if (StringUtils.isEmpty( appNo )) {
appNo = "0";
}
if (!StringUtils.isEmpty( appName )) {
int newNo = Integer.parseInt( appNo ) + 1;
newAppNo = String.format( appName + "_" + "%05d", newNo );
} else {
newAppNo = appName + newAppNo;
}
return newAppNo;
}

}

2、启动SpringBoot
Application 即可看到相关打印信息。
3、不足之处望指点

转载于:https://www.cnblogs.com/misterzhaoyan/p/9987174.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值