热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Java定时任务详解

定时任务在项目中经常会使用到,本文主要根据博主自己使用定时的经验分如下几点介绍定时任务:1、Quartz定时任务简介及Spring配置Quartz定时任务;2、SchedulerFactory对定时任务进行增删改查

定时任务在项目中经常会使用到,本文主要根据博主自己使用定时的经验分如下几点介绍定时任务:

1、Quartz定时任务简介及Spring配置Quartz定时任务

2、SchedulerFactory对定时任务进行增删改查

3、总结

Quartz定时任务简介:

Quartz是项目中经常用到的定时任务之一,是一个完全由java编写的开源作业调度框架,可以与J2EE与J2SE应用程序相结合也可以单独使用,其主要组成部分包括Job、Scheduler、CronExpression,这里就不一一介绍了,下面介绍Spring如何配置Quartz。

配置Quartz需要明白的一点是配置Quartz即配置Job、Scheduler和CronExpression,这三部分配置完成后,就是一个完整的定时任务,配置如下:

 
  
   
   
     
      
      
     
   


 
   
  


 
   
     
       
     
   



配置完成后,就是增加一个为你执行一个任务的Java类。每一个Quartz Job必须有一个 实现了org.quartz.Job接口的具体类,代码如下:

public class TestQuartzJob extends QuartzJobBean {
  @Override
  protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException
  {
    // 获取Job配置的接口
    TestServiceImpl testServiceImpl = (TestServiceImpl) arg0.getJobDetail().getJobDataMap().get("testServiceImpl");
    // 执行业务方法
    quartzStart();
  }
  public void quartzStart(){
    // 业务方法...
  }
}

当然,在Job中其实不用特意的配置接口,使用Spring的注入即可,这里只是把这个配置接口的方法进行说明。

到这里,简单的配置Quartz定时任务已经完成,下面附加一个我在项目中使用Quartz的情形:cronExpression表达式从数据库读取。

当时,我解决这个问题的方法是继承org.springframework.scheduling.quartz.CronTriggerBean,设置cronExpression,具体代码如下:

Trigger的配置要改:


  
  

xx.InitCronTriggerFactoryBean代码:

public class InitCronTriggerFactoryBean extends CronTriggerFactoryBean implements Serializable {

  private static final long serialVersiOnUID= 1L;

  @Resource
  private SysParamService sysParamService;

  private String key;

  public void setKey(String key)
  {
    this.key = key;

    setCronExpression(getCronExpressionFromDB());
  }

  private String getCronExpressionFromDB()
  {
    if(StringUtils.isEmpty(key))
      return "0 0/5 * * * ?";

    SysParam sysParam = new SysParam();

    try
    {
      sysParam = sysParamService.getNameByKey(key);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    if(sysParam != null && !StringUtils.isEmpty(sysParam.getParamValue()))
      return sysParam.getParamValue();

    return "0 0/5 * * * ?";
  }
}

其中,SysParamService是根据key到数据库查询对应的cronExpression表达式的接口,这个接口除了使用Spring注入,也可以使用set方法设置,如下:


  
  
  



这样,在xx.InitCronTriggerFactoryBean就要加入sysParamService的set方法,此时的xx.InitCronTriggerFactoryBean代码为:

public class InitCronTriggerFactoryBean extends CronTriggerFactoryBean implements Serializable {
  private static final long serialVersiOnUID= 1L;
  private SysParamServiceImpl sysParamService;
  private String key;
  public void setKey(String key)
  {
    this.key = key;
  }
  public void setSysParamService(SysParamServiceImpl sysParamService)
  {
    this.sysParamService = sysParamService;
    setCronExpression(getCronExpressionFromDB());
  }
  private String getCronExpressionFromDB()
  {
    if(StringUtils.isEmpty(key))
      return "0 0 0/1 * * ?";
    SysParam sysParam = new SysParam();
    try
    {
      sysParam = sysParamServiceImpl.getNameByKey(key);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    if(sysParam != null && !StringUtils.isEmpty(sysParam.getParamValue()))
      return sysParam.getParamValue();
    return "0 0 0/1 * * ?";
  }
}

Quartz定时任务到这里就差不多了,基本的配置和使用就是上面将的,想要深入了解Quartz可以在网上查找更多的资料,并在实践中使用。接下来将讲解在项目中使用的可以随时对定时任务进行增删改查操作的实例。

定时任务的增删改查,其实可以看做是对数据进行增删改查。不过,定时任务的增删改查是操作Job和Trigger,具体代码如下:

定时任务管理器代码:

public class QuartzManager {

