一、背景

    SSM项目中要用到定时器,初期使用Timer,后来用spring 的schedule,都比较简单,所以功能比较单一而且他们不能动态的配置时间。后来就研究quartz,准备整合到项目中。Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。

二、quartz的官网下载压缩包

  最好下载稳定版,我这里下载的是2.3.0,quartz下载地址

三、建立数据库,导入sql脚本

  sql脚本的位置:quartz-2.3.0-distribution\quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore\tables_mysql_innodb.sql(我项目中使用的mysql),这里要注意,不同类型的数据库要用不同的数据库脚本;

四、Maven中导入依赖 

  这里quartz的版本必须与数据库脚本的版本一致不然会报错。因为quartz的每个版本数据库改动挺大的,假如这里配置的2.3.0,而你用2.1.7的sql脚本,肯定会出错。所以要一一匹配。

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>

五、配置文件

  quartz的持久化有两种,一种是RAM,一种是JDBC。

  RAMJobStore是使用最简单的JobStore,它也是性能最高的(在CPU时间方面)。RAMJobStore以其明显的方式获取其名称:它将其所有数据保存在RAM中。这就是为什么它是闪电般快的,也是为什么这么简单的配置。缺点是当您的应用程序结束(或崩溃)时,所有调度信息都将丢失 - 这意味着RAMJobStore无法履行作业和triggers上的“非易失性”设置。对于某些应用程序,这是可以接受的 - 甚至是所需的行为,但对于其他应用程序,这可能是灾难性的。

  JDBCJobStore也被恰当地命名 - 它通过JDBC将其所有数据保存在数据库中。因此,配置比RAMJobStore要复杂一点,而且也不是那么快。但是,性能下降并不是很糟糕,特别是如果您在主键上构建具有索引的数据库表。在相当现代的一套具有体面的LAN(在调度程序和数据库之间)的机器上,检索和更新触发triggers的时间通常将小于10毫秒。

  本次整合采用的是JDBCStore。如果你采用RAMStore,你只需要将org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX注释掉,把Configure Datasources标签中的内容注释掉。

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
# #============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: quartzScheduler
org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 2
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================ #default config
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true #============================================================================
#havent cluster spring
#============================================================================
org.quartz.jobStore.isClustered = false #数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_ #============================================================================
# Configure Datasources,如果在spring的配置文件中,指定dataSource,那么就是用的spring中已经配置好的数据源,即被覆盖。如果没有指定dataSource,则使用的是此处配置的数据库参数
#============================================================================
org.quartz.jobStore.dataSource:qzDS
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/magicmedecg
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root

六、spring与quartz的整合配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd"> <!-- quartz -->
<bean id="scheduleReportFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--这里使用的是spring中已经配置好的数据源;当然如果不配置则使用quartz.properties中的数据库配置。-->
        <property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="startupDelay" value="100"/>
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<property name="configLocation" value="classpath:quartz.properties"/>
</bean> </beans>

七、定义Job类

这里的@Setter是生成类的属性的setter方法,这个注解不是quartz的,而是lombok的。@sertter = 属性的setter方法。

@Setter
public class RemindUserJob implements Job { private String appuserId; private String orderSn; private static int count = 0; @Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); System.out.println("我执行了,时间是" + System.currentTimeMillis() + ",count = " + count + ",appuserId = " + appuserId + ",orderSn=" + orderSn); count++;
}
}

八、创建任务

@RequestMapping("test04")
@ResponseBody
public void test04() throws Exception { // 创建scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 创建JobDetail
JobDetail jobDetail = newJob(RemindUserJob.class)
.withIdentity("job1", "group1")
.usingJobData("appuserId", "asdfghjkl")
.usingJobData("orderSn", "0as8fg")
.build(); // 指定时间触发,每隔2s执行一次,重复20次
Trigger trigger2 = newTrigger()
.withIdentity("trigger2", "group1")
.startAt(new Date())
.withSchedule(simpleSchedule()
.withIntervalInSeconds(2)
.withRepeatCount(20))
.build(); scheduler.scheduleJob(jobDetail,trigger2);
scheduler.start();
}

九、运行效果

[2019-03-25 15:11:08,149] [org.quartz.impl.StdSchedulerFactory] : Quartz scheduler 'quartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
[2019-03-25 15:11:08,150] [org.quartz.impl.StdSchedulerFactory] : Quartz scheduler version: 2.3.0
[2019-03-25 15:11:08,255] [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] : Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge15ka11duunroghgkbm|aa25642, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge15ka11duunroghgkbm|aa25642, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/magicmedecg, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
[2019-03-25 15:11:08,525] [org.quartz.impl.jdbcjobstore.JobStoreTX] : Freed 0 triggers from 'acquired' / 'blocked' state.
[2019-03-25 15:11:08,530] [org.quartz.impl.jdbcjobstore.JobStoreTX] : Recovering 0 jobs that were in-progress at the time of the last shut-down.
[2019-03-25 15:11:08,530] [org.quartz.impl.jdbcjobstore.JobStoreTX] : Recovery complete.
[2019-03-25 15:11:08,532] [org.quartz.impl.jdbcjobstore.JobStoreTX] : Removed 0 'complete' triggers.
[2019-03-25 15:11:08,534] [org.quartz.impl.jdbcjobstore.JobStoreTX] : Removed 0 stale fired job entries.
[2019-03-25 15:11:08,535] [org.quartz.core.QuartzScheduler] : Scheduler quartzScheduler_$_NON_CLUSTERED started.
我执行了,时间是1553497868902,count = 0,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497870183,count = 1,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497872178,count = 2,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497874183,count = 3,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497876179,count = 4,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497878177,count = 5,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497880178,count = 6,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497882180,count = 7,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497884183,count = 8,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497886184,count = 9,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497888176,count = 10,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497890175,count = 11,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497892177,count = 12,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497894178,count = 13,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497896176,count = 14,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497898190,count = 15,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497900381,count = 16,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497902176,count = 17,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497904205,count = 18,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497906175,count = 19,appuserId = asdfghjkl,orderSn=0as8fg
我执行了,时间是1553497908177,count = 20,appuserId = asdfghjkl,orderSn=0as8fg

