定时任务:按时间自动上下架(每日统计与刷新状态)

  • Post author:
  • Post category:其他


task对象(与数据库关联)

package com.ujiol.system.entity;


import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Date;

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("task")
public class Task {

	private static final long serialVersionUID = 1L;
	@TableId(value = "task_id", type = IdType.AUTO)
	private Long taskId;
	@TableField
	private Integer taskState;
	@TableField
	private String beanName;
	@TableField
	private String methodName;
	@TableField
	private Long processId;
	@TableField
	private Date taskExecuteTime;
	@TableField
	private Integer taskType;
	@ApiModelProperty(value = "创建时间")
	@TableField(fill = FieldFill.INSERT)
	private Date taskCreated;
	@ApiModelProperty(value = "更新时间")
	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date taskModified;

}

时间处理工具

package com.ujiol.common.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

/**
 * A utility class for parsing and formatting dates as used in this project.
 *
 * @author lee
 * @since 2017/2/17 10:50:00
 */
@Component
public class DateUtils {
    @Autowired
    private RestTemplate restTemplate;

    public static String formatDate(Date date, String datePattern) {
        return new SimpleDateFormat(datePattern).format(date);
    }

    /**
     * Parses the date value using the given date pattern.
     *
     * @param dateValue   The date value to parse.
     * @param datePattern The date pattern to use.
     * @return The parsed date or null.
     */
    public static Date parseDate(String dateValue, String datePattern) {
        try {
            return new SimpleDateFormat(datePattern).parse(dateValue);
        } catch (ParseException e) {
            System.err.println(e.fillInStackTrace());
        }
        return null;
    }

    public static Object countTwoDate(Object startDate, Object endDate) {

        Date start = (Date) startDate;
        Date end = (Date) endDate;
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);
        long time1 = cal.getTimeInMillis();
        cal.setTime(end);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));

    }

    public static Object countTwoDayWeek(Object startDate, Object endDate) {
        {
            Date start = (Date) startDate;
            Date end = (Date) endDate;
            Calendar cal = Calendar.getInstance();
            cal.setTime(start);
            long time1 = cal.getTimeInMillis();
            cal.setTime(end);
            long time2 = cal.getTimeInMillis();
            long between_days = (time2 - time1) / (1000 * 3600 * 24);
            Long between_mins = (time2 - time1) % (1000 * 3600 * 24);
            Double days = Double.parseDouble(String.valueOf(between_days));
            if ((days / 7) > 0 && (days / 7) < 1) {
                // 不满一周的按一周算
                return 1;
            } else if (days / 7 >= 1) {
                int day = days.intValue();
                if (day % 7 >= 0 && between_mins > 0) {
                    return day / 7 + 1;
                } else {
                    return day / 7;
                }
            } else if ((days / 7) == 0) {
                return 0;
            } else {
                // 负数返还null
                return null;
            }
        }
    }

    public static int lastDate(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date2);
        int l2 = cal.get(Calendar.DAY_OF_YEAR);
        cal.setTime(date1);
        int l1 = cal.get(Calendar.DAY_OF_YEAR);
        return l2 - l1;
    }

    public static int lastWeek(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date2);
        int l1 = cal.get(Calendar.WEEK_OF_YEAR);
        cal.setTime(date1);
        int l2 = cal.get(Calendar.WEEK_OF_YEAR);
        return l1 - l2;
    }

    /**
     * 根据日期获取当天是周几
     *
     * @param
     * @return 周几
     */
    public static Integer dateToWeek(Date date) {
        Integer[] weekDays = {7, 1, 2, 3, 4, 5, 6};
        // String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return weekDays[w];
    }

    /**
     * 根据日期获取当天是周几
     *
     * @param
     * @return 周几
     */
    public static String dateToWeekCN(Date date) {
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        // String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return weekDays[w];
    }

    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }
    public static Date getDateYel(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
        return zero;
    }

    public static Date getDateZero(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
        return zero;
    }

    public static Date getTomorrowDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date tomorrow = calendar.getTime();
        return tomorrow;
    }

    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static String getPastDate(int past, Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
        Date today = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String result = sdf.format(today);
        return result;
    }

    public static Date getPastDate2(int past, Date date) {
        Date dayZero = getDateZero(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dayZero);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
        Date day = calendar.getTime();
        return day;
    }

    public static String getYearSemester(Date date) {
        String yearSemester;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int currentMonth = calendar.get(Calendar.MONTH) + 1;
        if (currentMonth >= 1 && currentMonth <= 2) {
            yearSemester = "1";
        } else if (currentMonth >= 3 && currentMonth <= 7) {
            yearSemester = "2";
        } else {
            yearSemester = "1";
        }
        return yearSemester;
    }

    public static int getLastMinutes(Date date1, Date date2) {
        return (int) ((date2.getTime() - date1.getTime()) / 60 / 100);
    }

    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            cal.add(Calendar.DAY_OF_MONTH, 1);
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(endDate);
        return lDate;
    }

    public static int yearsBetween(String start, String end) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar startDate = Calendar.getInstance();
        Calendar endDate = Calendar.getInstance();
        startDate.setTime(sdf.parse(start));
        endDate.setTime(sdf.parse(end));
        return (endDate.get(Calendar.YEAR) - startDate.get(Calendar.YEAR));
    }

    public static int yearsBetween(Date start, Date end) throws ParseException {
        int day1 = start.getDay();
        int day2 = end.getDay();
        return (day2 - day1) / 365;
    }

    public static LocalTime dateToLocalTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        LocalTime localTime = localDateTime.toLocalTime();
        return localTime;
    }

    public static Date getMondayByDate(Date time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
        return cal.getTime();
    }

    public static Date getDayStart(Date date) {
        Calendar c = new GregorianCalendar();
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    public static Date getDayEnd(Date date) {
        Calendar c = new GregorianCalendar();
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    public static Long dateDiff(Date startDate, Date endDate) throws ParseException {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long diff = endDate.getTime() - startDate.getTime();
        long day = diff / nd;
        long hour = diff % nd / nh;
        long min = diff % nd % nh / nm;
        return min;
    }

    public static String getCron(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH)+1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        String cron = String.valueOf(second) + " " + String.valueOf(minute) + " " + String.valueOf(hour) + " "
                + String.valueOf(day) + " " + String.valueOf(month) + " " + "?";
        return cron;
    }

}

