java - 执行方法未在预定时间调用quartz+spring

标签 java spring quartz-scheduler crontrigger

我正在尝试使用 spring 和新功能来实现quartz持久作业。我已经在 SimpleQuartzJob 类中实现了 Job 接口(interface)。当我运行主程序时,作业保留在数据库中,但实现作业的 SimpleQuartzJob 的执行(JobExecutionContext context)方法没有在预定时间触发。我无法弄清楚为什么会发生这种情况。

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

public class SimpleQuartzJob implements Job {
    private String someParam;
    private int someParam2;

    public void setSomeParam(String someParam) {
        this.someParam = someParam;
    }

    public void setSomeParam2(int someParam2) {
        this.someParam2 = someParam2;
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        System.out.println("My job is running with " + someParam + ' '
                + someParam2);

    }

}

持久化CronTriggerFactoryBean

package com.practise.quartz.jdbc;

import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailAwareTrigger;


    public class PersistableCronTriggerFactoryBean extends CronTriggerFactoryBean {

        @Override
        public void afterPropertiesSet() {
            super.afterPropertiesSet();

            //Remove the JobDetail element
            getJobDataMap().remove(JobDetailAwareTrigger.JOB_DETAIL_KEY);
        }
    }

Autowiring SpringBeanJobFactory

    public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
        implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    public Object createJobInstance(final TriggerFiredBundle bundle)
            throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job); // the magic is done here
        return job;
    }

}

spring-quartz-jdbc.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" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="com.practise.quartz"></context:component-scan>


    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        id="dataSource">
        <property value="com.mysql.jdbc.Driver" name="driverClassName" />
        <property value="jdbc:mysql://localhost:3306/test" name="url" />
        <property value="root" name="username" />
        <property value="root" name="password" />
    </bean>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource" />

    </bean>

    <bean id="myJob"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.practise.quartz.jdbc.SimpleQuartzJob" />
        <property name="jobDataAsMap">
            <map>
                <entry key="someParam" value="some value" />
                <entry key="someParam2" value="1" />
            </map>
        </property>
        <property name="durability" value="true" />
    </bean>

    <bean id="quartzTriggers"
        class="com.practise.quartz.jdbc.PersistableCronTriggerFactoryBean">
        <!-- Reference to the job bean that will be triggered: -->
        <property name="jobDetail" ref="myJob" />
        <property name="cronExpression" value="0/5 * * * * ?" />
        <property name="misfireInstruction"
            value="#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_DO_NOTHING}" />
    </bean>

    <bean id="quartzJobFactory" class="com.practise.quartz.jdbc.AutowiringSpringBeanJobFactory">
        <property name="ignoredUnknownProperties" value="applicationContext" />
    </bean>

    <bean id="quartzScheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

        <property name="configLocation" value="classpath:quartz.properties" />
        <property name="dataSource" ref="dataSource" />
        <property name="transactionManager" ref="transactionManager" />

        <property name="schedulerName" value="quartzScheduler" />
        <property name="overwriteExistingJobs" value="true" />

        <property name="autoStartup" value="true" />
        <property name="applicationContextSchedulerContextKey" value="applicationContext" />

        <property name="jobFactory" ref="quartzJobFactory" />

        <!-- NOTE: Must add both the jobDetail and trigger to the scheduler! -->
        <property name="jobDetails">
            <list>
                <ref bean="myJob" />
            </list>
        </property>
        <property name="triggers">
            <list>
                <ref bean="quartzTriggers" />
            </list>
        </property>
    </bean>

</beans>

测试方法

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

public class Test {
public static void main(String[] args) {
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-quartz-jdbc.xml");

}
}

quartz .属性

org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true

# Change this to match your DB vendor
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Needed to manage cluster instances
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=SimpleQuazrtzJob  

org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

控制台记录器

