一。 直接编写相关代码。
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();
}
}
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);
}
}
}
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 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(applicationContext.getBeansOfType(OnceTask.class).values());
}
}
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();
}
}
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 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(applicationContext.getBeansOfType(ScheduledTask.class).values());
}
public void setTaskScheduler(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
}
在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();
}
}