spring4.3.7整合quartz2.2.3

因项目需要,在SSM中整合quartz,其中遇到了几处很坑的地方,作为记录,方便以后查看。

项目背景:

​ Maven构建项目:Spring4.3.7、Shiro1.3.2、Quartz2.2.3,数据库用的是MySQL 5.6.36

1. 首先引入Quartz的jar包

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

2. 在数据库中建立Quartz相关的表

tables_mysql_innodb.sql 这些表在官网上可以下载,http://www.quartz-scheduler.org/downloads/ ,解压后在quartz-2.2.3\docs\dbTables下,选择合适的SQL

   #
   # In your Quartz properties file, you'll need to set 
   # org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
   #
   #
   # By: Ron Cordell - roncordell
   #  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.

   DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
   DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
   DROP TABLE IF EXISTS QRTZ_LOCKS;
   DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_TRIGGERS;
   DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
   DROP TABLE IF EXISTS QRTZ_CALENDARS;

   CREATE TABLE QRTZ_JOB_DETAILS(
   SCHED_NAME VARCHAR(120) NOT NULL,
   JOB_NAME VARCHAR(200) NOT NULL,
   JOB_GROUP VARCHAR(200) NOT NULL,
   DESCRIPTION VARCHAR(250) NULL,
   JOB_CLASS_NAME VARCHAR(250) NOT NULL,
   IS_DURABLE VARCHAR(1) NOT NULL,
   IS_NONCONCURRENT VARCHAR(1) NOT NULL,
   IS_UPDATE_DATA VARCHAR(1) NOT NULL,
   REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
   JOB_DATA BLOB NULL,
   PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_TRIGGERS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   TRIGGER_NAME VARCHAR(200) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   JOB_NAME VARCHAR(200) NOT NULL,
   JOB_GROUP VARCHAR(200) NOT NULL,
   DESCRIPTION VARCHAR(250) NULL,
   NEXT_FIRE_TIME BIGINT(13) NULL,
   PREV_FIRE_TIME BIGINT(13) NULL,
   PRIORITY INTEGER NULL,
   TRIGGER_STATE VARCHAR(16) NOT NULL,
   TRIGGER_TYPE VARCHAR(8) NOT NULL,
   START_TIME BIGINT(13) NOT NULL,
   END_TIME BIGINT(13) NULL,
   CALENDAR_NAME VARCHAR(200) NULL,
   MISFIRE_INSTR SMALLINT(2) NULL,
   JOB_DATA BLOB NULL,
   PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
   FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
   REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   TRIGGER_NAME VARCHAR(200) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   REPEAT_COUNT BIGINT(7) NOT NULL,
   REPEAT_INTERVAL BIGINT(12) NOT NULL,
   TIMES_TRIGGERED BIGINT(10) NOT NULL,
   PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
   FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
   REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_CRON_TRIGGERS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   TRIGGER_NAME VARCHAR(200) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   CRON_EXPRESSION VARCHAR(120) NOT NULL,
   TIME_ZONE_ID VARCHAR(80),
   PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
   FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
   REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_SIMPROP_TRIGGERS
     (          
       SCHED_NAME VARCHAR(120) NOT NULL,
       TRIGGER_NAME VARCHAR(200) NOT NULL,
       TRIGGER_GROUP VARCHAR(200) NOT NULL,
       STR_PROP_1 VARCHAR(512) NULL,
       STR_PROP_2 VARCHAR(512) NULL,
       STR_PROP_3 VARCHAR(512) NULL,
       INT_PROP_1 INT NULL,
       INT_PROP_2 INT NULL,
       LONG_PROP_1 BIGINT NULL,
       LONG_PROP_2 BIGINT NULL,
       DEC_PROP_1 NUMERIC(13,4) NULL,
       DEC_PROP_2 NUMERIC(13,4) NULL,
       BOOL_PROP_1 VARCHAR(1) NULL,
       BOOL_PROP_2 VARCHAR(1) NULL,
       PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
       FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
       REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_BLOB_TRIGGERS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   TRIGGER_NAME VARCHAR(200) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   BLOB_DATA BLOB NULL,
   PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
   INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
   FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
   REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_CALENDARS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   CALENDAR_NAME VARCHAR(200) NOT NULL,
   CALENDAR BLOB NOT NULL,
   PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_FIRED_TRIGGERS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   ENTRY_ID VARCHAR(95) NOT NULL,
   TRIGGER_NAME VARCHAR(200) NOT NULL,
   TRIGGER_GROUP VARCHAR(200) NOT NULL,
   INSTANCE_NAME VARCHAR(200) NOT NULL,
   FIRED_TIME BIGINT(13) NOT NULL,
   SCHED_TIME BIGINT(13) NOT NULL,
   PRIORITY INTEGER NOT NULL,
   STATE VARCHAR(16) NOT NULL,
   JOB_NAME VARCHAR(200) NULL,
   JOB_GROUP VARCHAR(200) NULL,
   IS_NONCONCURRENT VARCHAR(1) NULL,
   REQUESTS_RECOVERY VARCHAR(1) NULL,
   PRIMARY KEY (SCHED_NAME,ENTRY_ID))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_SCHEDULER_STATE (
   SCHED_NAME VARCHAR(120) NOT NULL,
   INSTANCE_NAME VARCHAR(200) NOT NULL,
   LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
   CHECKIN_INTERVAL BIGINT(13) NOT NULL,
   PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
   ENGINE=InnoDB;

   CREATE TABLE QRTZ_LOCKS (
   SCHED_NAME VARCHAR(120) NOT NULL,
   LOCK_NAME VARCHAR(40) NOT NULL,
   PRIMARY KEY (SCHED_NAME,LOCK_NAME))
   ENGINE=InnoDB;

   CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
   CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);

   CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
   CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
   CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
   CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
   CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
   CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
   CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
   CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
   CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
   CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
   CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
   CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

   CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
   CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
   CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
   CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
   CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
   CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);

   commit; 

