使用JobDetailBean
1: 添加Quartz依赖jar包
添加Quartz包的依赖
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
2. 配置文件
创建并配置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<import resource="spring-context.xml"/>
<import resource="test-job-quartz.xml"/>
</beans>
创建并配置spring-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- 注解autowire驱动 -->
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
</beans>
创建并配置test-job-quartz.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- 测试定时任务 -->
<bean name="testTaskJobBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.hm.quartz.TestJob" />
<property name="durability" value="true" />
</bean>
<bean id="testTaskJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testTaskJobBean" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
<bean id="springJobFactory" class="com.hm.job.SpringJobFactory" />
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="testTaskJobTrigger"/>
</list>
</property>
<property name="jobFactory" ref="springJobFactory" />
</bean>
</beans>
3. 配置SpringJobFactory
package com.hm.job;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public class SpringJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
this.applicationContext = applicationContext;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle)throws Exception {
Object obj = super.createJobInstance(bundle);
if (obj != null) {
applicationContext.getAutowireCapableBeanFactory().autowireBean(obj);
}
return obj;
}
}
4. 配置执行类
package com.hm.quartz;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class TestJob extends QuartzJobBean {
private static final Logger LOGGER = LoggerFactory.getLogger(TestJob.class);
@Override
protected void executeInternal(JobExecutionContext context)throws JobExecutionException {
LOGGER.info("【TestJob running job... 】");
//TODO 处理自己的业务逻辑
}
}
5. 编写启动测试
创建2个启动测试, 分别右键启动
package com.hm.quartz;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppOne {
private static Logger LOGGER = LoggerFactory.getLogger(AppOne.class);
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "spring/applicationContext.xml" });
context.start();
LOGGER.info("【AppOne==========MainQuartzTest==========:{}】", "Start");
}
}
package com.hm.quartz;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTwo {
private static Logger LOGGER = LoggerFactory.getLogger(AppTwo.class);
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "spring/applicationContext.xml" });
context.start();
LOGGER.info("【AppTwo==========MainQuartzTest==========:{}】", "Start");
}
}
结果如下: 可以看到AppOne 和AppTwo 均已经成功启动,并定时执行。
但是这2个线程在同一个时间点如15:16:20
, 均执行了任务,这样在集群的环境下会导致一个任务执行了多次的问题
#AppOne 打印
2019-04-28 15:16:04,437 INFO [org.quartz.core.QuartzScheduler] Scheduler quartzScheduler_$_NON_CLUSTERED started.
2019-04-28 15:16:04,453 INFO [org.springframework.context.support.DefaultLifecycleProcessor] Starting beans in phase 2147483647
2019-04-28 15:16:04,453 INFO [com.hm.quartz.AppOne] 【AppOne==========MainQuartzTest==========:Start】
2019-04-28 15:16:10,023 INFO [com.hm.quartz.TestJob] 【TestJob running job... 】
2019-04-28 15:16:20,014 INFO [com.hm.quartz.TestJob] 【TestJob running job... 】
2019-04-28 15:16:30,013 INFO [com.hm.quartz.TestJob] 【TestJob running job... 】
#AppTwo 打印
2019-04-28 15:16:17,674 INFO [com.hm.quartz.AppTwo] 【AppTwo==========MainQuartzTest==========:Start】
2019-04-28 15:16:20,015 INFO [com.hm.quartz.TestJob] 【TestJob running job... 】
2019-04-28 15:16:30,014 INFO [com.hm.quartz.TestJob] 【TestJob running job... 】
代码下载:spring集成Quartz-1
使用MethodInvokeJobDetailFactoryBean
有变动的地方如下
创建并配置test-job-quartz.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- 具体执行的任务,同quartz使用 -->
<bean id="mainService" class="com.hm.quartz.TestJob">
<constructor-arg index="0" value="node-1"></constructor-arg>
</bean>
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- job-name -->
<property name="name" value="test-job" />
<!-- job-group -->
<property name="group" value="test-group" />
<!-- 调用的类 -->
<property name="targetObject" ref="mainService" />
<!-- 调用类中的方法 -->
<property name="targetMethod" value="start" />
<!--是否允许任务并发执行。当值为false时,表示必须等到前一个线程处理完毕后才再启一个新的线程 -->
<property name="concurrent" value="false" />
</bean>
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail" />
<property name="startDelay" value="0" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
<bean id="scheduler" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
</beans>
package com.hm.quartz;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestJob {
private String name;
public TestJob(String name) {
this.name = name;
}
public void print() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("time:" + dateFormat.format(date) + name.concat(" doing............"));
}
public void start(){
print();
}
}
代码下载:spring集成Quartz-2