好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

浅谈在springboot中使用定时任务的方式

springboot定时任务

在springboot环境下有多种方法,这里记录下使用过的其中两种;1、使用注解,2、通过实现接口的方式。

使用注解的方式虽然比较简单,但是如果项目需要用户对定时周期进行修改操作,只使用注解就比较难实现。所以可以使用实现接口的方式。通过对接口的实现,可以在项目运行时根据需要修改任务执行周期,只需要关闭原任务再开启新任务即可。

1、使用注解方式

​ 首先需要在启动类下添加 @EnableScheduling 注解(@EnableAsync是开启异步的注解)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package com.fongtech.cli;

 

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.annotation.EnableScheduling;

 

@SpringBootApplication

@MapperScan ( "com.fongtech.cli.mbg.*.**" )

@EnableAsync

@EnableScheduling

public class SpringbootAdminApplication {

 

     public static void main(String[] args) {

         SpringApplication.run(SpringbootAdminApplication. class , args);

     }

 

}

接着在需要用到定时任务的类和方法下加 @Component 和 @Scheduled(cron = "0 0/1 * * * ? ")注解,其中@Scheduled()中的 ‘cron' 有固定的格式。(@Async注解表示开启异步)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@Slf4j

@Component

public class AsyncTaskConfiguration {

 

     /**

      * 每分钟检查任务列表,判断任务类型执行相应的任务

      * 根据实际任务执行情况,限定执行任务数量

      */

     @Scheduled (cron = "0 0/1 * * * ? " )

     @Async

     public void startCommonTask() throws Exception {

         log.info( "startCommonTask  start........." + Thread.currentThread().getName());

         commonTaskService.startCommonTask();

         log.info( "startCommonTask  end........." + Thread.currentThread().getName());

 

     }}

2、使用实现接口的方式

​ 通过实现 SchedulingConfigurer 接口,可对定时任务进行操作。实现接口的方式相比使用注解更加灵活,但需要编写代码,相对繁琐。

​ 实现工具类如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

package com.fongtech.cli.admin.tasktime;

 

import com.fongtech.cli.common.util.BeanUtils;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.SchedulingException;

import org.springframework.scheduling.TaskScheduler;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.scheduling.annotation.SchedulingConfigurer;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import org.springframework.scheduling.config.TriggerTask;

import org.springframework.scheduling.support.CronTrigger;

 

import javax.annotation.PostConstruct;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ScheduledFuture;

 

/**

  * @author linb

  * @date 2020/6/15 11:16

  */

@Configuration

//@EnableScheduling

public class DefaultSchedulingConfigurer implements SchedulingConfigurer {

     private ScheduledTaskRegistrar taskRegistrar;

     private Set<ScheduledFuture<?>> scheduledFutures = null ;

     private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<>();

 

     @Override

     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

         this .taskRegistrar = taskRegistrar;

     }

 

     @SuppressWarnings ( "unchecked" )

     private Set<ScheduledFuture<?>> getScheduledFutures() {

         if (scheduledFutures == null ) {

             try {

                 // spring版本不同选用不同字段scheduledFutures

                 scheduledFutures = (Set<ScheduledFuture<?>>) BeanUtils.getProperty(taskRegistrar, "scheduledTasks" );

             } catch (NoSuchFieldException e) {

                 throw new SchedulingException( "not found scheduledFutures field." );

             }

         }

         return scheduledFutures;

     }

 

     /**

      * 添加任务

      */

     public void addTriggerTask(String taskId, TriggerTask triggerTask) {

         if (taskFutures.containsKey(taskId)) {

             throw new SchedulingException( "the taskId[" + taskId + "] was added." );

         }

         TaskScheduler scheduler = taskRegistrar.getScheduler();

         ScheduledFuture<?> future = scheduler.schedule(triggerTask.getRunnable(), triggerTask.getTrigger());

         getScheduledFutures().add(future);

         taskFutures.put(taskId, future);

     }

 

     /**

      * 取消任务

      */

     public void cancelTriggerTask(String taskId) {

         ScheduledFuture<?> future = taskFutures.get(taskId);

         if (future != null ) {

             future.cancel( true );

         }

         taskFutures.remove(taskId);

         getScheduledFutures().remove(future);

     }

 

     /**

      * 重置任务

      */

     public void resetTriggerTask(String taskId, TriggerTask triggerTask) {

         cancelTriggerTask(taskId);

         addTriggerTask(taskId, triggerTask);

     }

 

     /**

      * 任务编号

      */

     public Set<String> taskIds() {

         return taskFutures.keySet();

     }

 

     /**

      * 是否存在任务

      */

     public boolean hasTask(String taskId) {

         return this .taskFutures.containsKey(taskId);

     }

 

     /**

      * 任务调度是否已经初始化完成

      */

     public boolean inited() {

         return this .taskRegistrar != null && this .taskRegistrar.getScheduler() != null ;

     }

}

​ 在项目启动后就自动开启任务的操作类如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

package com.fongtech.cli.admin.tasktime;

 

import com.fongtech.cli.admin.service.IAuthLoginService;

import com.fongtech.cli.admin.service.IBackupsService;

import com.fongtech.cli.admin.service.IDictionnaryEntryService;

import com.fongtech.cli.mbg.model.entity.AuthLogin;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.CommandLineRunner;

import org.springframework.core.annotation.Order;

import org.springframework.scheduling.config.TriggerTask;

import org.springframework.scheduling.support.CronTrigger;

import org.springframework.stereotype.Component;

 

/**

  * 项目启动后执行,

  */

@Slf4j

@Component

@Order (value = 1 )

public class CmdRunner implements CommandLineRunner {

 

     @Autowired

     private DefaultSchedulingConfigurer defaultSchedulingConfigurer;

     @Autowired

     private IDictionnaryEntryService dictionnaryEntryService;

     @Autowired

     private IBackupsService backupsService;

     @Autowired

     private IAuthLoginService authLoginService;

 

     @Override

     public void run(String... args) throws Exception {

         log.info( "------按照预设备份周期启动数据库备份定时任务" );

         while (!defaultSchedulingConfigurer.inited())

         {

             try {

                 Thread.sleep( 100 );

             } catch (InterruptedException e) {

                 e.printStackTrace();

             } finally {

 

             }

         }

         String cron = dictionnaryEntryService.getEntryValueByName( "CRON_VALUE" );

         //默认按照管理员用户权限执行备份任务

         AuthLogin authLogin = authLoginService.query().eq(AuthLogin::getLogin_user, "admin" ).getOne();

         //启动线程,按照原表内的时间执行备份任务

         defaultSchedulingConfigurer.addTriggerTask( "task" ,

                 new TriggerTask(

                         () -> System.out.println( "=====----------启动定时任务=-----------" );,

                         new CronTrigger(cron)));

     }

}

​ 暂停定时任务:

?

1

defaultSchedulingConfigurer.cancelTriggerTask( "task" );

到此这篇关于浅谈在springboot中使用定时任务的方式的文章就介绍到这了,更多相关springboot定时任务内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://blog.csdn.net/iampatrick_star/article/details/117930163

查看更多关于浅谈在springboot中使用定时任务的方式的详细内容...

  阅读:16次