Spring-Scheduler(定时任务)

1、XML声明task和设置注解(标红段落)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.2.xsd">
        
    <!-- 识别@Scheduled注解 -->
    <task:annotation-driven/>
 </beans>

2、创建controller测试

package com.ll.controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ll.service.SchedulerJobService;

@Controller
public class SchedulerController {
    @Resource(name = "SchedulerJobService")
    SchedulerJobService schedulerJob;

    @RequestMapping("scheduler")
    @ResponseBody
    public void setSchedulerJob(@RequestParam String cron) {
        schedulerJob.addTriggerTask("task01", "cron-json", cron);
    }

    @RequestMapping("cancelallscheduler")
    @ResponseBody
    public void cancelAllSchedulerJob() {
        schedulerJob.removeTriggerTask("task01");
    }
}
View Code

3、SchedulerJobService.java

package com.ll.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import com.ll.utils.BeanUtils;


@Service(value = "SchedulerJobService")
@Lazy(false)
@EnableScheduling
public class SchedulerJobService implements SchedulingConfigurer {
    private final String FIELD_SCHEDULED_FUTURES = "scheduledTasks";
    private ScheduledTaskRegistrar taskRegistrar;
    private Set<ScheduledFuture<?>> scheduledFutures = null;
    private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        this.taskRegistrar = scheduledTaskRegistrar;
        // taskRegistrar.addTriggerTask(doTask("test"), getTrigger("*/5 * * * * ?"));
    }

    /**
     * 获取ScheduledFutures
     * 
     * @return
     */
    @SuppressWarnings("all")
    private Set<ScheduledFuture<?>> getScheduledFutures() {
        if (scheduledFutures == null) {
            try {
                scheduledFutures = (Set<ScheduledFuture<?>>) BeanUtils.getProperty(taskRegistrar,
                        FIELD_SCHEDULED_FUTURES);
            } catch (NoSuchFieldException e) {
                throw new SchedulingException("not found scheduledTasks field.");
            }
        }
        return scheduledFutures;
    }

    /**
     * 添加定时任务
     * 
     * @return
     */
    public void addTriggerTask(String taskId, String jobData, String cron) {
        if (taskFutures.containsKey(taskId)) {
            throw new SchedulingException("the taskId[" + taskId + "] was added.");
        }
        TaskScheduler scheduler = taskRegistrar.getScheduler();
        // cron = "*/5 * * * * ?"
        ScheduledFuture<?> future = scheduler.schedule(doTask(jobData), getTrigger(cron));
        getScheduledFutures().add(future);
        taskFutures.put(taskId, future);
    }

    /**
     * 是否存在任务
     * 
     * @param taskId
     * @return
     */
    public boolean hasTask(String taskId) {
        return this.taskFutures.containsKey(taskId);
    }

    /**
     * 任务编号
     * 
     * @return
     */
    public Set<String> taskIds() {
        return taskFutures.keySet();
    }

    /**
     * 任务调度是否已经初始化完成
     * 
     * @return
     */
    public boolean inited() {
        return this.taskRegistrar != null && this.taskRegistrar.getScheduler() != null;
    }

    /**
     * 删除指定的定时任务
     * 
     * @return
     */
    public void removeTriggerTask(String taskId) {
        ScheduledFuture<?> future = taskFutures.get(taskId);
        if (future != null) {
            future.cancel(true);
        }
        taskFutures.remove(taskId);
        getScheduledFutures().remove(future);
    }

    /**
     * 业务执行方法
     * 
     * @return
     */
    private Runnable doTask(String jobData) {
        return new Runnable() {
            @Override
            public void run() {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                
                System.out.println("-----------------(doTask)---------------");
                // 业务逻辑
                System.out.println("jobData: " + jobData + ",时间为: " + simpleDateFormat.format(new Date()));
            }
        };
    }

    /**
     * 业务触发器
     * 
     * @return
     */
    private Trigger getTrigger(String cron) {
        return new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 触发器
                CronTrigger trigger = new CronTrigger(cron);
                return trigger.nextExecutionTime(triggerContext);
            }
        };
    }

}
View Code

