springboot定时任务—实现SchedulingConfigurer接口做定时调度(一)

定时任务在平时的工作中是很常见的,怎么有效的管理这些个定时任务呢?有的用配置文件,而我却喜欢用可视化列表管理,其实原理也就是把所有的定时任务都放到表里去管理,在项目启动的时候把这些个定时任务扫描到定时任务里即可!废话不多说了,先看看怎么去实现吧。其实SchedulingConfigurer实现方法很简单,只需要实现SchedulingConfigurer并重写configureTasks方法,在启动类必须加上@EnableScheduling注解即可。这里我就是做个封装和优化,让定时任务更好管理,原理还是这个原理。整个项目的实现是在springboot+jpa的环境下。跟着下面的向导来学习吧:

目录

1.创建定时任务的管理表(sys_scheduled)

2.构造定时任务表的相关类

2.1 实体类

2.2 Repository数据库交互类

2.3 Service服务类

3.定时任务配置类(这个是重点哦!!!!)

3.1主要是为了获取bean

 3.2配置类和定时任务管理表的交互(建立关系)

4.测试类编写并进行验证

 5.奉上一些常用的cron表达式


1.创建定时任务的管理表(sys_scheduled)

CREATE TABLE `sys_scheduled` (
  `id` varchar(32) NOT NULL COMMENT '主键',
  `job_name` varchar(200) DEFAULT NULL COMMENT '定时任务名称',
  `class_name` varchar(200) DEFAULT NULL COMMENT '类名',
  `method` varchar(250) DEFAULT NULL COMMENT '方法名',
  `cron` varchar(200) DEFAULT NULL COMMENT '定时任务表达式',
  `start_flag` varchar(2) DEFAULT NULL COMMENT '启用标记',
  `create_date` varchar(32) DEFAULT NULL COMMENT '创建日期',
  `create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
  `update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
  `update_date` varchar(32) DEFAULT NULL COMMENT '更新日期',
  `del_flag` varchar(32) DEFAULT NULL COMMENT '删除标记',
  `temp1` varchar(2500) DEFAULT NULL COMMENT '备注',
  `temp2` varchar(64) DEFAULT NULL COMMENT '备用字段2',
  `temp3` varchar(250) DEFAULT NULL COMMENT '备用字段3',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='定时任务配置表';

2.构造定时任务表的相关类

2.1 实体类

package com.lengmo.entity;

import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;

@Entity
@Data//让实体类的get和set方法得以简化,引入lombok包即可
@Table(name="sys_scheduled")
public class SysScheduled  implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private String id;		// 主键
	@Column(name="job_name")//表里的字段名称映射到实体类
	private String jobName;		// 定时任务名称
	@Column(name="class_name")
	private String className;		// 类名
	@Column(name="method")
	private String method;		// 方法名
	@Column(name="cron")
	private String cron;		// 定时任务表达式
	@Column(name="start_flag")
	private String startFlag;		// 启用标记
	@Column(name="temp1")
	private String temp1;//备注
}

2.2 Repository数据库交互类

package com.lengmo.repository;

import com.lengmo.entity.SysScheduled;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.io.Serializable;
import java.util.List;

public interface SysScheduledRepository extends JpaRepository<SysScheduled, Serializable> {
    @Query(" from SysScheduled s where s.startFlag='1'")
    public List<SysScheduled> getScheduleList();
}

2.3 Service服务类

package com.lengmo.service;

import java.util.List;
import com.lengmo.entity.SysScheduled;
import com.lengmo.repository.SysScheduledRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SysScheduledService{
	@Autowired
	private SysScheduledRepository sysScheduledRepository;
	public List<SysScheduled>  getScheduleList(){
		return sysScheduledRepository.getScheduleList();
	}		
}

3.定时任务配置类(这个是重点哦!!!!)

3.1主要是为了获取bean

package com.lengmo.common;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class ApplicationContextHelper implements ApplicationContextAware {
 
    private static ApplicationContext applicationContext;
 
    public ApplicationContextHelper() {
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHelper.applicationContext = applicationContext;
    }
 
    public static Object getBean(String beanName) {
       return applicationContext != null?applicationContext.getBean(beanName):null;
    }
}

 3.2配置类和定时任务管理表的交互(建立关系)