注:整合过程中可能遇到的异常:spring整合quartz异常:org.quartz.JobPersistenceException: Couldn't clean volatile data: Unknown column 'IS_VOLATILE' in 'where clause'

SSM项目整合Quartz的更多相关文章

  1. SSM项目整合基本步骤

    SSM项目整合 1.基本概念 1.1.Spring Spring 是一个开源框架, Spring 是于 2003  年兴起的一个轻量级的 Java  开发框架,由 Rod Johnson  在其著作  ...

  2. SSM项目整合第一步 注册登陆实现

    SSM项目整合第一步  注册: 项目目录: 一.数据库建表: 源码: ; -- ---------------------------- -- Table structure for t_user - ...

  3. SSM 项目整合

    SSM整合:spring + springmvc + mybatis 1.1 生成Maven项目:ar_ssm 1.2 添加jar包 <dependencies> <!-- 单元测试 ...

  4. SSM项目整合纪实

    一 前 言 本来是为了探究一些功能性问题,需要一套完整的项目架构,本以为SSM用过那么多了,轻松搭建不在话下,但是过程中还是遇到一些问题,踩到一些未曾料想的坑.博文以搭建极简架构为目的,附带一些关键阐 ...

  5. ssm项目整合shiro

    pom.xml <properties> <shiro.version>1.2.2</shiro.version> </properties> < ...

  6. Solr专题(三)SSM项目整合Solr

    一.环境配置 所需要的jar包: org.apache.solr.solr-solrj maven依赖: <!-- https://mvnrepository.com/artifact/org. ...

  7. SpringMVC详解及SSM框架整合项目

    SpringMVC ssm : mybatis + Spring + SpringMVC MVC三层架构 JavaSE:认真学习,老师带,入门快 JavaWeb:认真学习,老师带,入门快 SSM框架: ...

  8. SSM 整合 quartz JDBC方式实现job动态增删改查记录

    虽然网上有很多资料,但是都不够系统,本文记录下自己的整合过程. 1. 搭建一个SSM项目,此处略. 2. 按照quartz官方要求,建立quartz相关的数据库和表,相关sql语句如下: /* Nav ...

  9. 使用IntelliJ IDEA创建Maven聚合工程、创建resources文件夹、ssm框架整合、项目运行一体化

    一.创建一个空的项目作为存放整个项目的路径 1.选择 File——>new——>Project ——>Empty Project 2.WorkspaceforTest为项目存放文件夹 ...

随机推荐

  1. Linux运维企业架构实战系列

    Linux运维企业架构项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-LVS.nginx实现负载均衡系列 2.1 项目实战2.1-实现基于LVS负载均衡集 ...

  2. shared_ptr和动态数组

    std::shared_ptr智能指针是c++11一个相当重要的特性,可以极大地将开发者从资源申请/释放的繁重劳动中解放出来. 然而直到c++17前std::shared_ptr都有一个严重的限制,那 ...

  3. 【转载】 Sqlserver中通过Select Into语句快速单表备份

    在Sqlserver数据库中,备份数据的方式有很多种,可以使用整个数据库备份,也可使用导出包含数据和架构的脚本文件的方式来进行单表或多表数据的备份,其实还有一种Select Into的方式可以快速备份 ...

  4. 15个常用的javaScript正则表达式

    1 用户名正则 //用户名正则,4到16位(字母,数字,下划线,减号) ,}$/; //输出 true console.log(uPattern.test("iFat3")); 2 ...

  5. iframe 父页面调用子页面的vue方法

                    父页面代码:            html: <div id="app"> //省略业务代码x行..... <iframe sr ...

  6. Github 快速建库上传本地代码

    1 github.com网页端先建好一个空库 2 本地对这个库进行 git clone 3 向本地库中添加已完成文件 4 运行如下命令 git add . (注:别忘记后面的.,此操作是把Test文件 ...

  7. (四) Keras Dropout和正则化的使用

    视频学习来源 https://www.bilibili.com/video/av40787141?from=search&seid=17003307842787199553 笔记 使用drop ...

  8. Android为TV端助力 电影栏目移动到底部或者顶部时抖动动画

    1 移动到底部上下抖动ObjectAnimator animatorX = ObjectAnimator.ofFloat(holder.itemView,"translationX" ...

  9. 导入虚拟机vmware,此主机支持Intel VT-x,但Intel VT-x处于禁用状态和黑屏

    解决方法:进入BIOS(按什么键进入bios,需要看你用什么电脑),把Intel Virtualization Technology         设置enabled 然后是黑屏解决方法:管理员模式 ...

  10. JavaScript jQuery 中定义数组操作及数组操作

    1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象 Javascript不支持多维数组,但是因为数组里面可以包含对象(数组也是一个对象),所以数组可以通过相互嵌套实现类似多维 ...