spring 集成quartz 部署在tomcat里 任务每次会执行两遍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring 集成quartz 部署在tomcat里 任务每次会执行两遍相关的知识,希望对你有一定的参考价值。

spring集成quartz 在tomcat里部署项目 为什么启动的时候 任务每次会执行两遍
quartz的配置文件在web.xml 给spring去加载了

参考技术A

    你是不是同样的定时器配置了两次?

    你定时器扫描的时间间隔是不是太短?tomcat启动的时间大于或等于运行两次的周期时间。

    希望对你有帮助!

追问

定时器只配置了一次 而且时间只定了一天的某个时间点 到了时间点后去执行任务

我没有把配置文件配到applicationContext.xml 中 我就是单独写的一个配置文件 然后统一去加载

追答

还有你的项目是不是在多台机有启动,比如测试环境有一个(已启动),你自己的开发环境也启动了,配置的时间点是一样的,也会出现同一时间点多次执行。如果还不是,你的配置应该是有问题的,我一直用spring定时器,都没碰到过这样的问题。

参考技术B quartz定时调度框架的定时器没有设置好,请参考配置文件重新设置定时器,事实上在Spring进行初始化的时候会初始化quartz调度框架,但是这个时候任务是不会自动执行的 参考技术C

    你是不是同样的定时器配置了两次?

    你定时器扫描的时间间隔是不是太短?tomcat启动的时间大于或等于运行两次的周期时间。

    希望对你有帮助!

参考技术D 在网上找到了你所遇问题的解决方案,链接如下:
http://leitelyaya.iteye.com/blog/854096
如果能解决你的问题,记得采纳喔,虽然解决方案不是我做的,但找起来也挺麻烦的,嘿嘿~~追问

提问之前 已经在网上搜索过了 都没有解决问题 你提供的链接里的问题跟我的不太一样 我现在还只是用工具在tomcat里部署运行 没有打包部署

追答

那就不知道了,在很久以前用过这个,现在早忘了;

Quartz与Spring集成——创建调度器

前言

在《Quartz与Spring集成—— SchedulerFactoryBean的初始化分析》一文中介绍过Spring集成Quartz时的初始化过程,其中简单的提到了创建调度器的方法createScheduler。本文将着重介绍Quartz初始化时是如何创建调度器的。

创建调度器

这里从createScheduler的实现(见代码清单1)来分析,其处理步骤如下:

  1. 设置线程上下文的类加载器;
  2. 通过单例方法获取SchedulerRepository的实例(见代码清单2);
  3. 从调度仓库实例SchedulerRepository中查找已经存在的调度器,这里想说的是虽然此实现考虑到了多线程安全问题,不过这种方式效率较低。不如提前初始化,由final修饰,不使用同步语句,避免线程间的阻塞和等待;
  4. 获取调取器(见代码清单3),其实际上首先从调度器缓存中查找调度器,否则调用instantiate方法创建调度器;
  5. 检查重新获取的调度器和已经存在的调度器是否相同,如果相同则说明此调度器已经被激活了,将会报出异常。如果调度器是首次被激活,那么将返回此调度器。这里的实现稍微有些拖沓,其实只有当existingScheduler为null时,才会调用instantiate方法创建newScheduler,也只有在这个时候newScheduler才不等于existingScheduler,并且不会抛出异常。因此我们甚至可以省去Scheduler existingScheduler = (schedulerName != null ? repository.lookup(schedulerName) : null);这行代码,而直接将代码清单3中的实现进行修改——当sched为null时才调用instantiate方法创建调度器。

代码清单1

	protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName)
			throws SchedulerException {

		// Override thread context ClassLoader to work around naive Quartz ClassLoadHelper loading.
		Thread currentThread = Thread.currentThread();
		ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
		boolean overrideClassLoader = (this.resourceLoader != null &&
				!this.resourceLoader.getClassLoader().equals(threadContextClassLoader));
		if (overrideClassLoader) {
			currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
		}
		try {
			SchedulerRepository repository = SchedulerRepository.getInstance();
			synchronized (repository) {
				Scheduler existingScheduler = (schedulerName != null ? repository.lookup(schedulerName) : null);
				Scheduler newScheduler = schedulerFactory.getScheduler();
				if (newScheduler == existingScheduler) {
					throw new IllegalStateException("Active Scheduler of name '" + schedulerName + "' already registered " +
							"in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!");
				}
				if (!this.exposeSchedulerInRepository) {
					// Need to remove it in this case, since Quartz shares the Scheduler instance by default!
					SchedulerRepository.getInstance().remove(newScheduler.getSchedulerName());
				}
				return newScheduler;
			}
		}
		finally {
			if (overrideClassLoader) {
				// Reset original thread context ClassLoader.
				currentThread.setContextClassLoader(threadContextClassLoader);
			}
		}
	}

代码清单2

    public static synchronized SchedulerRepository getInstance() {
        if (inst == null) {
            inst = new SchedulerRepository();
        }

        return inst;
    }