简单的可配置的定时任务

写的一个简单的可以在页面进行配置的定时任务,存在不少问题。现在勉强能用。还是需要改进
定义一个任务接口:

public interface Task {

	public void start();

	public void stop();

	public void restart();

	public boolean isAlive();
}

抽象实现:

public abstract class BusinessTask implements Runnable, BeanNameAware, Task {

	@Autowired(required = false) 
	protected ThreadPoolTaskScheduler threadPoolTaskScheduler;
	@Autowired
	TaskInfoDao taskInfoDao;
	// 接收生成的定时计划
	protected ScheduledFuture<?> future;
	// 任务名称
	protected String taskName;

	TaskInfo taskInfo;

	// 处理你的业务
	public abstract void doBusiness();

	@Override
	public void run() {
		// 检测配置有无更新
		TaskInfo dbTaskInfo = getTaskInfo();
		if (!dbTaskInfo.equals(this.taskInfo)) {
			// 有更新重启定时任务
			restart();
			return;
		}
		// 未启用状态,不执行任务
		if (this.taskInfo.getIsusing()) {
			return;
		}
//需要锁没有获取到锁就不执行		
if(this.taskInfo.getNeedLock()&&!allowRun(taskInfo.getTimeout())) {
			return;
		} 
		excuteBusiness();
	}

	@Override
	public void start() {
		this.taskInfo = getTaskInfo();
		this.future = threadPoolTaskScheduler.schedule(this, new CronTrigger(taskInfo.getCron()));
	}

	@Override
	public void stop() {
		if (future != null) {
			future.cancel(true);
			this.taskInfo = null;
		}
	}

	@Override
	public void restart() {
		stop();
		start();
	}

	@Override
	public boolean isAlive() {
		if (future == null) {
			return false;
		}
		return !future.isCancelled();
	}
	@Override
	public void setBeanName(String name) {
		this.taskName = name;
	}

	// 分布式锁,利用redis的setne指令
	private boolean allowRun(int timeout) {
		return RedisUtils.tryLock(taskName, timeout);
	}

	// 获取taskInfo信息
	private TaskInfo getTaskInfo() {
		try {
			TaskInfo taskInfo = taskInfoDao.get(taskName, null);
			if (null == taskInfo) {
				// 数据库没有配置,给一个默认配置的
				TaskInfo newTask = new TaskInfo();
				//把当前的bean名设置成主键
				newTask.setCode(taskName);
				newTask.setCron("0/30 * * * * ?");
				newTask.setIsusing(1);// 启用状态
				newTask.setTimeout(1);// 锁的过期时间
				newTask.setName(taskName + "任务");
				newTask.setNeedLock(0);
				taskInfoDao.insertSelective(newTask);
				taskInfo = newTask;
			}
			return taskInfo;
		} catch (Exception e) {
			log.error("获取taskInfo信息失败:" + taskName, e);
		}
		return null;
	}

	private synchronized  void excuteBusiness() {
		try {
			doBusiness();
		} catch (Exception e) {
			log.warn("任务执行失败:class={},message={}", e.getClass().getName(), e.getMessage());
		}
	}
}

任务启动

public class TaskLauncher implements EasySpringListener {

	@Override
	public void doSome(ApplicationContext applicationContext) {
		String systemType = System.getProperty("os.name");
		String lowerCase = systemType.toLowerCase();
		if (lowerCase.indexOf("linux") == -1) {
			return;
		}
		Map<String, Task> tasks = applicationContext.getBeansOfType(Task.class);
		tasks.forEach((k, task) -> task.start());

	}
}

启动开关

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableScheduling
@Import(TaskLauncher.class)
public @interface EnableBusinessTask {
}

页面配置:
在这里插入图片描述
使用示例:

public class SameUserTask extends BusinessTask {

	@Override
	public void doBusiness() {
		pullUsers();
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值