简单定时任务框架

本文介绍了一个基于Spring框架的定时任务管理系统实现案例。该系统通过Spring IoC容器管理OnceTask和ScheduledTask两种任务类型,并利用Spring Task Scheduler进行调度。文章详细展示了相关Java类的设计与配置文件的编写,并给出具体使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一。 直接编写相关代码。

main.java

package com.ffcs.icity.app.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Main implements Runnable {

	private final static Logger logger = LoggerFactory.getLogger(Main.class);

	private ApplicationContext context;

	private void init() {
		logger.info("initializing Spring IoC container");
		this.context = new ClassPathXmlApplicationContext(new String[] { "classpath*:conf/applicationContext-*.xml","classpath*:/applicationContext-*.xml" });
		logger.info("initialized Spring IoC container");
	}
	
	private void processOnceTask(){
		OnceTaskExecutor onceTaskExecutor=(OnceTaskExecutor)this.context.getBean(OnceTaskExecutor.class);
		if(onceTaskExecutor!=null){
			logger.info("executing OnceTasks");
			onceTaskExecutor.execute();
			logger.info("executed OnceTasks");
		}
	}
	
	private void processScheduledTask(){
		ScheduledTaskExecutor scheduledTaskExecutor=(ScheduledTaskExecutor)this.context.getBean(ScheduledTaskExecutor.class);
	    if (scheduledTaskExecutor!=null) {
	    	logger.info("executing ScheduledTasks");
	    	scheduledTaskExecutor.execute();
	    	logger.info("executing ScheduledTasks");
		}
	}

	@Override
	public void run() {
		init();
		processScheduledTask();
		processOnceTask();
	}
	
}

OnceTask.java

package com.ffcs.icity.app.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 执行一次的任务.
 * @author linwei
 *
 */
public abstract class OnceTask implements Runnable {

	protected Logger logger;

	public OnceTask() {
		this.logger = LoggerFactory.getLogger(this.getClass());
	}

	protected abstract void doTask();

	@Override
	public void run() {
		try {
			this.logger.info("starting task");
			doTask();
			this.logger.info("completed task");
		} catch (Throwable throwable) {
			this.logger.error("failed task", throwable);
		}
	}

}


OnceTaskExecutor

package com.ffcs.icity.app.core;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;



/**
 * 单次任务调度执行器
 * @author linwei
 *
 */
public class OnceTaskExecutor implements ApplicationContextAware {

	private final static Logger logger = LoggerFactory.getLogger(OnceTaskExecutor.class);

	private List<OnceTask> onceTasks;

	public void execute() {
		logger.info("OnceTask count:{}", this.onceTasks.size());
		for (OnceTask onceTask : this.onceTasks) {
			logger.info("executing {}", onceTask);
			new Thread(onceTask).start();
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		//获取配置文件中BEAN类型是OnceTask的相关BEAN信息
		this.onceTasks = new ArrayList<OnceTask>(applicationContext.getBeansOfType(OnceTask.class).values());
	}


}

ScheduledTask.java

package com.ffcs.icity.app.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;


/**
 * 定时任务
 * @author linwei
 *
 */
public abstract class ScheduledTask implements Runnable {

	private final static String LOG_MDC_TASK_SID = "SID";

	protected Logger logger;

	/**
	 * 执行次数.
	 */
	private long count = 1;

	/**
	 * 错误次数.
	 */
	private long errCount = 0;

	public ScheduledTask() {
		this.logger = LoggerFactory.getLogger(this.getClass());
	}

	public abstract void doTask();

	@Override
	public void run() {

		MDC.put(LOG_MDC_TASK_SID, Long.toString(count));

		try {

			logger.info("starting task[{}]", count);

			long startTime = System.currentTimeMillis();

			doTask();

			long elapsedTime = System.currentTimeMillis() - startTime;

			logger.info("completed task[{}],elapsed time: {} ms", count, elapsedTime);

		} catch (Throwable throwable) {

			errCount++;

			logger.error("failed task[" + count + "],error total: " + errCount, throwable);

		} finally {
			MDC.remove(LOG_MDC_TASK_SID);
			count++;
		}

	}

