java - 如何使用调度程序触发 Spring Quartz 触发器

标签 java spring quartz-scheduler

我以前从未使用过 quartz 调度程序,而且我在创建 Quartz 作业时遇到了问题。我通过 cronExpression 配置的触发器没有触发,我没有看到我遗漏了什么。

在此先感谢您的帮助或建议!

我正在使用:

  • quartz 版本 1.6.3

  • spring 版本 3.1.1

调度器:

<beans default-autowire="byName"
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"
    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.1.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <!-- Quartz Scheduler -->
    <bean id="scheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="dataSource" ref="itc5DataSource" />
        <property name="applicationContextSchedulerContextKey" value="applicationContext" />
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.scheduler.instanceName">${cepis.portal.scheduler.name}</prop>
                <prop key="org.quartz.scheduler.instanceId">${cepis.portal.scheduler.instanceId}</prop>
                <prop key="org.quartz.threadPool.class">${cepis.portal.scheduler.threadPool.class}</prop>
                <prop key="org.quartz.threadPool.threadCount">${cepis.portal.scheduler.threadPool.threadCount}
                </prop>
                <prop key="org.quartz.jobStore.class">${cepis.portal.scheduler.jobStore.class}</prop>
                <prop key="org.quartz.jobStore.isClustered">${cepis.portal.scheduler.jobStore.isClustered}</prop>
                <prop key="org.quartz.jobStore.useProperties">${cepis.portal.scheduler.jobStore.useProperties}
                </prop>
                <prop key="org.quartz.jobStore.tablePrefix">${cepis.portal.scheduler.jobStore.tablePrefix}</prop>
                <prop key="org.quartz.jobStore.driverDelegateClass">${cepis.portal.scheduler.jobStore.driverDelegateClass}
                </prop>
                <prop key="org.quartz.jobStore.selectWithLockSQL">${cepis.portal.scheduler.jobStore.selectWithLockSQL}
                </prop>
            </props>
        </property>

        <property name="jobDetails">
            <list>
                <ref bean="updateNoShowAppointmentJob" />           
            </list>
        </property>

        <property name="triggers">
            <list>
                <ref bean="updateNoShowTrigger" />          
            </list>
        </property>

    </bean>

    <!-- *************************************************************************************************  -->

    <bean id="updateNoShowAppointmentJob" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="name" value="CEPIS-UpdateNoShows" />
        <property name="group" value="Appointments" />              
        <property name="jobClass" value="edu.uky.cepis.util.cron.job.UpdateNoShowAppointmentJob" />
    </bean>


    <!-- *************************************************************************************************  --> 

    <bean id="updateNoShowTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="name" value="UpdateNoShow" />
        <property name="group" value="Appointments" />
        <property name="jobDetail" ref="updateNoShowAppointmentJob" />
        <!--  Do this every 60 seconds.-->
        <property name="cronExpression" value="0 * * * * ?" />
    </bean>



</beans>

工作:

/**
 * 
 */
package edu.uky.cepis.util.cron.job;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import edu.uky.cepis.service.AdvisingSessionService;
import edu.uky.cepis.domain.AdvisingSession;

/**
 * @author cawalk4
 * 
 * Purpose: Update all appointments with a date before the current date time
 * Setting the appointmentStatus to "No Show"
 * 
 */
public class UpdateNoShowAppointmentJob extends QuartzJobBean {

    private static Logger log = Logger.getLogger(
        UpdateNoShowAppointmentJob.class);

    private AdvisingSessionService advisingSessionService;

    private static String NO_SHOW = "No Show";

    @Override
    protected void executeInternal(JobExecutionContext context)
            throws JobExecutionException {

        log.debug("Running UpdateNoShowAppointmentJob at " + new Date());

        ApplicationContext appContext = null;

        try {
            appContext = (ApplicationContext) context.getScheduler()
                .getContext().get("applicationContext");
        } catch (SchedulerException se) {
            System.err.println(se);
        }

        try {
            advisingSessionService = (AdvisingSessionService) appContext
                .getBean("advisingSessionService", AdvisingSessionService.class);
        } catch (Exception e) {
            System.err.println(e);
        }
        if (advisingSessionService != null) {
            List<AdvisingSession> advisingSessionList =
                new ArrayList<AdvisingSession>(0);

            advisingSessionList = advisingSessionService.getNewNoShowAdvisingSessions();

            if (advisingSessionList == null) {
                log.debug("advisingSessionSlotlist is null.");
                return;
            } else if (advisingSessionList.isEmpty()) {
                log.debug("There are no new No Show advising appointments.");
                return;
            }

            log.debug("Total no show e-mails are: " + advisingSessionList.size());

            // Update the appointments 

            for(AdvisingSession advisingSession : advisingSessionList){

                advisingSessionService.updateAdvisingSession(                   
                        advisingSession,
                        advisingSession.getSessionType(), 
                        NO_SHOW,
                        advisingSession.getPreSessionText(), 
                        advisingSession.getSessionText(), 
                        advisingSession.getStudentNotes(), 
                        advisingSession.getAdvisorNotes(), 
                        advisingSession.getAdvisingSessionSlot(), 
                        advisingSession.getNoShowEmailSentBoolean());
            }
        } else {
            log.debug("advisingSessionService is null.");
        }
    }

    public void setadvisingSessionService(AdvisingSessionService advisingSessionService) {
        this.advisingSessionService = advisingSessionService;
    }

    public AdvisingSessionService getadvisingSessionService() {
        return advisingSessionService;
    }
}

最佳答案

如果您删除设置 scheduler bean 的 jobDetails 属性的 XML 部分,它应该会按预期工作。

如果您查看 Spring 的 SchedulerAccessor 类(SchedulerFactoryBean 的父类(super class))上的 setTriggers 的 javadoc,您可以看到:

If the Trigger determines the corresponding JobDetail itself, the job will be automatically registered with the Scheduler. Else, the respective JobDetail needs to be registered via the "jobDetails" property of this FactoryBean.

他们没有提到的是,如果您已经注册了 JobDetail,它将阻止 Trigger 安排其引用的作业。 SchedulerAccessor 中的 addTriggerToScheduler 方法的源代码有这段代码:

JobDetail jobDetail = findJobDetail(trigger);
if (jobDetail != null) {
    // Automatically register the JobDetail too.
    if (!this.jobDetails.contains(jobDetail) && addJobToScheduler(jobDetail)) {
        this.jobDetails.add(jobDetail);
    }
}

然后您可以看到,如果 jobDetails 已经包含您的作业,则 if 条件将很快失败,并且 addJobToScheduler 方法将永远不会被调用。

关于java - 如何使用调度程序触发 Spring Quartz 触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203004/

相关文章:

java - 带有 hibernate 4.1 注释配置的 Spring 3.1.1

java - 将 WebServiceTemplate 与 keystore 一起使用

java - 如何使 Eclipse 中的 Quartz Scheduler 工作?

grails - Grails Quartz插件不记得作业执行之间的状态数据吗?

Java内存不足异常

java - 如何在运行时调试 jar?

java - 在 Linux (Ubuntu) 中在 java 7 和 java 8 之间切换的推荐方法是什么?

java - 在 Android 上的评论屏幕上实现网络调用的最佳实践是怎样的?

java - 如何将 Map<String, String> 转换为 Map<Long, String> ? (选项 : using guava)

java - 使用 Spring Mail 将电子邮件保存到已发送文件夹中