package com.lengmo.common;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import com.lengmo.entity.SysScheduled;
import com.lengmo.service.SysScheduledService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

@Component
public class ScheduleSetting implements SchedulingConfigurer {
    @Autowired
    private SysScheduledService sysScheduledService;
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        // 获取所有任务
    	List<SysScheduled> scheduleList = sysScheduledService.getScheduleList();
    	System.out.println(scheduleList.size());
         for (SysScheduled s : scheduleList){
             scheduledTaskRegistrar.addTriggerTask(getRunnable(s), getTrigger(s));
         }
    }
 
 
    /**
     * 转换首字母小写
     *
     * @param str
     * @return
     */
    public static String lowerFirstCapse(String str) {
        char[] chars = str.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }
 
    /**
     * runnable
     * @param scheduleConfig
     * @return
     */
    private Runnable getRunnable(final SysScheduled scheduleConfig){
        return new Runnable() {
            @Override
            public void run() {
                Class<?> clazz;
                try {
                    clazz = Class.forName(scheduleConfig.getClassName());
                    String className = lowerFirstCapse(clazz.getSimpleName());
                    Object bean = (Object) ApplicationContextHelper.getBean(className);
                    Method method = ReflectionUtils.findMethod(bean.getClass(), scheduleConfig.getMethod());
                    ReflectionUtils.invokeMethod(method, bean);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        };
    }
 
    /**
     * Trigger
     * @param scheduleConfig
     * @return
     */
    private Trigger getTrigger(final SysScheduled scheduleConfig){
        return new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                CronTrigger trigger = new CronTrigger(scheduleConfig.getCron());
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        };
 
    }
}

4.测试类编写并进行验证

package com.lengmo.common.scheduled;

import org.springframework.stereotype.Component;

@Component
public class TaskTest1 {
    public  void runTaskTest(){
        System.out.println("=====================测试定时任务====================");
    }
}

 5.奉上一些常用的cron表达式

Cron表达式: *秒    *分钟   *小时   *天   *月          *星期                                            *年份
           0~59   0~59   0~23   0~31  0~11   1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT         1970-2099

“30 * * * * ?”不是每30秒执行一次的意思,这个是每分钟的第30秒执行的意思

#经典案例: 
“30 * * * * ?” 每分钟第30秒触发任务
“30 10 * * * ?” 每小时的10分30秒触发任务 
“30 10 1 * * ?” 每天1点10分30秒触发任务 
“30 10 1 20 * ?” 每月20号1点10分30秒触发任务 
“30 10 1 20 10 ? *” 每年10月20号1点10分30秒触发任务 
“30 10 1 20 10 ? 2011” 2011年10月20号1点10分30秒触发任务 
“30 10 1 ? 10 * 2011” 2011年10月每天1点10分30秒触发任务 
“30 10 1 ? 10 SUN 2011” 2011年10月每周日1点10分30秒触发任务 
“15,30,45 * * * * ?” 每分钟的第15秒,30秒,45秒时触发任务 
“15-45 * * * * ?” 15到45秒内,每秒都触发任务 
“15/5 * * * * ?” 每分钟的每15秒开始触发,每隔5秒触发一次 
“15-30/5 * * * * ?” 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次 
“0 0/3 * * * ?” 每小时的第0分0秒开始,每三分钟触发一次 
“0 15 10 ? * MON-FRI” 星期一到星期五的10点15分0秒触发任务 
“0 15 10 L * ?” 每个月最后一天的10点15分0秒触发任务 
“0 15 10 LW * ?” 每个月最后一个工作日的10点15分0秒触发任务 
“0 15 10 ? * 5L” 每个月最后一个星期四的10点15分0秒触发任务 
“0 15 10 ? * 5#3”每个月第三周的星期四的10点15分0秒触发任务

好了,到这里整个定时任务的功能就完成了,以后只需要再定时任务表里添加相应的类和方法,就能把自动的开启这个定时任务!让定时任务更简单!!!大家可以去试试,上面的代码都是亲自测试过的,没有任何问题的!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值