定时任务加载内容类

package com.ujiol.common.taskjob;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: simple-demo
 * @description: 添加定时任务注册类,用来增加、删除定时任务。
 * @author: 
 * @date: 2019/5/23
 **/
@Component
public class CronTaskRegistrar implements DisposableBean {

    private final Map<CronTask, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>();

    @Autowired
    private TaskScheduler taskScheduler;

    public TaskScheduler getScheduler() {
        return this.taskScheduler;
    }

    /**
     * 新增定时任务
     * @param task
     * @param cronExpression
     */
    public void addCronTask(Runnable task, String cronExpression) {
        addCronTask(new CronTask(task, cronExpression));
    }

    public void addCronTask(CronTask cronTask) {
        if (cronTask != null) {
            //Runnable task = cronTask.getRunnable();
            if (this.scheduledTasks.containsKey(cronTask)) {
                removeCronTask(cronTask);
            }

            this.scheduledTasks.put(cronTask, scheduleCronTask(cronTask));
        }
    }

    /**
     * 移除定时任务
     * @param
     */
    public void removeCronTask(CronTask cronTask) {
    	Runnable task = cronTask.getRunnable();
        ScheduledTask scheduledTask = this.scheduledTasks.remove(task);
        if (scheduledTask != null)
            scheduledTask.cancel();
    }

    public ScheduledTask scheduleCronTask(CronTask cronTask) {
        ScheduledTask scheduledTask = new ScheduledTask();
        scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());

        return scheduledTask;
    }


    @Override
    public void destroy() {
        for (ScheduledTask task : this.scheduledTasks.values()) {
            task.cancel();
        }
        this.scheduledTasks.clear();
    }
}

取消定时任务类

package com.ujiol.common.taskjob;

import java.util.concurrent.ScheduledFuture;

/**
 * @program: simple-demo
 * @description: 定时任务控制类
 * @author: CaoTing
 * @date: 2019/5/23
 **/
public final class ScheduledTask {

    public volatile ScheduledFuture<?> future;
    /**
     * 取消定时任务
     */
    public void cancel() {
        ScheduledFuture<?> future = this.future;
        if (future != null) {
            future.cancel(true);
        }
    }
}

定时任务执行类

package com.ujiol.common.taskjob;

import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @program: simple-demo
 * @description: 定时任务运行类
 * @author: CaoTing
 * @date: 2019/5/23
 **/
@Slf4j
public class SchedulingRunnable implements Runnable {


    private String beanName;

    private String methodName;

    private Object[] params;

    public SchedulingRunnable(String beanName, String methodName) {
        this(beanName, methodName, null);
    }

    public SchedulingRunnable(String beanName, String methodName, Object...params ) {
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
    }

    @Override
    public void run() {
        log.info("定时任务开始执行 - bean:{},方法:{},参数:{}", beanName, methodName, params);
        long startTime = System.currentTimeMillis();

        try {
            Object target = SpringUtil.getBean(beanName);

            Method method = null;
            if (null != params && params.length > 0) {
                Class<?>[] paramCls = new Class[params.length];
                for (int i = 0; i < params.length; i++) {
                    paramCls[i] = params[i].getClass();
                }
                method = target.getClass().getDeclaredMethod(methodName, paramCls);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (null != params && params.length > 0) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception ex) {
            log.error(String.format("定时任务执行异常 - bean:%s,方法:%s,参数:%s ", beanName, methodName, params), ex);
        }

        long times = System.currentTimeMillis() - startTime;
        log.info("定时任务执行结束 - bean:{},方法:{},参数:{},耗时:{} 毫秒", beanName, methodName, params, times);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SchedulingRunnable that = (SchedulingRunnable) o;
        if (params == null) {
            return beanName.equals(that.beanName) &&
                    methodName.equals(that.methodName) &&
                    that.params == null;
        }

        return beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params);
    }

