`

Spring Quartz 持久化解决方案

阅读更多


Quartz是实现了序列化接口的,包括接口,所以可以使用标准方式序列化到数据库。
而Spring2.5.6在集成Quartz时却未能考虑持久化问题。


Spring对JobDetail进行了封装,却未实现序列化接口,所以持久化的时候会产生NotSerializable问题,这也是网上一直在那边叫嚣为什么不能持久化到数据库问题,哥今天看了下Spring源码,发现Spring对Quartz持久化的问题.
1. 不知道Spring未来会不会对持久化的支持,不过我们可以有如下解决方案,比如改写
Spring的代码,实现序列化接口.
2. 不使用Spring的Fatory,自己实现任务的初始化.

既然Spring不支持持久化,那么持久化任务还是自己编写实现吧,否则每次都需要打包发布,麻烦,自己编写的类与Quartz完全兼容.

注意:为什么Spring不支持外配置任务,可能也是考虑到这方面问题所以才不提供这些任务的执行化支持.[配置文件配置与数据库配置重复]

直接使用Quartz是支持序列化功能,比如直接使用页面配置Quartz界面,设置任务执行时间等属性。

通过配置实现的是不应该初始化到数据库,否则直接在数据库中配置了。不过也是可以配置的,通过改写JobDetailBean.代码如下:

package org.frame.auth.service;

import java.util.Map;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.quartz.DelegatingJob;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

public class PersistentJobDetailBean extends JobDetail
implements BeanNameAware, InitializingBean {

	private static final long serialVersionUID = -4389885435844732405L;

	private Class actualJobClass;

	private String beanName;

	/**
	 * Overridden to support any job class, to allow a custom JobFactory
	 * to adapt the given job class to the Quartz Job interface.
	 * @see SchedulerFactoryBean#setJobFactory
	 */
	public void setJobClass(Class jobClass) {
		if (jobClass != null && !Job.class.isAssignableFrom(jobClass)) {
			super.setJobClass(DelegatingJob.class);
			this.actualJobClass = jobClass;
		}
		else {
			super.setJobClass(jobClass);
		}
	}

	/**
	 * Overridden to support any job class, to allow a custom JobFactory
	 * to adapt the given job class to the Quartz Job interface.
	 */
	public Class getJobClass() {
		return (this.actualJobClass != null ? this.actualJobClass : super.getJobClass());
	}

	/**
	 * Register objects in the JobDataMap via a given Map.
	 * <p>These objects will be available to this Job only,
	 * in contrast to objects in the SchedulerContext.
	 * <p>Note: When using persistent Jobs whose JobDetail will be kept in the
	 * database, do not put Spring-managed beans or an ApplicationContext
	 * reference into the JobDataMap but rather into the SchedulerContext.
	 * @param jobDataAsMap Map with String keys and any objects as values
	 * (for example Spring-managed beans)
	 * @see SchedulerFactoryBean#setSchedulerContextAsMap
	 */
	public void setJobDataAsMap(Map jobDataAsMap) {
		getJobDataMap().putAll(jobDataAsMap);
	}

	/**
	 * Set a list of JobListener names for this job, referring to
	 * non-global JobListeners registered with the Scheduler.
	 * <p>A JobListener name always refers to the name returned
	 * by the JobListener implementation.
	 * @see SchedulerFactoryBean#setJobListeners
	 * @see org.quartz.JobListener#getName
	 */
	public void setJobListenerNames(String[] names) {
		for (int i = 0; i < names.length; i++) {
			addJobListener(names[i]);
		}
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}



	public void afterPropertiesSet() {
		if (getName() == null) {
			setName(this.beanName);
		}
		if (getGroup() == null) {
			setGroup(Scheduler.DEFAULT_GROUP);
		}
	}


}


这里把Spring的ApplicationContext去掉了,因为这个属性没有实现序列化接口。其他配置与原告一致:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " http://www.springframework.org/dtd/spring-beans.dtd ">
<beans default-autowire="byName">


   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

        <property name="url" >
        	<value><![CDATA[jdbc:mysql://localhost:3306/txl?connectTimeout=1000&useUnicode=true&characterEncoding=utf-8]]></value>
        </property>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>

	<bean id="jobDetail" class = "org.frame.auth.service.PersistentJobDetailBean">
			<property name="jobClass" value="org.frame.auth.service.PersistentJob"></property>
	</bean>

<!--	<bean id="trigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean" >-->
<!--			<property name="jobDetail" ref="jobDetail"></property>-->
<!--			<property name="startDelay" value="1000"></property>-->
<!--			<property name="repeatInterval" value="3000"></property>-->
<!--			<property name="jobDataAsMap">-->
<!--				<map>-->
<!--					<entry key="message" value="this is trigger"></entry>-->
<!--				</map>-->
<!--			</property>-->
<!--	</bean>-->

	<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
         <property name="jobDetail" ref="jobDetail"/>
         <property name="cronExpression">
             <value>0/10 * * * * ?</value>
         </property>
	</bean>

	<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
			<property name="dataSource" ref="dataSource"></property>
			<property name="applicationContextSchedulerContextKey"  value="applicationContextKey" />
			<property name="configLocation" value="classpath:quartz.properties"/>
	</bean>

</beans>


org.frame.auth.service.PersistentJob这个类很简单,如下:
package org.frame.auth.service;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class PersistentJob implements Job  {


	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		System.out.println("spring quartz!");
	}

}


有人可能会说,你这种任务调度持久化就没有意义了,是的,一般持久化到数据库的代码如下:
package org.frame.auth.service;

import java.util.Map;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;

public class PersistentJob implements StatefulJob  {


	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		// TODO Auto-generated method stub
		Map map = context.getJobDetail().getJobDataMap();
		System.out.println("["+context.getJobDetail().getName()+"]"+map.get("message"));
		map.put("message", "updated Message");
	}

}


这样的话,信息message就会持久化到数据库中了.可以建立系统的连锁调度,这根据你的业务需求了.

在Spring中配置的任务通过我这种修改是可以运行,不过每次运行都需要把原先的任务删除,否则会提示任务已经存在,Quartz的优势是就算服务器停止,下次重启能够恢复原先的任务并继续执行.
  • 大小: 35.3 KB
  • 大小: 23.5 KB
0
3
分享到:
评论

相关推荐

    Spring Quartz1.8.x

    4. **Job持久化**:在Spring Quartz中,你可以选择将Job的状态和Trigger的信息持久化到数据库,这样即使应用重启,任务和触发器也不会丢失。这通常通过配置`JobStore`实现,如使用`org.quartz.impl.jdbcjobstore....

    Java_Spring与Quartz的整合

    Java Spring 框架是企业级应用开发的热门选择,它提供了一种全面的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect Oriented Programming,AOP)的解决方案,使得开发者能够更加专注于业务逻辑的实现,...

    spring quartz类全包spring quartz类全包spring quartz类全包

    Spring Quartz 是一个强大的任务调度框架,它允许开发者在Spring应用中灵活地定义和执行定时任务。Quartz本身是一个独立...无论是在大型企业级应用还是小型项目中,Spring Quartz都是一个值得信赖的定时任务解决方案。

    spring整合quartz文档

    Spring 整合 Quartz 是一种常见的任务调度解决方案,用于在应用程序中安排和执行周期性的任务。Quartz 是一个功能丰富的开源任务调度库,适用于 Java 平台,尤其适用于 J2EE 和 J2SE 应用。它允许开发人员精确地定义...

    Spring Quartz应用相关jar

    Spring Quartz是将Quartz定时任务框架与Spring框架集成的一个解决方案,它允许开发者在Spring的管理环境中轻松地配置和运行Quartz作业。这个压缩包包含了实现这一功能所需的关键库文件。 1. **Spring.jar**: 这是...

    spring quartz 整合示例

    在IT行业中,Spring框架与Quartz的整合是一个常见的任务调度解决方案。这个压缩包文件提供了一个实际的示例,用于演示如何在Spring应用中集成Quartz进行任务调度。下面将详细解释其中涉及的知识点。 首先,Quartz是...

    Quartz+spring定时任务demo

    还可以在配置文件中指定 JobStore 类型,例如使用 JDBCJobStore 来持久化作业和触发器信息。 3. **配置 Spring**:在 Spring 的 XML 配置文件中声明一个 `SchedulerFactoryBean`,这是 Spring 用来管理和启动 ...

    spring-quartz定时设置详细说明

    Quartz 可以与任何持久化机制集成,包括 JDBC 数据库存储任务信息。 二、Spring 集成 Quartz 1. 添加依赖:在 Maven 或 Gradle 项目中,需要引入 Spring 对 Quartz 的支持。添加相应的依赖库,例如: Maven: ``...

    Spring quartz 定时任务调度

    通过以上介绍,我们可以看出Spring Quartz是一个功能强大且灵活的任务调度解决方案,适用于各种需要定时任务的应用场景。结合Spring的特性,可以让开发人员更高效地管理和执行定时任务,提高软件的自动化水平。

    Spring quartz1.6.jar(java定时任务)

    在Java定时任务领域,Spring Quartz 提供了高度灵活且可靠的解决方案。本篇将深入探讨Spring与Quartz的集成,以及如何利用它们实现Java定时任务调度。 首先,Quartz是一个完全实现了JDBC作业存储的开源作业调度框架...

    Spring quartz任务调度

    在实际应用中,我们可能还需要处理任务的持久化,以便服务器重启后能够恢复之前的状态。这通常是通过将Quartz的配置设置为使用数据库存储Job和Trigger来实现的。这里提供的"tables_oracle.sql"文件很可能就是用于在...

    Spring定时器quartz

    总之,Spring定时器Quartz提供了一种强大的解决方案,用于在Spring应用中管理定时任务。通过合理的配置和设计,开发者可以构建出稳定、可靠且可扩展的任务调度系统。如果你需要更深入地了解这个主题,可以参考给出的...

    Spring整合Quartz

    Spring整合Quartz是一个常见的任务调度解决方案,用于在Java应用程序中执行定时任务。Quartz是一个功能强大的、开放源代码的作业调度框架,而Spring框架则是一个全面的企业级应用开发框架。将两者结合,我们可以利用...

    Spring-quartz实现定时器(含代码)

    Spring是一个开源的Java平台,它提供了全面的企业级应用程序开发解决方案,包括依赖注入(DI)、面向切面编程(AOP)以及丰富的数据访问和事务管理功能。Spring的模块化设计使得开发者可以根据项目需求选择必要的...

    Spring-quartz计划任务

    Spring框架与Quartz的结合使用,是Java开发中常见的定时任务解决方案。Quartz是一个开源的作业调度框架,可以用来在指定的时间执行特定的任务。而Spring框架则提供了对Quartz的集成,使得我们可以方便地在Spring应用...

    转:spring多个定时任务quartz配置

    在Spring框架中,Quartz是一个强大的任务调度库,可以用于...总之,Spring与Quartz的整合提供了灵活且强大的定时任务解决方案,适用于各种复杂的调度需求。正确配置和使用,能够帮助我们构建高效、可靠的后台任务系统。

    quartz整合springbatch定时集群实现mysql参考模版

    总的来说,"quartz_springbatch"模版提供了一个完整的解决方案,用于构建基于Quartz和SpringBatch的定时任务集群,且与MySQL数据库集成,确保数据的可靠性和任务的高可用性。通过学习和理解这个模版,开发者可以快速...

    Quartz--JAVA定时任务\Java应用:Java调度任务和Spring Quartz (1)

    Quartz还支持集群和持久化,这意味着多个Quartz实例可以在分布式环境中协作调度任务,而且任务的状态和计划可以存储在数据库中,保证了高可用性和容错性。通过Spring与Quartz的整合,可以轻松地在Spring应用中管理...

    Spring+Quartz定时调度

    在Java世界中,实现定时任务调度是非常常见的需求,Spring框架结合Quartz库提供了一种高效且灵活的解决方案。本文将深入探讨Spring与Quartz的整合,以及如何利用它们来创建和管理定时任务。 ### 一、Spring与Quartz...

    spring_quartz_定时任务

    Quartz的强大之处在于其灵活性和可扩展性,支持多种调度策略,如简单触发器、cron触发器、间隔触发器等,并且可以进行持久化存储,保证服务器重启后任务不会丢失。 三、Spring整合Quartz 1. 添加依赖:在项目中...

Global site tag (gtag.js) - Google Analytics