	/**
	 * 子类覆盖此方法,提供表示执行时间定义的Cron表达式.同时指示此定时任务的执行方式为基于cron表达式.
	 */
	public String getCron() {
		return null;
	}

	/**
	 * 子类覆盖此方法,用于设置两次任务执行的间隔时间(单位:毫秒).同时指示此定时任务的执行方式为以固定间隔时间的重复执行(
	 * 下一次的执行会在上一次执行完成后固定的时间间隔后开始).
	 * 
	 * 注:如果子类同时覆盖了getCron()方法,那么优先使用基于cron表达式方式的定时任务.
	 * 
	 */
	public long getDelay() {
		return -1;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("ScheduledTask [cron=");
		builder.append(this.getCron());
		builder.append(", delay=");
		builder.append(this.getDelay());
		builder.append("]");
		return builder.toString();
	}

}

ScheduledTaskExecutor.java

package com.ffcs.icity.app.core;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;



/**
 * 定时任务执行器
 * @author linwei
 *
 */
public class ScheduledTaskExecutor implements ApplicationContextAware{
	
	private final static Logger logger = LoggerFactory.getLogger(ScheduledTaskExecutor.class);
	
	private List<ScheduledTask> scheduledTasks;
	
	private TaskScheduler taskScheduler;
	
	public void execute() {
		logger.info("ScheduledTask count:{}", this.scheduledTasks.size());
		for (ScheduledTask scheduledTask : this.scheduledTasks) {
			if(scheduledTask.getCron()!=null){
				logger.info("executing {} by cron", scheduledTask);
				this.taskScheduler.schedule(scheduledTask,new CronTrigger(scheduledTask.getCron()));
			}else if(scheduledTask.getDelay()>=0){
				logger.info("executing {} by delay", scheduledTask);
				this.taskScheduler.scheduleWithFixedDelay(scheduledTask, scheduledTask.getDelay());
			}else{
				logger.warn("invalid {}. because subclass must override getCron() or getDelay().", scheduledTask);
			}
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.scheduledTasks = new ArrayList<ScheduledTask>(applicationContext.getBeansOfType(ScheduledTask.class).values());
	}

	public void setTaskScheduler(TaskScheduler taskScheduler) {
		this.taskScheduler = taskScheduler;
	}
	
}

二。 编写相关配置文件信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
	default-lazy-init="false">

	<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
	<context:component-scan base-package="com.ffcs.icity" />

	<task:annotation-driven scheduler="scheduler" />

	<task:scheduler id="scheduler" pool-size="50" />

	<bean id="onceTaskExecutor" class="com.ffcs.icity.app.core.OnceTaskExecutor" />
	
	<bean id="scheduledTaskExecutor" class="com.ffcs.icity.app.core.ScheduledTaskExecutor">
	     <property name="taskScheduler" ref="scheduler"/>
	</bean>

	<!-- local development环境 -->
	<beans profile="development">
		<context:property-placeholder
			ignore-resource-not-found="true"
			location="classpath*:/application.properties,
		                      classpath*:/application.development.properties" />
	</beans>

	<!-- test 环境 -->
	<beans profile="test">
		<context:property-placeholder
			ignore-resource-not-found="true"
			location="classpath*:/application.properties,
          			         classpath*:/application.test.properties" />
	</beans>

	<!-- production环境 -->
	<beans profile="production">
		<context:property-placeholder
			ignore-unresolvable="true" location="classpath*:/application.properties" />
	</beans>

</beans>

三。 使用实例

在com.ffcs.icity扫描路径下创建相关需要执行的JAVA文件,如下:

TestTask.java

package com.ffcs.icity.test;

import org.springframework.stereotype.Service;

import com.ffcs.icity.app.core.OnceTask;


@Service
public class TestTask extends OnceTask{

	@Override
	protected void doTask() {
		System.err.println("111111"); 
		System.err.println("okok.");
	}

}


四。 执行代码。

执行如下方法调用即可。

package test;

import com.ffcs.icity.app.core.Main;

public class Test {

	
	public static void main(String[] args) {
		
		new Main().run();
	}
	
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值