非web应用开发中,系统用Spring集成Quartz,也就是在Spring配置文件applicationContext.xml中配置Quartz,具体代码如下:
- <!-- Quartz调度模块 -->
- <bean id="callJobBean" class="iprai.quartz.CallJobBean" />
- <bean id="callJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject">
- <ref bean="callJobBean" />
- </property>
- <property name="targetMethod">
- <value>executeInternal</value>
- </property>
- </bean>
- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail">
- <ref bean="callJobDetail" />
- </property>
- <property name="cronExpression">
- <value>0 0/5 * * * ?</value>
- </property>
- </bean>
- <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref local="cronTrigger" />
- </list>
- </property>
- </bean>
<!-- Quartz调度模块 --> <bean id="callJobBean" class="iprai.quartz.CallJobBean" /> <bean id="callJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="callJobBean" /> </property> <property name="targetMethod"> <value>executeInternal</value> </property> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="callJobDetail" /> </property> <property name="cronExpression"> <value>0 0/5 * * * ?</value> </property> </bean> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="cronTrigger" /> </list> </property> </bean>
当我的系统启动时,会读取并实例化applicationContext.xml文件中的其他bean,出现的问题就是读取一次配置文件并实例化一个与Quartz不相关的bean时,代码如下:
- ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- RiddickMessage message = (RiddickMessage)ctx.getBean("message");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
RiddickMessage message = (RiddickMessage)ctx.getBean("message");
Quartz就会相应地被调用一次,之前读取了多少次applicationContext.xml文件,运行时就会在Quartz设定的时间点重复执行相同次数的代码,也就是执行上面配置文件中的callJobBean对应的类中的executeInternal方法相同的次数,而且是同一个时间点,相当于配置了有多个一模一样的Job了。具体还没弄清楚是Spring到底是怎么自动实例化Quartz的,因为我都没有在代码中显式地实例化schedulerFactory这个bean,也就是下面代码没有运行:
- Resource resource = new ClassPathResource("applicationContext-CallJob.xml");
- BeanFactory factory = new XmlBeanFactory(resource);
- scheduler = (Scheduler) factory.getBean("schedulerFactory");
Resource resource = new ClassPathResource("applicationContext-CallJob.xml");
BeanFactory factory = new XmlBeanFactory(resource);
scheduler = (Scheduler) factory.getBean("schedulerFactory");
最后没办法,只得将applicationContext.xml文件中配置的Quartz代码移到另一个配置文件applicationContext-callJob.xml中,这样就避免了读取applicationContext.xml文件时自动实例化Quartz了。