Les singes âgés vous permettent de maîtriser le démarrage et l'arrêt dynamiques des tâches programmées par Spring boot

Un peu de Tangcheng. 2021-11-25 17:34:15
les singes vous permettent ma

Inspring bootDans le projet,Peut [email protected] [email protected] mise en œuvre des tâches programmées,On peut aussiSchedulingConfigurerInterfaces pour réaliser des tâches programmées.Mais ces deux méthodes ne peuvent pas être ajoutées dynamiquement、Supprimer、Démarrage、Arrêter la tâche.

Pour réaliser la fonction d'ajout dynamique, de suppression, de démarrage et d'arrêt,Une approche plus large est l'intégrationQuartzCadre.Mais mon principe de développement est:Lorsque les besoins du projet sont satisfaits,Compter le moins possible sur d'autres cadres,Évitez de surcharger et de compliquer les projets.

Voirspring-contextC'estjarDans le sacorg.springframework.scheduling.ScheduledTaskRegistrarCode source de cette classe,Il a été constaté qu'il était possible d'ajouter et de supprimer dynamiquement des tâches de démarrage et d'arrêt en modifiant cette classe.

6Les vieux singes te tiennent au courant.Spring BootMise en œuvre de l'ajout et de la suppression dynamiques des tâches programmées_spring boot

Page de liste des tâches programmées

6Les vieux singes te tiennent au courant.Spring BootMise en œuvre de l'ajout et de la suppression dynamiques des tâches programmées_spring_02

Journal d'exécution des tâches programmées

Ajouter une classe de configuration de pool de Threads pour effectuer des tâches programmées


@Configuration
public class SchedulingConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
// Nombre de Threads de base du pool de Threads d'exécution des tâches programmées
taskScheduler. setPoolSize( 4);
taskScheduler. setRemoveOnCancelPolicy( true);
taskScheduler. setThreadNamePrefix( "TaskSchedulerThreadPool-");
return taskScheduler;
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

AjouterScheduledFutureClasse d'emballage.ScheduledFuture- Oui.ScheduledExecutorServiceRésultats de l'exécution du pool de Threads de tâches programmées.