然后向qrtz_locks表中插入几条数据,要不会报错。

No row exists in table QRTZ_LOCKS for lock named: TRIGGER_ACCESS [See nested exception: java.sql.SQLException: No row exists in table QRTZ_LOCKS for lock named: TRIGGER_ACCESS]

INSERT INTO `qrtz_locks` VALUES ('scheduler', 'TRIGGER_ACCESS');
INSERT INTO `qrtz_locks` VALUES ('scheduler', 'JOB_ACCESS');
INSERT INTO `qrtz_locks` VALUES ('scheduler', 'CALENDAR_ACCESS');
INSERT INTO `qrtz_locks` VALUES ('scheduler', 'STATE_ACCESS');
INSERT INTO `qrtz_locks` VALUES ('scheduler', 'MISFIRE_ACCESS');

3. 新建Quartz相关的配置文件:quartz.properties

官网的配置文件持久化用的是Oracle数据库,我这里用的是MySQL,略作修改。

# 官网配置:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/ConfigJDBCJobStoreClustering.html
#===================================================================
# Configure Main Scheduler Properties
#===================================================================
org.quartz.scheduler.instanceName: quartzScheduler
org.quartz.scheduler.instanceId = AUTO

#===================================================================
# 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
#===================================================================
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:false

#===================================================================
#havent cluster spring
#===================================================================
#集群配置
org.quartz.jobStore.isClustered = false  

#数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_

#===================================================================
# Configure Datasources
#===================================================================
#JDBC驱动  Sping去管理dataSource ,这里不在配置数据源信息,如需要可以单独配置数据源
#org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
#org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz_test
#org.quartz.dataSource.qzDS.user:root
#org.quartz.dataSource.qzDS.password:root
#org.quartz.dataSource.qzDS.maxConnection:10

4. 整合Spring和Quartz

在applicationContext.xml文件中添加

   <bean id="customJobFactory" class="com.demo.job.CustomJobFactory"></bean>

   <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
   	<property name="dataSource" ref ="dataSource" />
   	<!-- 可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
   	<property name="overwriteExistingJobs" value="true" />
   	<!-- 必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 -->
   	<property name="startupDelay" value="2" />
   	<!-- 重要:customJobFactory 是为了解决Spring quartz Job不能依赖注入。 -->
   	<property name="jobFactory" ref="customJobFactory"></property>
   	<!-- applicationContextSchedulerContextKey:配置这个可以获取spring容器中的context --> 
   	<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
   	<property name="configLocation" value="classpath:quartz.properties"/>
   </bean>

CustomJobFactory.java的代码如下:

   package com.demo.job;

   import org.quartz.spi.TriggerFiredBundle;  
   import org.springframework.beans.factory.annotation.Autowired;  
   import org.springframework.beans.factory.config.AutowireCapableBeanFactory;  
   import org.springframework.scheduling.quartz.SpringBeanJobFactory;  
     
   public class CustomJobFactory extends SpringBeanJobFactory{  
     
       @Autowired    
       private AutowireCapableBeanFactory capableBeanFactory;    
       
       @Override    
       protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {    
           //调用父类的方法    
           Object jobInstance = super.createJobInstance(bundle);    
           //进行注入    
           capableBeanFactory.autowireBean(jobInstance);    
           return jobInstance;    
       }   
   }

5. 添加定时任务(作为示例service只写了一个方法,接口就不写了)