4.工具类BeanUtils.java

package com.ll.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanUtils
{

   public static Field findField(Class<?> clazz, String name)
   {
      try
      {
         return clazz.getField(name);
      }
      catch (NoSuchFieldException ex)
      {
         return findDeclaredField(clazz, name);
      }
   }

   public static Field findDeclaredField(Class<?> clazz, String name)
   {
      try
      {
         return clazz.getDeclaredField(name);
      }
      catch (NoSuchFieldException ex)
      {
         if (clazz.getSuperclass() != null)
         {
            return findDeclaredField(clazz.getSuperclass(), name);
         }
         return null;
      }
   }

   public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
   {
      try
      {
         return clazz.getMethod(methodName, paramTypes);
      }
      catch (NoSuchMethodException ex)
      {
         return findDeclaredMethod(clazz, methodName, paramTypes);
      }
   }

   public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
   {
      try
      {
         return clazz.getDeclaredMethod(methodName, paramTypes);
      }
      catch (NoSuchMethodException ex)
      {
         if (clazz.getSuperclass() != null)
         {
            return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
         }
         return null;
      }
   }

   public static Object getProperty(Object obj, String name) throws NoSuchFieldException
   {
      Object value = null;
      Field field = findField(obj.getClass(), name);
      if (field == null)
      {
         throw new NoSuchFieldException("no such field [" + name + "]");
      }
      boolean accessible = field.isAccessible();
      field.setAccessible(true);
      try
      {
         value = field.get(obj);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);
      }
      field.setAccessible(accessible);
      return value;
   }

   public static void setProperty(Object obj, String name, Object value) throws NoSuchFieldException
   {
      Field field = findField(obj.getClass(), name);
      if (field == null)
      {
         throw new NoSuchFieldException("no such field [" + name + "]");
      }
      boolean accessible = field.isAccessible();
      field.setAccessible(true);
      try
      {
         field.set(obj, value);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);
      }
      field.setAccessible(accessible);
   }

   public static Map<String, Object> obj2Map(Object obj, Map<String, Object> map)
   {
      if (map == null)
      {
         map = new HashMap<String, Object>();
      }
      if (obj != null)
      {
         try
         {
            Class<?> clazz = obj.getClass();
            do
            {
               Field[] fields = clazz.getDeclaredFields();
               for (Field field : fields)
               {
                  int mod = field.getModifiers();
                  if (Modifier.isStatic(mod))
                  {
                     continue;
                  }
                  boolean accessible = field.isAccessible();
                  field.setAccessible(true);
                  map.put(field.getName(), field.get(obj));
                  field.setAccessible(accessible);
               }
               clazz = clazz.getSuperclass();
            } while (clazz != null);
         }
         catch (Exception e)
         {
            throw new RuntimeException(e);
         }
      }
      return map;
   }

   /**
    * 获得父类集合,包含当前class
    * 
    * @param clazz
    * @return
    */
   public static List<Class<?>> getSuperclassList(Class<?> clazz)
   {
      List<Class<?>> clazzes = new ArrayList<Class<?>>(3);
      clazzes.add(clazz);
      clazz = clazz.getSuperclass();
      while (clazz != null)
      {
         clazzes.add(clazz);
         clazz = clazz.getSuperclass();
      }
      return Collections.unmodifiableList(clazzes);
   }
}
View Code

5、运行

主要写法:

1、实现SchedulingConfigurer接口

2、重写configureTasks方法,本地储存定时器对象, 方便后期维护

@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
	this.taskRegistrar = scheduledTaskRegistrar;
}

3、执行定时器

TaskScheduler scheduler = taskRegistrar.getScheduler();
// cron = "*/5 * * * * ?"
ScheduledFuture<?> future = scheduler.schedule(doTask(jobData), getTrigger(cron));

  

原文地址:https://www.cnblogs.com/hzb462606/p/15490120.html