Spring 3 \ Quartz 2.集成问题

时间:2014-04-02 11:31:37

标签: java spring quartz-scheduler

我有集成弹簧和石英的问题。我需要动态地将CronTriggerFactoryBean添加到SchedulerFactoryBean

XML Spring映射:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" scope="prototype">
    <property name="jobDetails">
        <list>
            <ref bean="plannedVacationServiceJob" />
        </list>
    </property>
    <property name="triggers">
        <list>
            <ref bean="plannedVacationServiceCronTrigger" />
        </list>
    </property>
</bean>

<bean id="plannedVacationServiceJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="com.my.service.package.PlannerJob" />
    <property name="durability" value="true" />
</bean>

<bean id="plannedVacationServiceCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" scope="prototype">
    <property name="jobDetail" ref="plannedVacationServiceJob" />
    <property name="cronExpression" value="*/15 * * * * ?" />
</bean>

Java代码:

@Service
public class Planner implements Planning { 
@Autowired
@Qualifier("plannedVacationServiceCronTrigger")
private CronTriggerFactoryBean plannedVacationServiceCronTrigger;

@Autowired
private SchedulerFactoryBean schedulerFactoryBean;

 @PostConstruct
 public void init() {
       schedulerFactoryBean.start();
 } 
//some code 
private void addTask(PlannerEntity entity) {
    try {
        String name = getIdentityName(entity);
        JobKey jobKey = new JobKey(name);
        String cronExpression = getCronExpression(entity);
        plannedVacationServiceCronTrigger.setCronExpression(cronExpression);
        JobDetail jobDetail =      JobBuilder.newJob(PlannerJob.class).withIdentity(jobKey).build();
        plannedVacationServiceCronTrigger.setJobDetail(jobDetail);
        plannedVacationServiceCronTrigger.setName(name);
        plannedVacationServiceCronTrigger.afterPropertiesSet();
        schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, plannedVacationServiceCronTrigger.getObject());
        triggers.put(entity.getId(), trigger);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

在这种情况下,我们只有一个触发器,它在xml映射中添加了

我尝试从xml中删除对触发器的引用,并从代码创建CronTriggerFactoryBean:

private void addTask(PlannerEntity entity) {
    try {
        String name = getIdentityName(entity);
        JobKey jobKey = new JobKey(name);
        String cronExpression = getCronExpression(entity);
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setCronExpression(cronExpression);
        JobDetail jobDetail = JobBuilder.newJob(PlannerJob.class).withIdentity(jobKey).build();
        trigger.setJobDetail(jobDetail);
        trigger.setName(name);
        trigger.afterPropertiesSet();
        schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, trigger.getObject());
        triggers.put(entity.getId(), trigger);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

但在这种情况下,我们没有任何触发器:

2014-04-02 14:28:55,144 DEBUG [org.quartz.core.QuartzSchedulerThread(org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread)] - batch acquisition of 0 triggers
2014-04-02 14:29:18,981 DEBUG [org.quartz.core.QuartzSchedulerThread(org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread)] - batch acquisition of 0 triggers
2014-04-02 14:29:46,361 DEBUG [org.quartz.core.QuartzSchedulerThread(org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread)] - batch acquisition of 0 triggers
2014-04-02 14:30:09,439 DEBUG [org.quartz.core.QuartzSchedulerThread(org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread)] - batch acquisition of 0 triggers

1 个答案:

答案 0 :(得分:0)

你不能那样做。 FactoryBean有一份特定的合同,而您正试图在其中间行事。

factory bean是一个bean,其目的是以编程方式创建bean。你不能真正注入一个工厂bean,因为它存在的唯一目的是注册一个bean。此外,start回调与应用程序上下文生命周期有关。当你从代码中调用它时,为时已晚,调度程序已经处于活动状态。

初始化bean时会注册触发器(在afterPropertiesSet回调方法中)。如果您在此之后尝试向工厂添加其他触发器,则不会将其考虑在内,因为已经创建了调度程序。

话虽如此,我还没有真正看到XML和Java代码之间的关系。在常规情况下,您的plannedVacationServiceCronTrigger应该被注册(并且没有理由将其作为prototype bean。)