Преглед изворни кода

优化定时任务管理模块

sunyj пре 9 година
родитељ
комит
e0081963b6

+ 15 - 11
src/main/java/com/uas/report/controller/ScheduleController.java

@@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
-import com.uas.report.controller.schedule.model.DailyTaskInformation;
-import com.uas.report.controller.schedule.service.DailyTaskService;
+import com.uas.report.controller.schedule.model.TaskInformation;
+import com.uas.report.controller.schedule.service.TaskService;
 import com.uas.report.service.FileService;
 
 @Controller
@@ -20,43 +20,47 @@ public class ScheduleController {
 	private FileService fileService;
 
 	@Autowired
-	private DailyTaskService dailyTaskService;
+	private TaskService taskService;
 
 	@RequestMapping("/deleteGeneratedFiles")
 	@ResponseBody
 	public String updateOverdue(@RequestParam(required = true) Integer hour,
 			@RequestParam(required = true) Integer minute, @RequestParam(required = true) Integer second) {
-		return "已开启:" + fileService.startDeleteGeneratedFilesDailyTask(hour, minute, second);
+		String message = "已开启:" + fileService.newDeleteGeneratedFilesDailyTask(hour, minute, second);
+		restart();
+		return message;
 	}
 
 	@RequestMapping("/tasks")
 	@ResponseBody
-	public List<DailyTaskInformation> allDailyTaskInformations() {
-		return dailyTaskService.allDailyTaskInformations();
+	public List<TaskInformation> allTaskInformations() {
+		return taskService.allTaskInformations();
 	}
 
 	@RequestMapping("/start")
 	@ResponseBody
 	public String start() {
-		return dailyTaskService.start();
+		return taskService.start();
 	}
 
 	@RequestMapping("/stop")
 	@ResponseBody
 	public String stop() {
-		return dailyTaskService.stop();
+		return taskService.stop();
 	}
 
 	@RequestMapping("/restart")
 	@ResponseBody
 	public String restart() {
-		dailyTaskService.stop();
-		return dailyTaskService.start();
+		if (!taskService.isStopped()) {
+			taskService.stop();
+		}
+		return taskService.start();
 	}
 
 	@RequestMapping("/isStopped")
 	@ResponseBody
 	public boolean isStopped() {
-		return dailyTaskService.isStopped();
+		return taskService.isStopped();
 	}
 }

+ 27 - 35
src/main/java/com/uas/report/controller/schedule/model/DailyTaskInformation.java

@@ -1,5 +1,7 @@
 package com.uas.report.controller.schedule.model;
 
+import java.util.Calendar;
+import java.util.Date;
 import java.util.Objects;
 
 /**
@@ -8,17 +10,12 @@ import java.util.Objects;
  * @author sunyj
  * @since 2016年12月12日 下午3:18:42
  */
-public class DailyTaskInformation {
+public class DailyTaskInformation extends TaskInformation {
 
 	/**
-	 * 任务标题
+	 * 一天的毫秒数
 	 */
-	private String title;
-
-	/**
-	 * 所执行的任务
-	 */
-	private Runnable command;
+	private static final long MILLISECONDS_OF_ONE_DAY = 24 * 60 * 60 * 1000;
 
 	/**
 	 * 执行时间中的小时
@@ -35,33 +32,14 @@ public class DailyTaskInformation {
 	 */
 	private int second;
 
-	public DailyTaskInformation() {
-		super();
-	}
-
-	public DailyTaskInformation(String title, Runnable command, int hour, int minute, int second) {
-		super();
-		this.title = title;
-		this.command = command;
+	public DailyTaskInformation(String title, Executable command, int hour, int minute, int second) {
 		this.hour = hour;
 		this.minute = minute;
 		this.second = second;
-	}
-
-	public String getTitle() {
-		return title;
-	}
-
-	public void setTitle(String title) {
-		this.title = title;
-	}
-
-	public Runnable getCommand() {
-		return command;
-	}
-
-	public void setCommand(Runnable command) {
-		this.command = command;
+		setTitle(title);
+		setCommand(command);
+		setInitialDelay(getInitialDelay());
+		setPeriod(MILLISECONDS_OF_ONE_DAY);
 	}
 
 	public int getHour() {
@@ -88,6 +66,20 @@ public class DailyTaskInformation {
 		this.second = second;
 	}
 
+	@Override
+	public long getInitialDelay() {
+		Calendar nowCalendar = Calendar.getInstance();
+		nowCalendar.setTime(new Date());
+		Calendar initialDelayCalendar = (Calendar) nowCalendar.clone();
+		initialDelayCalendar.set(Calendar.HOUR_OF_DAY, hour);
+		initialDelayCalendar.set(Calendar.MINUTE, minute);
+		initialDelayCalendar.set(Calendar.SECOND, second);
+		if (initialDelayCalendar.before(nowCalendar)) {
+			initialDelayCalendar.add(Calendar.DAY_OF_MONTH, 1);
+		}
+		return initialDelayCalendar.getTimeInMillis() - nowCalendar.getTimeInMillis();
+	}
+
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj) {
@@ -98,14 +90,14 @@ public class DailyTaskInformation {
 		}
 		DailyTaskInformation other = (DailyTaskInformation) obj;
 		// command不好比较,不进行比较
-		return Objects.equals(title, other.getTitle()) && hour == other.getHour() && minute == other.getMinute()
+		return Objects.equals(getTitle(), other.getTitle()) && hour == other.getHour() && minute == other.getMinute()
 				&& second == other.getSecond();
 	}
 
 	@Override
 	public String toString() {
-		return "DailyTaskInformation [title=" + title + ", command=" + command + ", hour=" + hour + ", minute=" + minute
-				+ ", second=" + second + "]";
+		return "DailyTaskInformation [title=" + getTitle() + ", hour=" + hour + ", minute=" + minute + ", second="
+				+ second + "]";
 	}
 
 }

+ 0 - 69
src/main/java/com/uas/report/controller/schedule/model/DailyTaskLog.java

@@ -1,69 +0,0 @@
-package com.uas.report.controller.schedule.model;
-
-import java.util.Date;
-
-/**
- * 每天定时任务的执行日志
- * 
- * @author sunyj
- * @since 2016年12月12日 下午3:22:30
- */
-public class DailyTaskLog {
-
-	/**
-	 * 每天定时任务的信息
-	 */
-	private DailyTaskInformation dailyTaskInformation;
-
-	/**
-	 * 任务执行时间
-	 */
-	private Date executeTime;
-
-	/**
-	 * 任务执行日志
-	 */
-	private String log;
-
-	public DailyTaskLog() {
-		super();
-	}
-
-	public DailyTaskLog(DailyTaskInformation dailyTaskInformation, Date executeTime, String log) {
-		super();
-		this.dailyTaskInformation = dailyTaskInformation;
-		this.executeTime = executeTime;
-		this.log = log;
-	}
-
-	public DailyTaskInformation getDailyTaskInformation() {
-		return dailyTaskInformation;
-	}
-
-	public void setDailyTaskInformation(DailyTaskInformation dailyTaskInformation) {
-		this.dailyTaskInformation = dailyTaskInformation;
-	}
-
-	public Date getExecuteTime() {
-		return executeTime;
-	}
-
-	public void setExecuteTime(Date executeTime) {
-		this.executeTime = executeTime;
-	}
-
-	public String getLog() {
-		return log;
-	}
-
-	public void setLog(String log) {
-		this.log = log;
-	}
-
-	@Override
-	public String toString() {
-		return "DailyTaskLog [dailyTaskInformation=" + dailyTaskInformation + ", executeTime=" + executeTime + ", log="
-				+ log + "]";
-	}
-
-}

+ 17 - 0
src/main/java/com/uas/report/controller/schedule/model/Executable.java

@@ -0,0 +1,17 @@
+package com.uas.report.controller.schedule.model;
+
+/**
+ * 可执行的,用于执行定时任务
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 上午11:31:39
+ */
+public interface Executable {
+
+	/**
+	 * 执行定时任务
+	 * 
+	 * @return 任务执行结果
+	 */
+	public String execute();
+}

+ 95 - 0
src/main/java/com/uas/report/controller/schedule/model/TaskInformation.java

@@ -0,0 +1,95 @@
+package com.uas.report.controller.schedule.model;
+
+import java.util.Objects;
+
+/**
+ * 定时任务信息
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 上午10:21:28
+ */
+public class TaskInformation {
+	/**
+	 * 任务标题
+	 */
+	private String title;
+
+	/**
+	 * 所执行的任务
+	 */
+	private Executable command;
+
+	/**
+	 * 第一次执行的延迟时间间隔(毫秒)
+	 */
+	private long initialDelay;
+
+	/**
+	 * 两次任务之间的等待时间间隔(毫秒)
+	 */
+	private long period;
+
+	public TaskInformation() {
+		super();
+	}
+
+	public TaskInformation(String title, Executable command, long initialDelay, long period) {
+		super();
+		this.title = title;
+		this.command = command;
+		this.initialDelay = initialDelay;
+		this.period = period;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public Executable getCommand() {
+		return command;
+	}
+
+	public void setCommand(Executable command) {
+		this.command = command;
+	}
+
+	public long getInitialDelay() {
+		return initialDelay;
+	}
+
+	public void setInitialDelay(long initialDelay) {
+		this.initialDelay = initialDelay;
+	}
+
+	public long getPeriod() {
+		return period;
+	}
+
+	public void setPeriod(long period) {
+		this.period = period;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null || getClass() != obj.getClass() || !(obj instanceof TaskInformation)) {
+			return false;
+		}
+		TaskInformation other = (TaskInformation) obj;
+		// command不好比较,不进行比较
+		return Objects.equals(title, other.getTitle()) && initialDelay == other.getInitialDelay()
+				&& period == other.getPeriod();
+	}
+
+	@Override
+	public String toString() {
+		return "TaskInformation [title=" + title + ", initialDelay=" + initialDelay + ", period=" + period + "]";
+	}
+
+}

+ 74 - 0
src/main/java/com/uas/report/controller/schedule/model/TaskLog.java

@@ -0,0 +1,74 @@
+package com.uas.report.controller.schedule.model;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.alibaba.fastjson.JSON;
+
+/**
+ * 定时任务的执行日志
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 上午10:25:50
+ */
+public class TaskLog {
+
+	/**
+	 * 定时任务的信息
+	 */
+	private TaskInformation taskInformation;
+
+	/**
+	 * 任务执行时间
+	 */
+	private Date executeTime;
+
+	/**
+	 * 任务执行结果
+	 */
+	private String result;
+
+	public TaskLog(TaskInformation taskInformation, Date executeTime, String result) {
+		super();
+		this.taskInformation = taskInformation;
+		this.executeTime = executeTime;
+		this.result = result;
+	}
+
+	public TaskInformation getTaskInformation() {
+		return taskInformation;
+	}
+
+	public void setTaskInformation(TaskInformation taskInformation) {
+		this.taskInformation = taskInformation;
+	}
+
+	public Date getExecuteTime() {
+		return executeTime;
+	}
+
+	public void setExecuteTime(Date executeTime) {
+		this.executeTime = executeTime;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public void setResult(String result) {
+		this.result = result;
+	}
+
+	public String toJSONString() {
+		return "{\"taskInformation\": " + JSON.toJSONString(taskInformation) + ", \"executeTime\": \""
+				+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(executeTime) + "\", \"result\": \"" + result
+				+ "\"}";
+	}
+
+	@Override
+	public String toString() {
+		return "TaskLog [taskInformation=" + taskInformation + ", executeTime=" + executeTime + ", result=" + result
+				+ "]";
+	}
+
+}

+ 0 - 57
src/main/java/com/uas/report/controller/schedule/service/DailyTaskService.java

@@ -1,57 +0,0 @@
-package com.uas.report.controller.schedule.service;
-
-import java.util.List;
-
-import com.uas.report.controller.schedule.model.DailyTaskInformation;
-import com.uas.report.controller.schedule.model.DailyTaskLog;
-
-/**
- * 管理定时任务
- * 
- * @author sunyj
- * @since 2016年12月13日 上午8:46:53
- */
-public interface DailyTaskService {
-	/**
-	 * 建立每天定时任务
-	 * 
-	 * @param dailyTaskInformation
-	 *            每天定时任务的信息
-	 */
-	public void newDailyTask(DailyTaskInformation dailyTaskInformation);
-
-	/**
-	 * 保存日志到本地文件
-	 * 
-	 * @param log
-	 */
-	public void saveLog(DailyTaskLog log);
-
-	/**
-	 * 获取定时任务信息
-	 * 
-	 * @return
-	 */
-	public List<DailyTaskInformation> allDailyTaskInformations();
-
-	/**
-	 * 开启定时任务
-	 * 
-	 * @return 返回的结果
-	 */
-	public String start();
-
-	/**
-	 * 关闭定时任务
-	 * 
-	 * @return 返回的结果
-	 */
-	public String stop();
-
-	/**
-	 * 定时任务是否停止
-	 * 
-	 * @return
-	 */
-	public boolean isStopped();
-}

+ 50 - 0
src/main/java/com/uas/report/controller/schedule/service/TaskService.java

@@ -0,0 +1,50 @@
+package com.uas.report.controller.schedule.service;
+
+import java.util.List;
+
+import com.uas.report.controller.schedule.model.TaskInformation;
+
+/**
+ * 管理定时任务
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 上午10:52:29
+ */
+public interface TaskService {
+	/**
+	 * 建立定时任务
+	 * 
+	 * @param taskInformation
+	 *            定时任务的信息
+	 */
+	public void newTask(TaskInformation taskInformation);
+
+	/**
+	 * 获取定时任务信息
+	 * 
+	 * @return
+	 */
+	public List<TaskInformation> allTaskInformations();
+
+	/**
+	 * 开启定时任务
+	 * 
+	 * @return 返回的结果
+	 */
+	public String start();
+
+	/**
+	 * 关闭定时任务
+	 * 
+	 * @return 返回的结果
+	 */
+	public String stop();
+
+	/**
+	 * 定时任务是否停止
+	 * 
+	 * @return
+	 */
+	public boolean isStopped();
+
+}

+ 0 - 186
src/main/java/com/uas/report/controller/schedule/service/impl/DailyTaskServiceImpl.java

@@ -1,186 +0,0 @@
-package com.uas.report.controller.schedule.service.impl;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-import com.alibaba.fastjson.JSONObject;
-import com.uas.report.controller.schedule.model.DailyTaskInformation;
-import com.uas.report.controller.schedule.model.DailyTaskLog;
-import com.uas.report.controller.schedule.service.DailyTaskService;
-import com.uas.report.core.exception.ReportException;
-import com.uas.report.util.PathUtils;
-
-/**
- * 管理定时任务
- * 
- * @author sunyj
- * @since 2016年12月12日 上午11:40:00
- */
-@Service
-public class DailyTaskServiceImpl implements DailyTaskService {
-
-	/**
-	 * 随容器启动时,普通成员变量的值会丢失,需要使用类域
-	 */
-	private static List<DailyTaskInformation> dailyTaskInformations = new ArrayList<>();
-
-	private static ScheduledExecutorService scheduledExecutorService;
-
-	private Logger logger = Logger.getLogger(DailyTaskServiceImpl.class);
-
-	/**
-	 * 一天的毫秒数
-	 */
-	private static final long MILLISECONDS_OF_ONE_DAY = 24 * 60 * 60 * 1000;
-
-	@Override
-	public void newDailyTask(DailyTaskInformation dailyTaskInformation) {
-		if (dailyTaskInformation == null || StringUtils.isEmpty(dailyTaskInformation.getTitle())
-				|| dailyTaskInformation.getCommand() == null) {
-			throw new NullPointerException();
-		}
-		if (containsDailyTask(dailyTaskInformation)) {
-			throw new ReportException("任务已存在:" + dailyTaskInformation);
-		}
-		dailyTaskInformations.add(dailyTaskInformation);
-		stop();
-		start();
-	}
-
-	/**
-	 * 判断定时任务是否已经存在
-	 * 
-	 * @param dailyTaskInformation
-	 * @return
-	 */
-	private boolean containsDailyTask(DailyTaskInformation dailyTaskInformation) {
-		if (CollectionUtils.isEmpty(dailyTaskInformations)) {
-			return false;
-		}
-		for (DailyTaskInformation d : dailyTaskInformations) {
-			if (dailyTaskInformation.equals(d)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * 建立每天定时任务
-	 * 
-	 * @param command
-	 *            所执行的任务
-	 * @param hour
-	 *            执行时间中的小时
-	 * @param minute
-	 *            执行时间中的分钟
-	 * @param second
-	 *            执行时间中的秒
-	 */
-	private void newDailyTask(Runnable command, int hour, int minute, int second) {
-		Calendar now = Calendar.getInstance();
-		now.setTime(new Date());
-		Calendar initialDelayCalendar = (Calendar) now.clone();
-		initialDelayCalendar.set(Calendar.HOUR_OF_DAY, hour);
-		initialDelayCalendar.set(Calendar.MINUTE, minute);
-		initialDelayCalendar.set(Calendar.SECOND, second);
-		if (initialDelayCalendar.before(now)) {
-			initialDelayCalendar.add(Calendar.DAY_OF_MONTH, 1);
-		}
-		scheduledExecutorService.scheduleAtFixedRate(command,
-				initialDelayCalendar.getTimeInMillis() - now.getTimeInMillis(), MILLISECONDS_OF_ONE_DAY,
-				TimeUnit.MILLISECONDS);
-
-	}
-
-	@Override
-	public void saveLog(DailyTaskLog log) {
-		if (log == null) {
-			throw new NullPointerException();
-		}
-		FileWriter fileWriter = null;
-		try {
-			fileWriter = new FileWriter(PathUtils.getAppPath() + "daily-task-log.log", true);
-			fileWriter.write(JSONObject.toJSONString(log) + "\n");
-			fileWriter.flush();
-			logger.info("Saved task log:" + JSONObject.toJSONString(log) + "\n");
-		} catch (IOException e) {
-			e.printStackTrace();
-		} finally {
-			if (fileWriter != null) {
-				try {
-					fileWriter.close();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-	}
-
-	@Override
-	public List<DailyTaskInformation> allDailyTaskInformations() {
-		return dailyTaskInformations;
-	}
-
-	@Override
-	public String start() {
-		String message = "";
-		if (!isStopped()) {
-			message = "已存在运行的定时任务";
-			logger.error(message);
-			return message;
-		}
-		if (!CollectionUtils.isEmpty(dailyTaskInformations)) {
-			// 线程数与任务数保持一致,这样保证任务间不会互相影响
-			scheduledExecutorService = Executors.newScheduledThreadPool(dailyTaskInformations.size());
-			for (DailyTaskInformation dailyTaskInformation : dailyTaskInformations) {
-				logger.info("New daily task: " + dailyTaskInformation);
-				newDailyTask(dailyTaskInformation.getCommand(), dailyTaskInformation.getHour(),
-						dailyTaskInformation.getMinute(), dailyTaskInformation.getSecond());
-			}
-			message = "已开启定时任务:" + dailyTaskInformations;
-			logger.info(message + "\n");
-			return message;
-		} else {
-			message = "定时任务为空";
-			logger.error(message + "\n");
-			return message;
-		}
-	}
-
-	@Override
-	public String stop() {
-		String message = "";
-		if (isStopped()) {
-			message = "定时任务已经停止或者未开启过";
-			logger.error(message);
-			return message;
-		}
-		logger.info("Remove old daily tasks...");
-		scheduledExecutorService.shutdownNow();
-		message = "已关闭定时任务";
-		logger.info(message + "\n");
-		return message;
-	}
-
-	@Override
-	public boolean isStopped() {
-		if (scheduledExecutorService == null) {
-			return true;
-		}
-		return scheduledExecutorService.isShutdown() || scheduledExecutorService.isTerminated();
-	}
-
-}

+ 181 - 0
src/main/java/com/uas/report/controller/schedule/service/impl/TaskServiceImpl.java

@@ -0,0 +1,181 @@
+package com.uas.report.controller.schedule.service.impl;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import com.uas.report.controller.schedule.model.Executable;
+import com.uas.report.controller.schedule.model.TaskInformation;
+import com.uas.report.controller.schedule.model.TaskLog;
+import com.uas.report.controller.schedule.service.TaskService;
+import com.uas.report.core.exception.ReportException;
+
+/**
+ * 管理定时任务
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 上午10:54:43
+ */
+@Service
+public class TaskServiceImpl implements TaskService {
+
+	/**
+	 * 存储定时任务信息(随容器启动时,普通成员变量的值会丢失,需要使用类域)
+	 */
+	private static List<TaskInformation> taskInformations = new ArrayList<>();
+
+	/**
+	 * 定时任务调度
+	 */
+	private static ScheduledExecutorService scheduledExecutorService;
+
+	/**
+	 * 任务执行日志文件的路径
+	 */
+	private static final String LOG_DIR = System.getProperty("java.io.tmpdir");
+
+	private Logger logger = Logger.getLogger(TaskServiceImpl.class);
+
+	@Override
+	public void newTask(TaskInformation taskInformation) {
+		if (taskInformation == null || StringUtils.isEmpty(taskInformation.getTitle())
+				|| taskInformation.getCommand() == null) {
+			throw new NullPointerException();
+		}
+		if (containsTask(taskInformation)) {
+			throw new ReportException("任务已存在:" + taskInformation);
+		}
+		taskInformations.add(taskInformation);
+	}
+
+	/**
+	 * 判断定时任务是否已经存在
+	 * 
+	 * @param taskInformation
+	 * @return
+	 */
+	private boolean containsTask(TaskInformation taskInformation) {
+		if (CollectionUtils.isEmpty(taskInformations)) {
+			return false;
+		}
+		for (TaskInformation d : taskInformations) {
+			if (taskInformation.equals(d)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * 保存日志到本地文件
+	 * 
+	 * @param log
+	 */
+	private void saveLog(TaskLog log) {
+		if (log == null) {
+			throw new NullPointerException();
+		}
+		FileWriter fileWriter = null;
+		try {
+			String logFilePath = (LOG_DIR.endsWith(File.separator) ? LOG_DIR : LOG_DIR + "/") + "report-task-log.log";
+			fileWriter = new FileWriter(logFilePath, true);
+			fileWriter.write(log.toJSONString() + "\n");
+			fileWriter.flush();
+			logger.info("Saved task log:" + log.toJSONString() + " to " + logFilePath + "\n");
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (fileWriter != null) {
+				try {
+					fileWriter.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+
+	@Override
+	public List<TaskInformation> allTaskInformations() {
+		return taskInformations;
+	}
+
+	@Override
+	public String start() {
+		String message = "";
+		if (!isStopped()) {
+			message = "已存在运行的定时任务";
+			logger.error(message);
+			return message;
+		}
+		if (!CollectionUtils.isEmpty(taskInformations)) {
+			// 线程数为1,以免多个创建索引的任务互相影响,导致索引创建失败
+			scheduledExecutorService = Executors.newScheduledThreadPool(1);
+			for (TaskInformation taskInformation : taskInformations) {
+				logger.info("New task: " + taskInformation);
+				scheduledExecutorService.scheduleAtFixedRate(getCommand(taskInformation),
+						taskInformation.getInitialDelay(), taskInformation.getPeriod(), TimeUnit.MILLISECONDS);
+			}
+			message = "已开启定时任务:" + taskInformations;
+			logger.info(message + "\n");
+			return message;
+		} else {
+			message = "定时任务为空";
+			logger.error(message + "\n");
+			return message;
+		}
+	}
+
+	/**
+	 * 获取任务需执行的命令
+	 * 
+	 * @param taskInformation
+	 * @return
+	 */
+	private Runnable getCommand(final TaskInformation taskInformation) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				logger.info("Task run...");
+				Executable command = taskInformation.getCommand();
+				String result = command.execute();
+				TaskLog taskLog = new TaskLog(taskInformation, new Date(), result);
+				saveLog(taskLog);
+			}
+		};
+	}
+
+	@Override
+	public String stop() {
+		String message = "";
+		if (isStopped()) {
+			message = "定时任务已经停止或者未开启过";
+			logger.error(message);
+			return message;
+		}
+		logger.info("Remove old tasks...");
+		scheduledExecutorService.shutdownNow();
+		message = "已关闭定时任务";
+		logger.info(message + "\n");
+		return message;
+	}
+
+	@Override
+	public boolean isStopped() {
+		if (scheduledExecutorService == null) {
+			return true;
+		}
+		return scheduledExecutorService.isShutdown() || scheduledExecutorService.isTerminated();
+	}
+}

+ 2 - 2
src/main/java/com/uas/report/jasperreports/engine/export/CustomJRXlsExporter.java

@@ -91,7 +91,7 @@ public class CustomJRXlsExporter extends JRXlsExporter {
 		if (customCellStyle) {
 			String textStr = styledText.getText();
 			TextValue textValue = getTextValue(textElement, textStr);
-			// 类型为String,但是实际值为数值,需设置为字符串类型,否则会显示绿色三角提示
+			// 类型为String,但是实际值为数值,需设置为字符串类型,否则会提示转为数值型
 			if (textValue instanceof StringTextValue) {
 				if (isNumber(textStr)) {
 					baseStyle.setDataFormat(dataFormat.getFormat("@"));
@@ -100,7 +100,7 @@ public class CustomJRXlsExporter extends JRXlsExporter {
 
 			super.createTextCell(textElement, gridCell, colIndex, rowIndex, styledText, baseStyle, forecolor);
 
-			// 数值类型需明确指定,否则会显示绿色三角提示
+			// 数值类型需明确指定,否则会提示转为数值型
 			if (textValue instanceof NumberTextValue) {
 				setNumberTextValue(textStr);
 			}

+ 1 - 1
src/main/java/com/uas/report/service/FileService.java

@@ -206,5 +206,5 @@ public interface FileService {
 	 *            任务时间:秒
 	 * @return
 	 */
-	public DailyTaskInformation startDeleteGeneratedFilesDailyTask(Integer hour, Integer minute, Integer second);
+	public DailyTaskInformation newDeleteGeneratedFilesDailyTask(Integer hour, Integer minute, Integer second);
 }

+ 12 - 17
src/main/java/com/uas/report/service/impl/FileServiceImpl.java

@@ -34,8 +34,8 @@ import com.itextpdf.text.DocumentException;
 import com.itextpdf.text.pdf.PdfCopy;
 import com.itextpdf.text.pdf.PdfReader;
 import com.uas.report.controller.schedule.model.DailyTaskInformation;
-import com.uas.report.controller.schedule.model.DailyTaskLog;
-import com.uas.report.controller.schedule.service.DailyTaskService;
+import com.uas.report.controller.schedule.model.Executable;
+import com.uas.report.controller.schedule.service.TaskService;
 import com.uas.report.core.exception.ReportException;
 import com.uas.report.service.FileService;
 import com.uas.report.support.SysConf;
@@ -49,9 +49,9 @@ public class FileServiceImpl implements FileService {
 
 	@Autowired
 	private SysConf sysConf;
-	
+
 	@Autowired
-	private DailyTaskService dailyTaskService;
+	private TaskService taskService;
 
 	private Logger logger = Logger.getLogger(getClass());
 
@@ -520,25 +520,20 @@ public class FileServiceImpl implements FileService {
 	}
 
 	@Override
-	public DailyTaskInformation startDeleteGeneratedFilesDailyTask(Integer hour, Integer minute, Integer second) {
+	public DailyTaskInformation newDeleteGeneratedFilesDailyTask(Integer hour, Integer minute, Integer second) {
 		if (hour == null || minute == null || second == null) {
 			throw new NullPointerException();
 		}
-		final DailyTaskInformation dailyTaskInformation = new DailyTaskInformation();
-		dailyTaskInformation.setTitle("定时删除pdf文件");
-		dailyTaskInformation.setHour(hour);
-		dailyTaskInformation.setMinute(minute);
-		dailyTaskInformation.setSecond(second);
-		dailyTaskInformation.setCommand(new Runnable() {
+		String title = "定时删除pdf等文件";
+		Executable command = new Executable() {
 			@Override
-			public void run() {
-				logger.info("Daily Task run...");
+			public String execute() {
 				delete(ReportConstants.GENERATED_FILES_ABSOLUTE_PATH, true);
-				DailyTaskLog dailyTaskLog = new DailyTaskLog(dailyTaskInformation, new Date(), "success");
-				dailyTaskService.saveLog(dailyTaskLog);
+				return "success";
 			}
-		});
-		dailyTaskService.newDailyTask(dailyTaskInformation);
+		};
+		DailyTaskInformation dailyTaskInformation = new DailyTaskInformation(title, command, hour, minute, second);
+		taskService.newTask(dailyTaskInformation);
 		return dailyTaskInformation;
 	}
 

+ 13 - 3
src/main/java/com/uas/report/support/StartupProcessor.java

@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
 
+import com.uas.report.controller.schedule.service.TaskService;
 import com.uas.report.service.FileService;
 
 /**
@@ -19,22 +20,31 @@ public class StartupProcessor implements ApplicationListener<ContextRefreshedEve
 
 	@Autowired
 	private FileService fileService;
+	
+	@Autowired
+	TaskService taskService ;
 
 	@Override
 	public void onApplicationEvent(ContextRefreshedEvent event) {
 		// 非root application context,才执行
 		if (event.getApplicationContext().getParent() != null) {
-			startDeleteGeneratedFilesDailyTask();
+			startTask();
 		}
 	}
 
 	/**
 	 * 容器启动时开启删除产生的pdf等文件的定时任务
 	 */
-	public void startDeleteGeneratedFilesDailyTask() {
+	public void startTask() {
 		if (sysConf.isDailyTaskAutoStart()) {
-			fileService.startDeleteGeneratedFilesDailyTask(sysConf.getDailyTaskHour(), sysConf.getDailyTaskMinute(),
+			fileService.newDeleteGeneratedFilesDailyTask(sysConf.getDailyTaskHour(), sysConf.getDailyTaskMinute(),
 					sysConf.getDailyTaskSecond());
+
+			// 开启定时任务
+			if (!taskService.isStopped()) {
+				taskService.stop();
+			}
+			taskService.start();
 		}
 	}