spring上quartz启动两次的有关问题

spring下quartz启动两次的问题

最近正在做的项目,测试的时候发现定时调度任务会执行两次,于是乎查资料呀,都说是Tomcat配置问题,哥改了还是不行,后来无奈使用了一个网上说的方法,将JOB中的方法使用同步,通过一个静态变量进行控制,配置如下:

 

   <bean id="sendOffMailTimerBean" class="com.c35.rouen.job.OffMailReportJob"> 
  <property name="isolationAreaService">
   <ref bean="isolationAreaService" />
  </property>    
    </bean>

 <bean id="offMailReportJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
       <property name="targetObject">
           <ref bean="sendOffMailTimerBean"/>
       </property>
       <!-- 调用类中的方法 -->
       <property name="targetMethod">
           <value>doSend</value>
       </property>
       <property name="concurrent">
           <value>false</value>
       </property>            
    </bean> 
    
    <bean id="deleteOffMailTimerBean" class="com.c35.rouen.job.OffMailDestroyJob"> 
  <property name="isolationAreaService">
   <ref bean="isolationAreaService" />
  </property>    
    </bean>    
    
 <bean id="offMailDestroyJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
       <property name="targetObject">
           <ref bean="deleteOffMailTimerBean"/>
       </property>
       <!-- 调用类中的方法 -->
       <property name="targetMethod">
           <value>doDelete</value>
       </property>
       <property name="concurrent">
           <value>false</value>
       </property>            
    </bean>     

    <!-- 每天整点发送隔离邮件报告 -->
 <bean id="offMailReportSendTrigger"
  class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail" ref="offMailReportJob"></property>
  <property name="cronExpression">
   <value>0 0 * * * ?</value>
  </property>
 </bean>
 
 <!-- 每天凌晨三点检查删除过期的隔离邮件 -->
 <bean id="offMailDestroyTrigger"
  class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail" ref="offMailDestroyJob"></property>
  <property name="cronExpression">
   <value>0 0 3 * * ?</value>
  </property>
 </bean> 

 <!-- 启动定时器 -->
 <bean id ="schedulerFactory" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
   <list>
    <ref bean="offMailReportSendTrigger" />
    <ref bean="offMailDestroyTrigger" />
   </list>
  </property>
 </bean>

 

 

JOB如下:

public class OffMailReportJob extends QuartzJobBean {

 private IIsolationAreaService isolationAreaService;
 
 public IIsolationAreaService getIsolationAreaService() {
  return isolationAreaService;
 }

 public void setIsolationAreaService(IIsolationAreaService isolationAreaService) {
  this.isolationAreaService = isolationAreaService;
 }

 private static JLogger log = LoggerFactory.getLogger(OffMailReportJob.class);
 
 static int sendIndexFlag =0;//由doSend修改,其他方法不要修改此参数

 public void doSend() {
  
  // 定时器同时调用两次的问题需要查找原因
  if (sendIndexFlag > 0)
   return;// 保证同一时刻只有一个定时器运行,通过这种方式保证每次定时时间到时,只执行一个线程
  sendIndexFlag = 1;// 锁定
  
  try {
   isolationAreaService.sendOffMailReport();
  } catch (Exception e) {
   log.error(e.getMessage(), e);
  }
  
  sendIndexFlag = 0;// 锁定解除
 }

 @Override
 protected void executeInternal(JobExecutionContext arg0)
   throws JobExecutionException {
 }

 

 

 

照此修改时可以解决问题滴

后台又查啊查的,发现问题的根本:

web容器启动的时候,读取applicationContext.xml文件时,会加载一次。
第二次:Spring本身会加载applicationContext.xml一次。
一般来说,我们的quartz配置就是写在applicationContext.xml文件里的。
解决办法很简单
先把quartz配置信息提取出来,单独存成一个文件,比如applicationContext-quartz.xml
然后修改web.xml,让web容器启动时,可以加载该文件
这样quartz只会在web容器启动时加载一次,Spring不会再加载了。