pring 4.x 注解方式配置quartz 2.2.x的集群

首先是pom.xml

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<artifactId>quartz-test</artifactId>
	<version>1.0</version>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<junit.version>4.12</junit.version>
		<spring.version>4.1.2.RELEASE</spring.version>
		<mysql.version>5.1.34</mysql.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- ============================== -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>
</project>

 创建数据库及表。

1、数据库名为:quartz

2、从http://quartz-scheduler.org/downloads上下载quartz包。

3、解压后,可从以docs\dbTables目录 下找到对应数据库的建表sql。

 quartz.properties

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool  
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore  
#============================================================================

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = clusterDS
org.quartz.jobStore.tablePrefix = QRTZ_
#你就告诉了 Scheduler 实例要它参与到一个集群当中。
org.quartz.jobStore.isClustered = true
#定义了Scheduler 实例检入到数据库中的频率(毫秒为单位)。Scheduler 检查是否其他的实例到了它们应当检入的时候未检入;
#这能指出一个失败的 Scheduler 实例,且当前 Scheduler 会以此来接管任何执行失败并可恢复的 Job。
#通过检入操作,Scheduler 也会更新自身的状态记录。
org.quartz.jobStore.clusterCheckinInterval = 20000

#============================================================================
# Configure Datasources  
#============================================================================

org.quartz.dataSource.clusterDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.clusterDS.URL = jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useFastDateParsing=false&autoReconnect=true
org.quartz.dataSource.clusterDS.user = root
org.quartz.dataSource.clusterDS.password = 123456
org.quartz.dataSource.clusterDS.maxConnections = 30
org.quartz.dataSource.clusterDS.validationQuery=select RAND()


#============================================================================
# Configure Plugins 
#============================================================================

org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin

 log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<appender name="default" class="org.apache.log4j.ConsoleAppender">
		<param name="target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss.SSS aa} %t [%c]%n%m%n%n" />
		</layout>
	</appender>


	<logger name="org.quartz">
		<level value="info" />
	</logger>

	<root>
		<level value="info" />
		<appender-ref ref="default" />
	</root>


</log4j:configuration>
package com.test.quartz;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Component;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
//@Scope("prototype")
public @interface QuartzJob
{

	String name();

	String group() default "DEFAULT_GROUP";

	String cronExp();
}
package com.test.quartz;

import org.quartz.Job;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public class SpringQuartzJobFactory extends SpringBeanJobFactory
{
	Logger logger = LoggerFactory.getLogger(SpringQuartzJobFactory.class);
	
	@Autowired
	private ApplicationContext ctx;

	@Override
	@SuppressWarnings("unchecked")
	protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception
	{
		Job job = null;
		try
		{
			job = ctx.getBean(bundle.getJobDetail().getJobClass());
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
			MutablePropertyValues pvs = new MutablePropertyValues();
			pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
			pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
			bw.setPropertyValues(pvs, true);
		}
		catch (Exception e)
		{
			logger.error(e.getMessage(), e);
			throw new Exception(e);
		}
		return job;
	}
}
package com.test.quartz;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;

public class QuartJobSchedulingListener implements ApplicationListener<ContextRefreshedEvent>
{
	Logger logger = LoggerFactory.getLogger(QuartJobSchedulingListener.class);

	@Autowired
	private Scheduler scheduler;

	public void onApplicationEvent(ContextRefreshedEvent event)
	{
		try
		{
			ApplicationContext applicationContext = event.getApplicationContext();
			this.loadCronTriggers(applicationContext, scheduler);
		}
		catch (Exception e)
		{
			logger.error(e.getMessage(), e);
		}
	}

	private void loadCronTriggers(ApplicationContext applicationContext, Scheduler scheduler)
	{
		Map<String, Object> quartzJobBeans = applicationContext.getBeansWithAnnotation(QuartzJob.class);
		Set<String> beanNames = quartzJobBeans.keySet();
		List<CronTrigger> cronTriggerBeans = new ArrayList<CronTrigger>();
		for (String beanName : beanNames)
		{
			Object object = quartzJobBeans.get(beanName);
			try
			{
				if (Job.class.isAssignableFrom(object.getClass()))
				{
					QuartzJob quartzJobAnnotation = AnnotationUtils.findAnnotation(object.getClass(), QuartzJob.class);
					JobKey jobKey = new JobKey(quartzJobAnnotation.name(), quartzJobAnnotation.group());
					JobDetail job = JobBuilder
							.newJob((Class<? extends Job>) object.getClass())
							.withIdentity(jobKey)
							.build();
					CronTrigger cronTrigger = TriggerBuilder
							.newTrigger()
							.withIdentity(quartzJobAnnotation.name() + "_trigger", quartzJobAnnotation.group())
							.withSchedule(CronScheduleBuilder.cronSchedule(quartzJobAnnotation.cronExp()))
							.build();
					scheduler.scheduleJob(job, cronTrigger);
				}
				else
				{
					String errorMsg = object.getClass() + " doesn't implemented " + Job.class.getName();
					logger.error(errorMsg);
					throw new RuntimeException(errorMsg);
				}
			}
			catch (Exception e)
			{
				logger.error(e.getMessage(), e);
			}
		}
	}
}

 applicationContext-quartz.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- 一定要在使用web中开启注解扫描配置 -->
	<context:annotation-config/> <context:component-scan base-package="com.test"/>
	
	<!-- 数据源 -->
	<!-- <bean name="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${hibernate.connection.driver_class}" />
		<property name="url" value="${hibernate.connection.url}" />
		<property name="username" value="${hibernate.connection.username}" />
		<property name="password" value="${hibernate.connection.password}" />
	</bean> -->

	<bean class="com.test.quartz.QuartJobSchedulingListener" />
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobFactory">
			<bean class="com.test.quartz.SpringQuartzJobFactory"></bean>
		</property>
		<!-- <property name="dataSource" ref="dataSource"/> -->
		<!-- 要记得要指定配置文件的位置 -->
		<property name="configLocation" value="classpath:quartz.properties" />
	</bean>
</beans>
package com.test.quartz;

import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.test.quartz.QuartzJob;

@QuartzJob(name = "HelloJob", cronExp = "0/5 * * * * ?")
public class HelloJob extends QuartzJobBean
{
	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException
	{
		System.out.println("Hello Job is running @ " + new Date());
		System.out.println(this.hashCode());
	}
}
package com.test.quartz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClient
{
	public static void main(String[] args)
	{
		ApplicationContext context =
				new ClassPathXmlApplicationContext("config/applicationContext-test.xml","config/applicationContext-quartz.xml");
		//System.out.println(context);
	}

}

猜你喜欢

转载自conkeyn.iteye.com/blog/2195942