    @Override
    public int hashCode() {
        if (params == null) {
            return Objects.hash(beanName, methodName);
        }

        return Objects.hash(beanName, methodName, params);
    }
}

执行调用方法

	private void handleTask(Activity activity) {
		Task task = new Task();
		task.setBeanName(beanName);
		task.setMethodName(methodName);
		task.setProcessId(activity.getActivityId());
		task.setTaskExecuteTime(activity.getActivityStartTime());
		task.setTaskType(taskType);
		taskService.save(task);
		SchedulingRunnable tasks = new SchedulingRunnable(task.getBeanName(), task.getMethodName(), task.getProcessId(),
				task.getTaskType());
		CronTaskRegistrar cronTaskRegistrar = new CronTaskRegistrar();
		cronTaskRegistrar.addCronTask(tasks, DateUtils.getCron(task.getTaskExecuteTime()));
	}

重启程序添加数据库中的定时任务

package com.ujiol.common.taskjob;


import com.ujiol.system.service.TaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(value = 1)
public class LoadTask implements ApplicationRunner {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoadTask.class);

    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;

    @Autowired
    private TaskService taskService;

    /**
     * 程序启动完毕后,需要自启的任务
     */
    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        LOGGER.info(" >>>>>> 项目启动完毕, 开启 => 需要自启的任务 开始!");
        TaskExample taskExample = new TaskExample();
        taskExample.or().andTaskStateEqualTo(0);
        if (taskService.existsByExample(taskExample)) {
            List<Task> taskList = taskService.findAllByExample(taskExample);
            for (Task task : taskList) {
                task.setTaskState(1);
                taskService.updateByEntity(task);
                SchedulingRunnable tasks = new SchedulingRunnable(task.getBeanName(), task.getMethodName(),
                        task.getEquipmentDomainName(), task.getEquipmentPortNumber(), task.getStartDate(),
                        task.getEndDate(), task.getVideoRecordId());
                cronTaskRegistrar.addCronTask(tasks, getCron(task.getEndDate()));
            }
            LOGGER.info(" >>>>>> 项目启动完毕, 开启 => 需要自启的任务 结束!");
        }
        LOGGER.info(" >>>>>> 项目启动完毕, 开启 => 暂无自启的任务 结束!");
    }

    private String getCron(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        String cron = String.valueOf(second) + " " + String.valueOf(minute) + " " + String.valueOf(hour) + " "
                + String.valueOf(day) + " " + String.valueOf(month) + " " + "?";
        return cron;
    }

}

———————————————————————————————————————————

定时任务之(每日定时任务)

package com.ujiol.common.taskjob;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ujiol.common.model.Result;
import com.ujiol.system.entity.Activity;
import com.ujiol.system.entity.Task;
import com.ujiol.system.service.ActivityService;
import com.ujiol.system.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

@Transactional
@RestController
public class ActivityTask {

	@Autowired
	private TaskService taskService;

	@Autowired
	private ActivityService activityService;

	private int activityStatus = 0; // 未生效
	private int activityingStatus = 1; // 生效
	private int unActivityStatus = 2; // 过期

	@RequestMapping(value = "/activityTask", method = RequestMethod.POST)
	//设置凌晨来刷新
	@Scheduled(cron = "0 0 1 * * ?")
	public Result<?> activityTask() {
		Date date = new Date();
		// 1. 将正在生效规则置为过期 2.将待生效规则置为生效 3. 任务表中标记为已执行
		QueryWrapper<Activity> queryWrapper = new QueryWrapper();
		queryWrapper.eq("activity_status", activityStatus)
				.le("activity_start_time", new Date());
		List<Activity> activityList = activityService.list(queryWrapper);
		for (Activity activity : activityList) {
			queryWrapper.clear();
			queryWrapper.eq("activity_id", activity.getActivityId())
					.eq("activity_status", activityingStatus);
			Activity ac = activityService.getOne(queryWrapper);
			if (ac != null) {
				ac.setActivityStatus(unActivityStatus);
				ac.setActivityUpdatedTime(date);
				activityService.updateById(ac);
			}
			activity.setActivityStatus(activityingStatus);
			activityService.updateById(ac);
			QueryWrapper<Task> queryWrapperT = new QueryWrapper();
			queryWrapperT.eq("process_id", ac.getActivityId());
			Task task = taskService.getOne(queryWrapperT);
			task.setTaskType(1);
			taskService.updateById(task);
		}
		return new Result<>(Result.RESULT_SUCCESS);
	}


}



版权声明:本文为code_manongz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。