package com.demo.service.impl;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.service.QuartzService;

@Service
public class QuartzServiceImpl implements QuartzService{
	
	private static Logger _log = LoggerFactory.getLogger(QuartzServiceImpl.class);
	
	@Autowired
	private Scheduler quartzScheduler;
	
	@Override
	public void runOnce(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class cls,
			Object data) {
		try {
			// 获取调度器
			Scheduler sched = quartzScheduler;
			// 创建一项作业
			JobDetail job = JobBuilder.newJob(cls)
					.withIdentity(jobName, jobGroupName).build();
			// 传入参数
			job.getJobDataMap().put("data", data);
			// 创建一个触发器
			SimpleTrigger trigger = TriggerBuilder.newTrigger()
					.withIdentity(triggerName, triggerGroupName)
					.withSchedule(SimpleScheduleBuilder
							.simpleSchedule()
							.withIntervalInSeconds(1)
							//重复执行的次数,因为加入任务的时候马上执行了,所以不需要重复,否则会多一次。
							.withRepeatCount(0))
					.build();
			// 告诉调度器使用该触发器来安排作业
			sched.scheduleJob(job, trigger);
			// 启动
			if (!sched.isShutdown()) {
				sched.start();
				_log.info("开始执行runOnce,时间:{}", new Date());
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

6. 定时任务,具体的业务逻辑

@Autowired注入,想数据库中添加一条数据,需要配置customJobFactory,上边有提到。

package com.demo.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.demo.common.result.AppResultConstant;
import com.demo.exception.AppException;
import com.demo.service.DiscountCouponService;

public class DiscountCouponJob extends QuartzJobBean{
	
	private static Logger _log = LoggerFactory.getLogger(DiscountCouponJob.class);
	
	@Autowired
	private DiscountCouponService discountCouponService;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		Object object = context.getJobDetail().getJobDataMap().get("data");
		if (!(object instanceof Integer)) {
			_log.error("参数格式不正确,应为:Integer,实际传参:{}", object);
			throw new AppException(AppResultConstant.INVALID_DATA);
		}
		Integer userId = Integer.parseInt(object.toString());
		discountCouponService.insertRegisterdiscountCoupon(userId);
		_log.info("添加新手优惠券成功!userId:{}", userId);
	}
}

重点来了!!

如果你的项目中用到了shiro,项目是起不来的,初始化quartzScheduler这个bean错误,因为shiro-quartz默认是对Quartz1.6版本的实现,所以一直会报一下错误:

unknow column ‘IS_VOLATILE’ in ‘where clause’

因为高版本的Quartz,比如quartz-2.0.2以后的版本数据库表结构变了,没有IS_VOLATILE这个字段了,所以要在shiro-quartz中排出对quartz的依赖,在pom.xml文件中修改:

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-quartz</artifactId>
	<version>${shiro.version}</version>
	<!-- 解决shiro和quartz的冲突问题 -->
	<exclusions>
		 <exclusion>
			<groupId>org.opensymphony.quartz</groupId>
			<artifactId>quartz</artifactId>
		 </exclusion>
	  </exclusions>
</dependency>

**总结:**普通的Spring和Quartz的整合并不费时间,主要是项目中用到了Shiro,卡了一两天。

实际上,在pom.xml文件中看到shiro-quartz时我还有点疑问,但并没有深究,但问题就出在细节上了。

下面贴出spring相关的jar包

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<maven.compiler.source>1.7</maven.compiler.source>
	<maven.compiler.target>1.7</maven.compiler.target>
	<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
	<spring.version>4.3.7.RELEASE</spring.version>
	<mybatis.version>3.4.2</mybatis.version>
	<mybatis-spring.version>1.3.1</mybatis-spring.version>
	<mybatis-pagehelper.version>5.0.1</mybatis-pagehelper.version>
	<mybatis-generator.version>1.3.5</mybatis-generator.version>
	<mybatis-ehcache.version>1.0.0</mybatis-ehcache.version>
	<ehcache.version>2.10.0</ehcache.version>
	<shiro.version>1.3.2</shiro.version>
</properties>

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>3.8.1</version>
	</dependency>
	<!-- spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aop</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aspects</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jdbc</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-test</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jms</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<!-- spring security -->
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-web</artifactId>
		<version>${spring-security.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>
		<version>${spring-security.version}</version>
	</dependency>
	<!--spring-session -->
	<dependency>
		<groupId>org.springframework.session</groupId>
		<artifactId>spring-session-data-redis</artifactId>
		<version>1.3.0.RELEASE</version>
	</dependency>
	<!-- quartz 任务调度 -->
	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz</artifactId>
		<version>2.2.3</version>
	</dependency>
	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz-jobs</artifactId>
		<version>2.2.3</version>
	</dependency>
	<!-- shiro -->
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-core</artifactId>
		<version>${shiro.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-web</artifactId>
		<version>${shiro.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-quartz</artifactId>
		<version>${shiro.version}</version>
		<!-- 解决shiro和quartz的冲突问题 -->
		<exclusions>
		  <exclusion>
			 <groupId>org.opensymphony.quartz</groupId>
			 <artifactId>quartz</artifactId>
		  </exclusion>
	   </exclusions>
	</dependency>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-spring</artifactId>
		<version>${shiro.version}</version>
	</dependency>
	<!-- mybatis -->
	<dependency>
		<groupId>org.mybatis</groupId>
		<artifactId>mybatis</artifactId>
		<version>${mybatis.version}</version>
	</dependency>
	<dependency>
		<groupId>org.mybatis</groupId>
		<artifactId>mybatis-spring</artifactId>
		<version>${mybatis-spring.version}</version>
	</dependency>
	<dependency>
		<groupId>com.github.pagehelper</groupId>
		<artifactId>pagehelper</artifactId>
		<version>${mybatis-pagehelper.version}</version>
	</dependency>
	<dependency>
		<groupId>org.mybatis.generator</groupId>
		<artifactId>mybatis-generator-core</artifactId>
		<version>${mybatis-generator.version}</version>
	</dependency>
	<!-- velocity模板引擎 -->
	<dependency>
		<groupId>org.apache.velocity</groupId>
		<artifactId>velocity</artifactId>
		<version>1.7</version>
	</dependency>
	<!-- 缓存 -->
	<dependency>
		<groupId>net.sf.ehcache</groupId>
		<artifactId>ehcache</artifactId>
		<version>${ehcache.version}</version>
	</dependency>
	<dependency>
		<groupId>org.mybatis</groupId>
		<artifactId>mybatis-ehcache</artifactId>
		<version>${mybatis-ehcache.version}</version>
	</dependency>
	<!-- mysql -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.34</version>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
		<version>1.0.14</version>
	</dependency>
	<!-- 日志 -->
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-api</artifactId>
		<version>1.7.12</version>
	</dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.7.12</version>
	</dependency>
	<!-- 上传 -->
	<dependency>
		<groupId>commons-fileupload</groupId>
		<artifactId>commons-fileupload</artifactId>
		<version>1.3.1</version>
	</dependency>
	<!-- swagger2 -->
	<dependency>
		<groupId>io.springfox</groupId>
		<artifactId>springfox-swagger2</artifactId>
		<version>2.4.0</version>
	</dependency>
	<dependency>
		<groupId>io.springfox</groupId>
		<artifactId>springfox-swagger-ui</artifactId>
		<version>2.4.0</version>
	</dependency>
	<!-- 常用工具包 -->
	<dependency>
		<groupId>commons-beanutils</groupId>
		<artifactId>commons-beanutils</artifactId>
		<version>1.9.3</version>
	</dependency>
	<dependency>
		<groupId>commons-lang</groupId>
		<artifactId>commons-lang</artifactId>
		<version>2.6</version>
	</dependency>
	<dependency>
		<groupId>commons-codec</groupId>
		<artifactId>commons-codec</artifactId>
		<version>1.10</version>
	</dependency>
	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-compress</artifactId>
		<version>1.12</version>
	</dependency>
	<!-- fluent-validator -->
	<dependency>
		<groupId>com.baidu.unbiz</groupId>
		<artifactId>fluent-validator</artifactId>
		<version>1.0.6</version>
	</dependency>
	<!-- json -->
	<dependency>
		<groupId>net.sf.json-lib</groupId>
		<artifactId>json-lib</artifactId>
		<version>2.4</version>
		<classifier>jdk15</classifier>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>1.2.28</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-core</artifactId>
		<version>2.6.5</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>2.6.5</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-annotations</artifactId>
		<version>2.6.5</version>
	</dependency>
	<!-- httpclient -->
	<dependency>
		<groupId>org.apache.httpcomponents</groupId>
		<artifactId>httpclient</artifactId>
		<version>4.5.2</version>
	</dependency>
	<!-- aspectj -->
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>1.8.8</version>
	</dependency>
	<!-- servlet -->
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>servlet-api</artifactId>
		<version>2.5</version>
		<scope>provided</scope>
	</dependency>
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
		<version>1.2</version>
	</dependency>
</dependencies>

参考文档:

http://www.quartz-scheduler.org

http://fanshuyao.iteye.com/blog/2392350

https://github.com/dufyun/quartz-core-learning


我的最新文章会先发到公众号【读钓的YY】上,欢迎关注!

发布了10 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/youthsong/article/details/79182567