  private static final Logger logger = LogPresident.getRootLogger();

  private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

  private static Map jobKeyMap = new HashMap();

  /**
  * 增加一个定时任务
  * @author zhiyuan.wu
  * @date 2017年3月30日
  * @param jobName
  * @param triggerName
  * @param cls
  * @param date
  */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static void addJob(String jobName, String triggerName, Class cls, Date date)
  {
    try
    {
      Scheduler scheduler = schedulerFactory.getScheduler();

      // job
      JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, Scheduler.DEFAULT_GROUP).build();

      // 触发器
      SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(triggerName, Scheduler.DEFAULT_GROUP).startAt(date).build();

      scheduler.scheduleJob(jobDetail, trigger);

      // 启动
      scheduler.start();

      jobKeyMap.put(jobDetail.getKey().getName(), jobDetail.getKey());
    }
    catch (Exception e)
    {
      logger.error("--------添加定时任务出错:" + e.getMessage(), e);
    }
  }

/**
* 删除对应的定时任务
* @author zhiyuan.wu
* @date 2017年3月29日
* @param jobKey
*/
public static void removeJob(JobKey jobKey)
{
  Scheduler scheduler;
  try
  {
    scheduler = schedulerFactory.getScheduler();
    scheduler.deleteJob(jobKey);

      jobKeyMap.remove(jobKey.getName());
    }
    catch (SchedulerException e)
    {
      logger.error("--------删除定时任务出错:" + e.getMessage(), e);
    }
  }

/**
* 启动所有定时任务
* @author zhiyuan.wu
* @date 2017年3月29日
*/
public static void startJobs()
{
  try
  {
    Scheduler sched = schedulerFactory.getScheduler();
    sched.start();
  }
  catch (Exception e)
  {
    logger.error("--------启动所有定时任务出错:" + e.getMessage(), e);
  }
}

/**
* 停止所有定时任务
* @author zhiyuan.wu
* @date 2017年3月29日
*/
public static void shutdownJobs()
{
  try
  {
    Scheduler sched = schedulerFactory.getScheduler();

    if (!sched.isShutdown())
    {
      sched.shutdown();
    }
  }
  catch (Exception e)
  {
    logger.error("--------停止所有定时任务出错:" + e.getMessage(), e);
  }
}

/**
* 修改定时任务
* @author zhiyuan.wu
* @date 2017年3月29日
* @param jobKey
* @param jobName
* @param triggerName
* @param cls
* @param date
*/
@SuppressWarnings("rawtypes")
public static void modifyJobTime(JobKey jobKey, String jobName, String triggerName, Class cls, Date date)
{
  try
  {
    removeJob(jobKey);

    addJob(jobName, triggerName, cls, date);
  }
  catch (Exception e)
  {
    logger.error("--------修改定时任务出错:" + e.getMessage(), e);
  }
}

/**
* 打印当前定时任务的jobName
* @author zhiyuan.wu
* @date 2017年3月29日
* @throws SchedulerException
*/
public static void printJobName() throws SchedulerException
{
  for (String jobName : jobKeyMap.keySet())
  {
    logger.info("--------jobName:" + jobName);
  }
}
}

Job代码:

public class TestJob implements Job {

  private static final Logger logger = LogPresident.getRootLogger();

