我有集成弹簧和石英的问题。我需要动态地将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
答案 0 :(得分:0)
你不能那样做。 FactoryBean
有一份特定的合同,而您正试图在其中间行事。
factory bean是一个bean,其目的是以编程方式创建bean。你不能真正注入一个工厂bean,因为它存在的唯一目的是注册一个bean。此外,start
回调与应用程序上下文生命周期有关。当你从代码中调用它时,为时已晚,调度程序已经处于活动状态。
初始化bean时会注册触发器(在afterPropertiesSet
回调方法中)。如果您在此之后尝试向工厂添加其他触发器,则不会将其考虑在内,因为已经创建了调度程序。
话虽如此,我还没有真正看到XML和Java代码之间的关系。在常规情况下,您的plannedVacationServiceCronTrigger
应该被注册(并且没有理由将其作为prototype
bean。)