19:10:43,349  INFO main support.ClassPathXmlApplicationContext:513 - Refreshing 
19:10:43,572 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/beans/spring-beans-3.0.xsd] in classpath: org/springframework/beans/factory/xml/spring-beans-3.0.xsd
19:10:43,686 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/context/spring-context.xsd] in classpath: org/springframework/context/config/spring-context-4.0.xsd
19:10:43,704 DEBUG main xml.PluggableSchemaResolver:119 - Found XML schema [http://www.springframework.org/schema/tool/spring-tool-4.0.xsd] in classpath: org/springframework/beans/factory/xml/spring-tool-4.0.xsd
19:10:43,737 DEBUG main xml.DefaultBeanDefinitionDocumentReader:108 - Loading bean definitions
19:10:43,761 DEBUG main xml.DefaultNamespaceHandlerResolver:157 - Loaded NamespaceHandler mappings: {http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
19:10:43,947 DEBUG main xml.BeanDefinitionParserDelegate:465 - No XML 'id' specified - using 'exampleJob' as bean name and [] as aliases
19:10:43,954 DEBUG main xml.XmlBeanDefinitionReader:223 - Loaded 11 bean definitions from location pattern [spring-quartz-jdbc.xml]
19:10:44,011 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,011 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,043 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' to allow for resolving potential circular references
19:10:44,048 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,125 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,126 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,129 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' to allow for resolving potential circular references
19:10:44,130 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,130 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,131 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,132 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' to allow for resolving potential circular references
19:10:44,133 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,133 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,134 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,143 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' to allow for resolving potential circular references
19:10:44,144 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,144 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,145 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,145 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor' to allow for resolving potential circular references
19:10:44,146 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:44,146 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,147 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,147 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor' to allow for resolving potential circular references
19:10:44,148 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:44,163 DEBUG main support.DefaultListableBeanFactory:672 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@468a9e1a: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,simpleScheduler,dataSource,transactionManager,exampleJob,cronTrigger,quartzJobFactory,quartzScheduler,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; root of factory hierarchy
19:10:44,164 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
19:10:44,164 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
19:10:44,165 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
19:10:44,165 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
19:10:44,166 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'simpleScheduler'
19:10:44,166 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'simpleScheduler'
19:10:44,179 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'simpleScheduler' to allow for resolving potential circular references
19:10:44,203 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'simpleScheduler'
19:10:44,204 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'dataSource'
19:10:44,204 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'dataSource'
19:10:44,208 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'dataSource' to allow for resolving potential circular references
19:10:44,262  INFO main datasource.DriverManagerDataSource:133 - Loaded JDBC driver: com.mysql.jdbc.Driver
19:10:44,263 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'dataSource'
19:10:44,264 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'transactionManager'
19:10:44,264 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'transactionManager'
19:10:44,284 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'transactionManager' to allow for resolving potential circular references
19:10:44,294 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'dataSource'
19:10:44,299 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'transactionManager'
19:10:44,300 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'transactionManager'
19:10:44,301 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'exampleJob'
19:10:44,301 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'exampleJob'
19:10:44,313 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'exampleJob' to allow for resolving potential circular references
19:10:44,361 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'exampleJob'
19:10:44,387 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'exampleJob'
19:10:44,388 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'cronTrigger'
19:10:44,389 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'cronTrigger'
19:10:44,395 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'cronTrigger' to allow for resolving potential circular references
19:10:44,408 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'exampleJob'
19:10:44,410 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'cronTrigger'
19:10:44,460 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'cronTrigger'
19:10:44,461 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'quartzJobFactory'
19:10:44,461 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'quartzJobFactory'
19:10:44,466 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'quartzJobFactory' to allow for resolving potential circular references
19:10:44,473 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'quartzJobFactory'
19:10:44,474 DEBUG main support.DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'quartzScheduler'
19:10:44,474 DEBUG main support.DefaultListableBeanFactory:449 - Creating instance of bean 'quartzScheduler'
19:10:44,490 DEBUG main support.DefaultListableBeanFactory:523 - Eagerly caching bean 'quartzScheduler' to allow for resolving potential circular references
19:10:44,507 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'dataSource'
19:10:44,508 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'transactionManager'
19:10:44,510 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'quartzJobFactory'
19:10:44,511 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'cronTrigger'
19:10:44,512 DEBUG main support.DefaultListableBeanFactory:1595 - Invoking afterPropertiesSet() on bean with name 'quartzScheduler'
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
19:10:44,532  INFO main quartz.SchedulerFactoryBean:553 - Loading Quartz config from [class path resource [quartz.properties]]
19:10:45,020 DEBUG main support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'quartzScheduler'
19:10:45,021 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
19:10:45,021 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
19:10:45,023 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'quartzScheduler'
19:10:45,024 DEBUG main support.DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'lifecycleProcessor'
19:10:45,026  INFO main support.DefaultLifecycleProcessor:341 - Starting beans in phase 2147483647
19:10:45,026  INFO main quartz.SchedulerFactoryBean:649 - Starting Quartz Scheduler now

数据库数据

qrtz_scheduler_state表-> qrtz_scheduler_state

qrtz_triggers表

enter image description here

qrtz_cron_triggers 表

enter image description here

qrtz_job_details表

enter image description here

最佳答案

org.quartz.jobStore.useProperties=false

独立 Quartz 对此没有任何问题:只需在“quartz.properties”文件中使用“org.quartz.jobStore.useProperties=true”即可。它告诉 Quartz 按原样存储作业参数,而不是通过 Java 序列化机制。

问题出在 Spring + Quartz 组合上。简单地更改上述属性将导致 Quartz 失败并出现错误。 Spring 的 *TriggerFactoryBeans 将它们的作业默默地存储在它们的触发器中。由于作业定义是复杂的对象,因此必须使用 Java 序列化机制来存储它们,这与“useProperties=true”设置相矛盾。

http://codrspace.com/Khovansa/spring-quartz-with-a-database/

关于java - 执行方法未在预定时间调用quartz+spring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35124152/

相关文章:

java - 当私有(private)函数需要调用公共(public)函数时如何改进?

java - 参数列表中引用变量占位符的术语

java - Spring Boot 应用程序预填充数据出现错误

mysql - Liquibase Spring error : Could not instantiate bean class [liquibase. integration.spring.SpringLiquibase]

java - 如何使用 Quartz 在 java 中安排任务?

c# - Quartz Job Scheduler 不触发作业 (C#)

java - hdfs dfs -ls 的默认值

java - 防止java.lang.StackOverflow错误简单sql池

java - HibernateDaoSupport 和原生 SQL

java - 将 Quartz 代码迁移到 2.2.x