public final class ScheduledTask {

volatile ScheduledFuture <?> future;

/**
* Annuler la tâche programmée
*/
public void cancel() {
ScheduledFuture <?> future = this. future;
if ( future != null) {
future. cancel( true);
}
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

AjouterRunnableClasse d'implémentation d'interface,Appelé par un pool de Threads de tâches programmées,Utilisé pour exécuter la désignationbeanLa méthode à l'intérieur.


public class SchedulingRunnable implements Runnable {

private static final Logger logger = LoggerFactory. getLogger( SchedulingRunnable. class);

private String beanName;

private String methodName;

private String params;

public SchedulingRunnable( String beanName, String methodName) {
this( beanName, methodName, null);
}

public SchedulingRunnable( String beanName, String methodName, String params) {
this. beanName = beanName;
this. methodName = methodName;
this. params = params;
}

@Override
public void run() {
logger. info( "Début de la tâche programmée - bean:{},Méthodes:{},Paramètres:{}", beanName, methodName, params);
long startTime = System. currentTimeMillis();

try {
Object target = SpringContextUtils. getBean( beanName);

Method method = null;
if ( StringUtils. isNotEmpty( params)) {
method = target. getClass(). getDeclaredMethod( methodName, String. class);
} else {
method = target. getClass(). getDeclaredMethod( methodName);
}

ReflectionUtils. makeAccessible( method);
if ( StringUtils. isNotEmpty( params)) {
method. invoke( target, params);
} else {
method. invoke( target);
}
} catch ( Exception ex) {
logger. error( String. format( "Exception à l'exécution des tâches programmées - bean:%s,Méthodes:%s,Paramètres:%s ", beanName, methodName, params), ex);
}

long times = System. currentTimeMillis() - startTime;
logger. info( "Fin de la tâche programmée - bean:{},Méthodes:{},Paramètres:{},Ça prend du temps:{} MS", beanName, methodName, params, times);
}

@Override
public boolean equals( Object o) {
if ( this == o) return true;
if ( o == null || getClass() != o. getClass()) return false;
SchedulingRunnable that = ( SchedulingRunnable) o;
if ( params == null) {
return beanName. equals( that. beanName) &&
methodName. equals( that. methodName) &&
that. params == null;
}

return beanName. equals( that. beanName) &&
methodName. equals( that. methodName) &&
params. equals( that. params);
}

@Override
public int hashCode() {
if ( params == null) {
return Objects. hash( beanName, methodName);
}

return Objects. hash( beanName, methodName, params);
}
}
  • 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.

Ajouter une classe d'enregistrement des tâches programmées,Pour augmenter、Supprimer la tâche programmée.

@Component
public class CronTaskRegistrar implements DisposableBean {

private final Map < Runnable, ScheduledTask > scheduledTasks = new ConcurrentHashMap <>( 16);

@Autowired
private TaskScheduler taskScheduler;

public TaskScheduler getScheduler() {
return this. taskScheduler;
}

public void addCronTask( Runnable task, String cronExpression) {
addCronTask( new CronTask( task, cronExpression));
}

public void addCronTask( CronTask cronTask) {
if ( cronTask != null) {
Runnable task = cronTask. getRunnable();
if ( this. scheduledTasks. containsKey( task)) {
removeCronTask( task);
}

this. scheduledTasks. put( task, scheduleCronTask( cronTask));
}
}

public void removeCronTask( Runnable task) {
ScheduledTask scheduledTask = this. scheduledTasks. remove( task);
if ( scheduledTask != null)
scheduledTask. cancel();
}

public ScheduledTask scheduleCronTask( CronTask cronTask) {
ScheduledTask scheduledTask = new ScheduledTask();
scheduledTask. future = this. taskScheduler. schedule( cronTask. getRunnable(), cronTask. getTrigger());

return scheduledTask;
}


@Override
public void destroy() {
for ( ScheduledTask task : this. scheduledTasks. values()) {
task. cancel();
}

this. scheduledTasks. clear();
}
}
  • 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.

Ajouter une classe d'exemple de tâche programmée


@Component( "demoTask")
public class DemoTask {
public void taskWithParams( String params) {
System. out. println( "Effectuer une tâche d'échantillon avec des paramètres:" + params);
}

public void taskNoParams() {
System. out. println( "Effectuer une tâche d'échantillon sans paramètres");
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

Conception de la table de base de données des tâches programmées

6Les vieux singes te tiennent au courant.Spring BootMise en œuvre de l'ajout et de la suppression dynamiques des tâches programmées_java_03

Conception de la table de base de données des tâches programmées

Ajouter une classe d'entité de tâche programmée


public class SysJobPO {
/**
* MissionID
*/
private Integer jobId;
/**
* beanNom
*/
private String beanName;
/**
* Nom de la méthode
*/
private String methodName;
/**
* Paramètres de la méthode
*/
private String methodParams;
/**
* cronExpression
*/
private String cronExpression;
/**
* Statut(1Normal 0Pause)
*/
private Integer jobStatus;
/**
* Remarques
*/
private String remark;
/**
* Temps de création
*/
private Date createTime;
/**
* Mise à jour
*/
private Date updateTime;

public Integer getJobId() {
return jobId;
}

public void setJobId( Integer jobId) {
this. jobId = jobId;
}

public String getBeanName() {
return beanName;
}

public void setBeanName( String beanName) {
this. beanName = beanName;
}

public String getMethodName() {
return methodName;
}

public void setMethodName( String methodName) {
this. methodName = methodName;
}

public String getMethodParams() {
return methodParams;
}

public void setMethodParams( String methodParams) {
this. methodParams = methodParams;
}

public String getCronExpression() {
return cronExpression;
}

public void setCronExpression( String cronExpression) {
this. cronExpression = cronExpression;
}

public Integer getJobStatus() {
return jobStatus;
}

public void setJobStatus( Integer jobStatus) {
this. jobStatus = jobStatus;
}

public String getRemark() {
return remark;
}

public void setRemark( String remark) {
this. remark = remark;
}

public Date getCreateTime() {
return createTime;
}

public void setCreateTime( Date createTime) {
this. createTime = createTime;
}

public Date getUpdateTime() {
return updateTime;
}

public void setUpdateTime( Date updateTime) {
this. updateTime = updateTime;
}

}
  • 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.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.

Ajouter une tâche programmée

6Les vieux singes te tiennent au courant.Spring BootMise en œuvre de l'ajout et de la suppression dynamiques des tâches programmées_spring_04

Ajouter une tâche programmée


boolean success = sysJobRepository. addSysJob( sysJob);
if ( ! success)
return OperationResUtils. fail( "Impossible d'ajouter");
else {
if ( sysJob. getJobStatus(). equals( SysJobStatus. NORMAL. ordinal())) {
SchedulingRunnable task = new SchedulingRunnable( sysJob. getBeanName(), sysJob. getMethodName(), sysJob. getMethodParams());
cronTaskRegistrar. addCronTask( task, sysJob. getCronExpression());
}
}

return OperationResUtils. success();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

Modifier la tâche programmée,Supprimer d'abord la tâche originale,Redémarrer une nouvelle tâche


boolean success = sysJobRepository. editSysJob( sysJob);
if ( ! success)
return OperationResUtils. fail( "Échec de l'édition");
else {
//Supprimer avant d'ajouter
if ( existedSysJob. getJobStatus(). equals( SysJobStatus. NORMAL. ordinal())) {
SchedulingRunnable task = new SchedulingRunnable( existedSysJob. getBeanName(), existedSysJob. getMethodName(), existedSysJob. getMethodParams());
cronTaskRegistrar. removeCronTask( task);
}

if ( sysJob. getJobStatus(). equals( SysJobStatus. NORMAL. ordinal())) {
SchedulingRunnable task = new SchedulingRunnable( sysJob. getBeanName(), sysJob. getMethodName(), sysJob. getMethodParams());
cronTaskRegistrar. addCronTask( task, sysJob. getCronExpression());
}
}

return OperationResUtils. success();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

Supprimer la tâche programmée


boolean success = sysJobRepository. deleteSysJobById( req. getJobId());
if ( ! success)
return OperationResUtils. fail( "Échec de la suppression");
else{
if ( existedSysJob. getJobStatus(). equals( SysJobStatus. NORMAL. ordinal())) {
SchedulingRunnable task = new SchedulingRunnable( existedSysJob. getBeanName(), existedSysJob. getMethodName(), existedSysJob. getMethodParams());
cronTaskRegistrar. removeCronTask( task);
}
}

return OperationResUtils. success();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

Début de la tâche programmée/Changement d'état d'arrêt

if (existedSysJob.getJobStatus().equals(SysJobStatus.NORMAL.ordinal())) {
SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
cronTaskRegistrar.addCronTask(task, existedSysJob.getCronExpression());
} else {
SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
cronTaskRegistrar.removeCronTask(task);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

Ajouter une mise en œuvreCommandLineRunnerInterfaceSysJobRunnerCatégorie,Quandspring bootAprès le lancement du projet,Chargement des tâches programmées dans la base de données avec un état normal.

@Service
public class SysJobRunner implements CommandLineRunner {

private static final Logger logger = LoggerFactory. getLogger( SysJobRunner. class);

@Autowired
private ISysJobRepository sysJobRepository;

@Autowired
private CronTaskRegistrar cronTaskRegistrar;

@Override
public void run( String... args) {
// Tâche programmée avec un état normal dans la base de données de chargement initial
List < SysJobPO > jobList = sysJobRepository. getSysJobListByStatus( SysJobStatus. NORMAL. ordinal());
if ( CollectionUtils. isNotEmpty( jobList)) {
for ( SysJobPO job : jobList) {
SchedulingRunnable task = new SchedulingRunnable( job. getBeanName(), job. getMethodName(), job. getMethodParams());
cronTaskRegistrar. addCronTask( task, job. getCronExpression());
}

logger. info( "Tâche programmée chargée...");
}
}
}
  • 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.

Classe d'outilsSpringContextUtils,Utilisé à partir despringObtenir dans un contenantbean

@Component
public class SpringContextUtils implements ApplicationContextAware {

private static ApplicationContext applicationContext;

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

public static Object getBean( String name) {
return applicationContext. getBean( name);
}

public static < T > T getBean( Class < T > requiredType) {
return applicationContext. getBean( requiredType);
}

public static < T > T getBean( String name, Class < T > requiredType) {
return applicationContext. getBean( name, requiredType);
}

public static boolean containsBean( String name) {
return applicationContext. containsBean( name);
}

public static boolean isSingleton( String name) {
return applicationContext. isSingleton( name);
}

public static Class <? extends Object > getType( String name) {
return applicationContext. getType( name);
}
}
  • 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.


版权声明
本文为[Un peu de Tangcheng.]所创,转载请带上原文链接,感谢
https://javamana.com/2021/11/20211125173308748a.html

  1. http://lx.gongxuanwang.com/sszt/32.htm
  2. 回顾我两个月面试阿里,携程,小红书,美团,网易等等(Java岗)
  3. JavaScript高级程序设计读后感(一)之零碎知识点查漏补缺
  4. http://lx.gongxuanwang.com/sszt/7.htm
  5. #yyds干货盘点#设计模式之【工厂模式】
  6. Java * SpringBoot实现万能文件在线预览,已开源,真香
  7. Redis | 第4章 Redis中的数据库《Redis设计与实现》
  8. Redis | 第4章 Redis中的数据库《Redis设计与实现》
  9. 关于centos docker版本过低导致 is not a valid repository/tag: invalid reference format
  10. Redis 源码简洁剖析 02 - SDS 字符串
  11. 回顧我兩個月面試阿裏,攜程,小紅書,美團,網易等等(Java崗)
  12. Rétrospectivement, j'ai passé deux mois à interviewer Ali, ctrip, Little Red Book, meituan, NetEase, etc. (Java post)
  13. Docker + webhook Automation Deployment Front End Project
  14. Java技术之Spring、Hibernate框架整合方法
  15. http://lx.gongxuanwang.com/sszt/32.htm
  16. 亚马逊自己的 Linux 发行版现在完全基于 Fedora 了
  17. Redis 源码简洁剖析 02 - SDS 字符串
  18. Java技術之Spring、Hibernate框架整合方法
  19. Méthode d'intégration des cadres de printemps et d'hibernation de la technologie Java
  20. Redis source Concise Analysis 02 - SDS String
  21. La distribution Linux d'Amazon est maintenant entièrement basée sur Fedora
  22. org.springframework.web.bind.MissingServletRequestParameterException
  23. Built in constraints and functions of MySQL Foundation (2)
  24. Basic operation of MySQL Foundation (I)
  25. Introduction to Java zero foundation 3: Java data types
  26. 从零开始搭建EasyDarwin环境——Linux系统开发环境搭建Golang
  27. Redis source Concise Analysis 02 - SDS String
  28. Construire l'environnement easydarwin à partir de zéro - - construire l'environnement de développement du système Linux golang
  29. javaweb代码是正确的,但是第一行代码就报错了
  30. **** | Java | 后端开挂:3行代码写出8个接口
  31. Java || 看了大二学长写的代码,我竟开始默默的模仿了。。。
  32. Java | 手把手教你实现一个抽奖系统(Java版)
  33. Java | Manuel pour vous apprendre à mettre en œuvre un système de loterie (version Java)
  34. Java | | après avoir lu le Code que j'ai écrit en deuxième année, j'ai commencé à imiter silencieusement...
  35. Java | back - end Pending: 3 - line Code write 8 Interfaces
  36. Le Code Web Java est correct, mais la première ligne de code est incorrecte
  37. Android网络编程之Http通信
  38. Android網絡編程之Http通信
  39. Http communication for Android Network Programming
  40. 数据结构实验八 领会图的两种主要储存结构和图的基本运算算法设计
  41. Hibernate数据校验简介
  42. The story of spring
  43. Il a dépensé 270 000 yuans pour soulever Xiaopeng p7 et a parcouru 3 627 km. Le propriétaire du véhicule a partagé 6 avantages et inconvénients.
  44. 阿里蚂蚁花呗团队面试题:spring+分布式+jvm+session+redis
  45. 【Java入门100例】14.字符串排序——compareTo()
  46. 【Java入门100例】13.修改文件扩展名——字符串替换
  47. Leetcode 79. Word Search [C + + / java detailed problem]
  48. Introduction à la vérification des données hibernantes
  49. Expérience de la structure des données
  50. Spring cloud gateway practice 2: more routing configuration methods
  51. Java network programming - summary overview
  52. 基于语法树的 Java 代码自动化插桩
  53. 云原生 Spring Boot 应用配置 Prometheus + Grafana 监控(保姆级)
  54. Spring cloud gateway practice 2: more routing configuration methods
  55. Jenkins file one line of code to deploy. Net program to k8s
  56. Java network programming - summary overview
  57. Cloud Native Spring Boot application configuration Prometheus + grafana Monitoring (baby - sitter)
  58. Insertion automatique de code Java basée sur l'Arbre syntaxique
  59. Le SUV phare de Xiaopeng, Xiaopeng G9, a fait ses débuts au salon de l'automobile et s'est tenu en position C dans la nouvelle force?
  60. Docker 从入门到实践系列四 - Docker 容器编排利器 Docker Compose