手动调用接口 开启\关闭一个定时任务(demo)

首先提供一个接口作为  开启关闭定时任务   因本地数据库嫌麻烦用redis暂时存一下模仿动态编辑执行时间

package com.dj.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;


/**
 * 定时任务自动/手动
 *
 * @author suliaodaidai
 * @Date 2023/08/13 16:24
 */
@RestController
@RequestMapping("/daiDai/task")
@Slf4j
public class Test {


    //官方提供接口      内涵可关闭的方法
    private ScheduledFuture<?> future;

    //注入Bean 用于调度定时任务  按照提供的schedule方法自定义
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    //容器内需要有一个名为它的组件
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
        return new ThreadPoolTaskScheduler();
    }

    @Autowired
    private StringRedisTemplate redisTemplate;
    @RequestMapping("/open")
    public String openTask(){

        String s = "0/5 * * * * *";
        String s1 = redisTemplate.opsForValue().get("corn");
            future= threadPoolTaskScheduler.schedule(new MyTask(), new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    return new CronTrigger(s1 == null ? s :s1).nextExecutionTime(triggerContext);
                }
            });
            log.info("定时任务开启++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            if (s1!=null){
                log.info("定时任务开启并且执行策略已更新最新效果++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            }
            log.info("定时任务开启成功  正在等待运行定时任务 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
     return "定时任务开始成功";
    }

    @RequestMapping("/close")
    public String close(){
        log.info("定时任务正在关闭中++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        if (future != null){
            //fratrue 提供的方法  如应该终端则为  true  无定时任务是  应该不会执行此方法,但是不影响调用
            future.cancel(true);
        }else {
            log.info("定时任务关闭失败++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        }
        log.info("定时任务正在关闭成功++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return "定时任务关闭成功";
    }

    @RequestMapping("/redisSet")
    public String redisSetCorn(String corn){
        //后续可使用正则验证
        //或者存如数据库取出
        redisTemplate.opsForValue().set("corn",corn);
        if (future != null){
            //修改了执行时间  ,正在重启定时任务服务
            log.info("修改了执行时间,正在重启定时任务服务++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            future.cancel(true);
        }
        try {
            openTask();
            log.info("重启定时任务服务成功++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        }catch (Exception e){
            return "服务异常请重试";
        }

        return "已修改缓存中的corn值  下一次开启定时任务时策略生效";
    }
}

 写了一个简单的打印  模拟要执行的任务 这里实现了Runnable接口不受Spring容器管理,需要手动注入bean找了一个第三方应用上下文工具类(实现了Runnable,用@Autowired 注入了redis为null导致空指针异常)

package com.dj.task;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @author suliaodaidai
 */
@Component
public class MyTask implements Runnable{

    private StringRedisTemplate redisTemplate;

    @Override
    public void run() {
        redisTemplate = SpringContextUtils.getApplicationContext().getBean(StringRedisTemplate.class);
        String s = redisTemplate.opsForValue().get("corn");
//        String s = (String)redisTemplate.opsForValue().get("corn");
        String substring = s.substring(s.indexOf("/"), s.indexOf(" "));
//        String substring = s == null ? "" : s.substring(2, 3);
        System.out.println(substring +"秒执行一次" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }


}
@Component
class SpringContextUtils implements ApplicationContextAware {

    /**
     * 应用上下文
     */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException {
        return (T)applicationContext.getBean(name);
    }

    public static <T> T getBean(Class<T> clz) throws BeansException {
        return (T)applicationContext.getBean(clz);
    }

}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值