如何使用调度程序获取Spring Quartz触发器

时间:2013-01-07 19:51:25

标签: java spring quartz-scheduler

我之前从未使用过石英调度程序,而且我在创建Quartz作业时遇到问题。我通过cronExpression配置的触发器不会触发,我也看不到我错过的内容。

提前感谢您的任何帮助或建议!

我正在使用:

  • quartz 1.6.3

  • spring version 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;
    }
}

1 个答案:

答案 0 :(得分:1)

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

如果你看一下Spring的setTriggersSchedulerAccessor上的SchedulerFactoryBean的javadoc(那是JobDetail的超类),你可以看到:

  

如果Trigger确定相应的JobDetail本身,则该作业   将自动注册到Scheduler。否则,   需要通过“jobDetails”注册相应的JobDetail   这个FactoryBean的属性。

他们没有提到的是,如果您已经注册了Trigger,它将阻止addTriggerToScheduler安排其引用的作业。 SchedulerAccessorJobDetail 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条件将快速失败,并且永远不会调用{{1}}方法。