Spring boot基于ScheduledFuture实现前端动态控制定时器开启关闭执行service层业务逻辑

5 篇文章 0 订阅
3 篇文章 0 订阅
使用的是swagger2进行前端接口测试

pom坐标

 <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
TaskController
package com.haitai.controller;

import com.haitai.common.TaskConfiguration;
import com.haitai.utils.RunnableEPE;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.core.config.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

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

@Slf4j
@Controller
@Api(tags = "定时任务")
@RequestMapping("/task")
public class TaskController {
    @Autowired
    private TaskConfiguration TaskConfiguration;
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    private ScheduledFuture<?> future1;
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }

    @RequestMapping(value ="start",method = RequestMethod.POST)
    @ApiOperation(value = "开启定时任务", httpMethod = "POST")
    @ResponseBody
    public void startCron1() {
        future1 = threadPoolTaskScheduler.schedule(new RunnableEPE(),new Trigger(){
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext){
                return new CronTrigger(TaskConfiguration.getCorn1()).nextExecutionTime(triggerContext);
            }
        });
    }
    @RequestMapping(value ="stop",method = RequestMethod.POST)
    @ApiOperation(value = "关闭定时任务", httpMethod = "POST")
    @ResponseBody
    public void stopCron1() {
        System.out.println("stop!!!!!!!!!!!!!!!!!!!!!!!");
        if (future1 != null) {
            future1.cancel(true);
        }
    }
}
application.properties配置类,可配置多个定时任务时间,我这里就配置了一个
#自定义定时器时间
task.corn1=0/1 * * * * ?
TaskConfiguration获取properties中的定时时间
package com.haitai.common;


import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "task")
@EqualsAndHashCode(callSuper = false)
public class TaskConfiguration {
    private String corn1;
    private String corn2;
}
RunnableUtil工具类
package com.haitai.utils;

import com.haitai.service.TaskService;
import com.haitai.service.impl.TaskServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Component//将工具类声明为spring组件
public class RunnableUtil implements Runnable {
    @Autowired
    TaskService taskService;
    //静态初使化当前类
    public static RunnableUtil runnableUtil;
    //    @PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。
    //    Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被、、、@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
    //    通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
    //    Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
    //    应用:在静态方法中调用依赖注入的Bean中的方法。
    @PostConstruct
    public void init() {
        runnableUtil = this;
        runnableUtil.taskService = this.taskService;
    }
    @Override
    public void run() {
        try {
            runnableUtil.taskService.startEPE();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
TaskService业务接口
package com.haitai.service;

public interface TaskService {
    void startEPE();
}
TaskServiceImpl业务接口实现类
package com.haitai.service.impl;

import com.haitai.service.TaskService;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class TaskServiceImpl implements TaskService{
    @Override
    public void startEPE() {
        //业务逻辑代码
        System.out.println("first DynamicTask," + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

执行结果:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot中,我们可以使用`@Scheduled`注解来配置定时任务。默认情况下,这个注解支持固定的时间表达式,例如:`@Scheduled(cron = "0 0 12 * * ?")`表示每天中午12点执行任务。 如果想要动态调整定时任务的执行时间,可以使用以下步骤: 1. 创建一个定时任务管理器类,用于管理所有的定时任务。这个类可以维护一个任务列表,每个任务都有一个唯一的ID和对应的执行时间表达式。 ``` @Component public class TaskManager { private Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>(); public void addTask(String id, Runnable task, String cronExpression) { ScheduledFuture<?> future = taskScheduler().schedule(task, new CronTrigger(cronExpression)); tasks.put(id, future); } public void removeTask(String id) { ScheduledFuture<?> future = tasks.get(id); if (future != null) { future.cancel(true); tasks.remove(id); } } public void updateTask(String id, String cronExpression) { removeTask(id); // 重新添加任务 // ... } private ThreadPoolTaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); scheduler.setThreadNamePrefix("TaskScheduler-"); scheduler.setWaitForTasksToCompleteOnShutdown(true); scheduler.setAwaitTerminationSeconds(60); scheduler.initialize(); return scheduler; } } ``` 2. 在需要执行的任务上添加`@Component`和`@Scope("prototype")`注解,这样每次调用`addTask`方法时都会创建一个新的任务实例。 ``` @Component @Scope("prototype") public class MyTask implements Runnable { private String id; public MyTask(String id) { this.id = id; } @Override public void run() { // 任务执行逻辑 } } ``` 3. 在需要动态调整执行时间的地方调用`TaskManager`的相关方法,例如: ``` @Autowired private TaskManager taskManager; @Autowired private ApplicationContext context; // 添加任务 MyTask task = context.getBean(MyTask.class, "task1"); taskManager.addTask("task1", task, "0 0/5 * * * ?"); // 修改任务执行时间 taskManager.updateTask("task1", "0 0/10 * * * ?"); // 删除任务 taskManager.removeTask("task1"); ``` 这样我们就可以动态调整定时任务的执行时间了。需要注意的是,修改任务执行时间时需要先删除旧的任务再添加新的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Exception.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值