  public void execute(JobExecutionContext context) throws JobExecutionException
  {
    JobKey jobKey = context.getJobDetail().getKey();

    logger.info("--------定时任务开始执行:" + jobKey.getName());

    // 业务方法...
    // 移除定时任务
    QuartzManager.removeJob(jobKey);
  }
}

增加一个定时任务代码:

QuartzManager.addJob(JobName, TriggerName , TestJob.class, Date);

这样,在到达时间Date时,定时任务将会执行。不过这样增加的任务是保存在内存中,项目重启将会丢失定时任务,所以,最好增加一个类,在项目启动时将会扫描数据库,将未执行的定时任务重新加载到内存中去。

定时任务在项目中运用需要根据业务具体调整,但只要弄清楚定时任务的原理和实现,那么就可以在项目中灵活运它用来具体的业务,希望这篇文章可以让大家快速了解和运用定时任务,并运用到实践中。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


推荐阅读
  • 本文深入解析了 Kubernetes 控制平面(特别是 API 服务器)与集群节点之间的通信机制,并对其通信路径进行了详细分类。旨在帮助用户更好地理解和定制其安装配置,从而增强网络安全性,确保集群的稳定运行。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 使用ArcGIS for Java和Flex浏览自定义ArcGIS Server 9.3地图
    本文介绍了如何在Flex应用程序中实现浏览自定义ArcGIS Server 9.3发布的地图。这是一个基本的入门示例,适用于初学者。 ... [详细]
  • 本文介绍了如何在GitHub上设置多个SSH Key,以解决原有Key失效的问题,并确保不同项目使用不同的私钥进行安全访问。 ... [详细]
  • 本文详细介绍了在 Ubuntu 系统上搭建 Hadoop 集群时遇到的 SSH 密钥认证问题及其解决方案。通过本文,读者可以了解如何在多台虚拟机之间实现无密码 SSH 登录,从而顺利启动 Hadoop 集群。 ... [详细]
  • 本文将详细介绍如何注册码云账号、配置SSH公钥、安装必要的开发工具,并逐步讲解如何下载、编译 HarmonyOS 2.0 源码。通过本文,您将能够顺利完成 HarmonyOS 2.0 的环境搭建和源码编译。 ... [详细]
  • 本文介绍了如何使用Python的Paramiko库批量更新多台服务器的登录密码。通过示例代码展示了具体实现方法,确保了操作的高效性和安全性。Paramiko库提供了强大的SSH2协议支持,使得远程服务器管理变得更加便捷。此外,文章还详细说明了代码的各个部分,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 如何在方法上应用@ConfigurationProperties注解进行属性绑定 ... [详细]
  • 如何在Windows内置的Ubuntu系统中更改SSH服务的端口号设置
    如何在Windows内置的Ubuntu系统中更改SSH服务的端口号设置 ... [详细]
  • 本文详细探讨了几种常用的Java后端开发框架组合及其具体应用场景。通过对比分析Spring Boot、MyBatis、Hibernate等框架的特点和优势,结合实际项目需求,为开发者提供了选择合适框架组合的参考依据。同时,文章还介绍了这些框架在微服务架构中的应用,帮助读者更好地理解和运用这些技术。 ... [详细]
  • SecureCRT是一款功能强大的终端仿真软件,支持SSH1和SSH2协议,适用于在Windows环境下高效连接和管理Linux服务器。该工具不仅提供了稳定的连接性能,还具备丰富的配置选项,能够满足不同用户的需求。通过SecureCRT,用户可以轻松实现对远程Linux系统的安全访问和操作。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • FreeBSD环境下PHP GD库安装问题的详细解决方案
    在 FreeBSD 环境下,安装 PHP GD 库时可能会遇到一些常见的问题。本文详细介绍了从配置到编译的完整步骤,包括解决依赖关系、配置选项以及常见错误的处理方法。通过这些详细的指导,开发者可以顺利地在 FreeBSD 上完成 PHP GD 库的安装,确保其正常运行。此外,本文还提供了一些优化建议,帮助提高安装过程的效率和稳定性。 ... [详细]
author-avatar
妖精蝴蝶74
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有