最近使用定时任务比较多,想起之前有一次用到过,但没有代码了。重新整理一份,仅供参考!
数据库使用的是mysql:
DROP TABLE IF EXISTS `bj_wcs`.`wcs_huakang_cron`; -- ---------------------------- -- Table structure for wcs_huakang_cron -- ---------------------------- CREATE TABLE `wcs_huakang_cron` ( `cron_id` varchar(30) not NULL COMMENT '唯一标识' PRIMARY KEY, `task_name` varchar(30) DEFAULT NULL COMMENT '任务名称', `cron` varchar(30) not NULL COMMENT '任务表达式', `class_name` varchar(255) not NULL COMMENT '类路径名称', `method_name` varchar(100) not NULL COMMENT '类的方法名', `type` varchar(30) DEFAULT NULL COMMENT '任务类型', `state` varchar(30) DEFAULT 0 COMMENT '任务状态:0:正常(启动);1:不正常(停止)', `create_by` varchar(30) DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建时间' )ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='定时任务管理表'; |
开发环境SpringBoot ============controller层:================================== package com.penghaisoft.wcs.corn.controller; /** * @Description * @Author zx * @Date 2022-01-21 **/ import com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron; import com.penghaisoft.wcs.corn.service.Scheduler; import com.penghaisoft.wcs.corn.service.WcsHuakangCronService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * 动态定时任务Controller */ @RestController @RequestMapping("/wcsHuakangCronController/") public class WcsHuakangCronController { @Autowired private Scheduler scheduler; @Autowired private WcsHuakangCronService wcsHuakangCronService; /** * 启动一个动态定时任务 * http://localhost:10085/wcsHuakangCron/start/2 */ @RequestMapping("start/{cronId}") public String start(@PathVariable("cronId") String cronId){ scheduler.start(cronId); return "操作成功"; } /** * 停止一个动态定时任务 * http://localhost:10085/wcsHuakangCron/stop/2 */ @RequestMapping("stop/{cronId}") public String stop(@PathVariable("cronId") String cronId){ scheduler.stop(cronId); return "操作成功"; } /** * 更新一个动态定时任务 * http://localhost:9090/wcs/wcsHuakangCron/save?taskId=2&taskExp=0/2 * * * * ?&taskClass=cn.huanzi.qch.springboottimer.task.MyRunnable3 */ @RequestMapping("save") public String save(WcsHuakangCron task) throws IllegalAccessException { //先更新表数据 WcsHuakangCron wcsHuakangCron = wcsHuakangCronService.selectByPrimaryKey(task.getCronId()); //null值忽略 List<String> ignoreProperties = new ArrayList<>(7); //反射获取Class的属性(Field表示类中的成员变量) for (Field field : task.getClass().getDeclaredFields()) { //获取授权 field.setAccessible(true); //属性名称 String fieldName = field.getName(); //属性的值 Object fieldValue = field.get(task); //找出值为空的属性,我们复制的时候不进行赋值 if(null == fieldValue){ ignoreProperties.add(fieldName); } } //org.springframework.beans BeanUtils.copyProperties(A,B):A中的值付给B BeanUtils.copyProperties(task, wcsHuakangCron,ignoreProperties.toArray(new String[0])); wcsHuakangCronService.insert(wcsHuakangCron); Scheduler.mysql_tasks.clear(); //停止旧任务 scheduler.stop(wcsHuakangCron.getCronId()); //重新启动 scheduler.start(wcsHuakangCron.getCronId()); return "操作成功"; } /** * 启动多个动态定时任务 * http://localhost:10085/wcsHuakangCron/start/2 */ @RequestMapping("start/{List}") public String start(@RequestBody List<WcsHuakangCron> list){ if(list.size()>0){ //循环开启所有动态定时任务 extracted(list); return "操作成功"; } return "操作失败"; } /** *功能描述: 默认加载开启所有定时任务 * @author zhangx * @date 2022/1/22 * @params * @return void */ @PostConstruct public void startAll(){ List<WcsHuakangCron> list= wcsHuakangCronService.findAll(); if(list.size()>0){ extracted(list); } } /** *功能描述: 循环开启所有动态定时任务 * @author zhangx * @date 2022/1/22 * @params * @return void */ private void extracted(List<WcsHuakangCron> list) { if(list.size()>0) { for (WcsHuakangCron wcsHuakangCron : list) { scheduler.start(wcsHuakangCron.getCronId()); } } } } ==============server层===================== -----------------------业务层----------------------- package com.penghaisoft.wcs.corn.service; import com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron; import com.penghaisoft.wcs.util.MethodRunUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.CronTrigger; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; /** * @Description 创建定时器 * @Author zx * @Date 2022-01-22 **/ @Slf4j @Configuration //1.主要用于标记配置类,兼备component的效果。 @EnableScheduling // 2.开启定时任务 public class Scheduler {//implements SchedulingConfigurer //数据库的任务 public static ConcurrentHashMap<String, WcsHuakangCron> mysql_tasks = new ConcurrentHashMap<>(10); //正在运行的任务 public static ConcurrentHashMap<String, ScheduledFuture> runTasks = new ConcurrentHashMap<>(10); //线程池任务调度 private ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); /** *功能描述: 查询定时任务的服务类 */ @Autowired private WcsHuakangCronService wcsHuakangCronService; /** * 初始化线程池任务调度 */ @Autowired public Scheduler(){ this.threadPoolTaskScheduler.setPoolSize(10); this.threadPoolTaskScheduler.setThreadNamePrefix("task-thread-"); this.threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); this.threadPoolTaskScheduler.initialize(); } /** * 获取所有数据库里的定时任务 */ @Scheduled(cron = "1/4 * * * * *") private void getAllWcsHuakangCron(){ //查询所有,并put到tasks Scheduler.mysql_tasks.clear(); log.info("定时任务进来了!"); List<WcsHuakangCron> list = wcsHuakangCronService.findAll(); log.info("几条数据:"+list.size()); if(list.size()>0) { for (WcsHuakangCron wcsHuakangCron:list) { Scheduler.mysql_tasks.put(wcsHuakangCron.getCronId(), wcsHuakangCron); this.start(wcsHuakangCron.getCronId()); } } } /** * 根据定时任务id,启动定时任务 */ public void start(String cronId){ try { //如果为空,重新获取 if(Scheduler.mysql_tasks.size() <= 0){ this.getAllWcsHuakangCron(); } WcsHuakangCron wcsHuakangCron = Scheduler.mysql_tasks.get(cronId); // String className = wcsHuakangCron.getClassName(); //获取任务类 Class<?> clazz = Class.forName(wcsHuakangCron.getClassName()); //获取类名称的方法 Method methods = clazz.getMethod(wcsHuakangCron.getMethodName()); // 创建对象 Objects obj = (Objects) clazz.getConstructor().newInstance(); //Cron表达式 CronTrigger cron = new CronTrigger(wcsHuakangCron.getCron()); //执行,并put到runTasks //Scheduler.runTasks.put(cronId, Objects.requireNonNull(this.threadPoolTaskScheduler.schedule(runnable, cron))); this.threadPoolTaskScheduler.schedule(new MethodRunUtil(className,methods),cron); this.updateTaskStatus(cronId,"0"); log.info("{},任务启动!",cronId); } catch (ClassNotFoundException | NoSuchMethodException e) { log.error("{},任务启动失败...",cronId); e.printStackTrace(); } } /** * 根据定时任务id,停止定时任务 */ public void stop(String taskId){ Scheduler.runTasks.get(taskId).cancel(true); Scheduler.runTasks.remove(taskId); this.updateTaskStatus(taskId,"1"); log.info("{},任务停止...",taskId); } /** * 更新数据库动态定时任务状态 */ private void updateTaskStatus(String taskId,String status){ WcsHuakangCron wcsHuakangCron = wcsHuakangCronService.selectByPrimaryKey(taskId); wcsHuakangCron.setState(status); wcsHuakangCronService.updateByPrimaryKey(wcsHuakangCron); } /* @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(() -> { if (!CollectionUtils.isEmpty(wcsHuakangCronList)) { log.info("检测动态定时任务列表..."); List<WcsHuakangCron> tts = new ArrayList<>(); wcsHuakangCronList.forEach(WcsHuakangCron -> { WcsHuakangCron tt = new WcsHuakangCron(); tt.setCron(WcsHuakangCron.getCron()); tt.setCronId("dynamic-task-" + WcsHuakangCron.getCronId()); tts.add(tt); }); } } , triggerContext -> new PeriodicTrigger(5L, TimeUnit.SECONDS).nextExecutionTime(triggerContext)); }*/ } 查询数据: package com.penghaisoft.wcs.corn.service; import com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron; import java.util.List; /** * @Description 定时任务管理 * @Author zx * @Date 2022/01/21 **/ public interface WcsHuakangCronService { int deleteByPrimaryKey(String cronId); int insert(WcsHuakangCron record); int insertSelective(WcsHuakangCron record); WcsHuakangCron selectByPrimaryKey(String cronId); int updateByPrimaryKeySelective(WcsHuakangCron record); int updateByPrimaryKey(WcsHuakangCron record); /** *功能描述: 查询所有定时任务 * @author zhangx * @date 2022/1/21 * @param * @return */ List<WcsHuakangCron> findAll(); } =============service实现层=============================== package com.penghaisoft.wcs.corn.service.impl; import com.penghaisoft.wcs.corn.model.dao.WcsHuakangCronMapper; import com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron; import com.penghaisoft.wcs.corn.service.WcsHuakangCronService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @Description * @Author zx * @Date 2022-01-21 **/ @Service("wcsHuakangCronService") public class WcsHuakangCronServiceImpl implements WcsHuakangCronService { @Autowired private WcsHuakangCronMapper wcsHuakangCronMapper; @Override public int deleteByPrimaryKey(String cronId) { return wcsHuakangCronMapper.deleteByPrimaryKey(cronId); } @Override public int insert(WcsHuakangCron record) { return wcsHuakangCronMapper.insert(record); } @Override public int insertSelective(WcsHuakangCron record) { return wcsHuakangCronMapper.insertSelective(record); } @Override public WcsHuakangCron selectByPrimaryKey(String cronId) { return wcsHuakangCronMapper.selectByPrimaryKey(cronId); } @Override public int updateByPrimaryKeySelective(WcsHuakangCron record) { return wcsHuakangCronMapper.updateByPrimaryKeySelective(record); } @Override public int updateByPrimaryKey(WcsHuakangCron record) { return wcsHuakangCronMapper.updateByPrimaryKey(record); } /** *功能描述: 查询所有定时任务 * @author zhangx * @date 2022/1/21 * @param * @return */ @Override public List<WcsHuakangCron> findAll() { return wcsHuakangCronMapper.findAll(); } } ================mapper层:============================ package com.penghaisoft.wcs.corn.model.dao; import com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron; import org.springframework.stereotype.Repository; import java.util.List; /** * @Description 定时任务管理 * @Author zx * @Date 2022/01/21 **/ @Repository public interface WcsHuakangCronMapper { int deleteByPrimaryKey(String cronId); int insert(WcsHuakangCron record); int insertSelective(WcsHuakangCron record); WcsHuakangCron selectByPrimaryKey(String cronId); int updateByPrimaryKeySelective(WcsHuakangCron record); int updateByPrimaryKey(WcsHuakangCron record); /** *功能描述: 查询所有定时任务 * @author zhangx * @date 2022/1/21 * @param * @return */ List<WcsHuakangCron> findAll(); } ================实体类:============================ package com.penghaisoft.wcs.corn.model.entity; import lombok.Data; import java.util.Date; /** *功能描述:定时任务管理类 * @author zhangx * @date 2022/1/21 * @param * @return */ @Data public class WcsHuakangCron { private String cronId;//定时任务id private String taskName;//定时任务名称 private String cron;//定时任务Cron表达式 private String className;//定时任务任务类完整路径 private String methodName;//定时任务任务类的方法名 private String type;//类型 private String state; //定时任务状态,0停用 1启用 private String createBy;//创建人 private Date createTime;//创建时间 public String getCronId() { return cronId; } public void setCronId(String cronId) { this.cronId = cronId == null ? null : cronId.trim(); } public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName == null ? null : taskName.trim(); } public String getCron() { return cron; } public void setCron(String cron) { this.cron = cron == null ? null : cron.trim(); } public String getClassName() { return className; } public void setClassName(String className) { this.className = className == null ? null : className.trim(); } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName == null ? null : methodName.trim(); } public String getType() { return type; } public void setType(String type) { this.type = type == null ? null : type.trim(); } public String getState() { return state; } public void setState(String state) { this.state = state == null ? null : state.trim(); } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy == null ? null : createBy.trim(); } public Date getCreate() { return createTime; } public void setCreate(Date createTime) { this.createTime = createTime; } } ============mapper.xml============================= <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.penghaisoft.wcs.corn.model.dao.WcsHuakangCronMapper"> <resultMap id="BaseResultMap" type="com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron"> <id column="cron_id" jdbcType="VARCHAR" property="cronId" /> <result column="task_name" jdbcType="VARCHAR" property="taskName" /> <result column="cron" jdbcType="VARCHAR" property="cron" /> <result column="class_name" jdbcType="VARCHAR" property="className" /> <result column="method_name" jdbcType="VARCHAR" property="methodName" /> <result column="type" jdbcType="VARCHAR" property="type" /> <result column="state" jdbcType="VARCHAR" property="state" /> <result column="create_by" jdbcType="VARCHAR" property="createBy" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> </resultMap> <sql id="Base_Column_List"> cron_id, task_name, cron, class_name, method_name, type, state, create_by, create_time </sql> <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from wcs_huakang_cron where cron_id = #{cronId,jdbcType=VARCHAR} </select> <!--查询所有的定时任务--> <select id="findAll" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from wcs_huakang_cron </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.String"> delete from wcs_huakang_cron where cron_id = #{cronId,jdbcType=VARCHAR} </delete> <insert id="insert" parameterType="com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron"> insert into wcs_huakang_cron (cron_id, task_name, cron, class_name, method_name, type, state, create_by, create_time ) values (#{cronId,jdbcType=VARCHAR}, #{taskName,jdbcType=VARCHAR}, #{cron,jdbcType=VARCHAR}, #{className,jdbcType=VARCHAR}, #{methodName,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR}, #{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP} ) </insert> <insert id="insertSelective" parameterType="com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron"> insert into wcs_huakang_cron <trim prefix="(" suffix=")" suffixOverrides=","> <if test="cronId != null"> cron_id, </if> <if test="taskName != null"> task_name, </if> <if test="cron != null"> cron, </if> <if test="className != null"> class_name, </if> <if test="methodName != null"> method_name, </if> <if test="type != null"> type, </if> <if test="state != null"> state, </if> <if test="createBy != null"> create_by, </if> <if test="createTime != null"> create_time, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="cronId != null"> #{cronId,jdbcType=VARCHAR}, </if> <if test="taskName != null"> #{taskName,jdbcType=VARCHAR}, </if> <if test="cron != null"> #{cron,jdbcType=VARCHAR}, </if> <if test="className != null"> #{className,jdbcType=VARCHAR}, </if> <if test="methodName != null"> #{methodName,jdbcType=VARCHAR}, </if> <if test="type != null"> #{type,jdbcType=VARCHAR}, </if> <if test="state != null"> #{state,jdbcType=VARCHAR}, </if> <if test="createBy != null"> #{createBy,jdbcType=VARCHAR}, </if> <if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron"> update wcs_huakang_cron <set> <if test="taskName != null"> task_name = #{taskName,jdbcType=VARCHAR}, </if> <if test="cron != null"> cron = #{cron,jdbcType=VARCHAR}, </if> <if test="className != null"> class_name = #{className,jdbcType=VARCHAR}, </if> <if test="methodName != null"> method_name = #{methodName,jdbcType=VARCHAR}, </if> <if test="type != null"> type = #{type,jdbcType=VARCHAR}, </if> <if test="state != null"> state = #{state,jdbcType=VARCHAR}, </if> <if test="createBy != null"> create_by = #{createBy,jdbcType=VARCHAR}, </if> <if test="createTime != null"> create_time = #{createTime,jdbcType=TIMESTAMP}, </if> </set> where cron_id = #{cronId,jdbcType=VARCHAR} </update> <update id="updateByPrimaryKey" parameterType="com.penghaisoft.wcs.corn.model.entity.WcsHuakangCron"> update wcs_huakang_cron set task_name = #{taskName,jdbcType=VARCHAR}, cron = #{cron,jdbcType=VARCHAR}, class_name = #{className,jdbcType=VARCHAR}, method_name = #{methodName,jdbcType=VARCHAR}, type = #{type,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR}, create_by = #{createBy,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=TIMESTAMP} where cron_id = #{cronId,jdbcType=VARCHAR} </update> </mapper> |