如何让Quartz作业在多ApplicationContext环境中运行?

时间:2012-03-23 13:40:50

标签: java spring osgi quartz-scheduler applicationcontext

我有一个Spring applicationContext.xmlContextLoaderListener中加载XmlWebApplicationContext的Spring Web应用程序。应用程序上下文有一个Quartz调度程序(使用SchedulerFactoryBean定义,如here),但没有触发器或作业详细信息。

在加载这个主应用程序上下文的过程中,我加载了一些包含自己的pluginApplicationContext.xml文件的“插件”JAR。 每个pluginApplicationContext.xml都作为主GenericXmlApplicationContext的子项加载到XmlWebApplicationContext

这些插件可能包含Quartz作业(QuartzJobBean),这些作业在上面讨论的调度程序中进行了调度。调度必须通过Quartz API以编程方式完成,但这对我来说很好。当作业被触发时,它很好地由Quartz实现,因为它扩展了QuartzJobBean,我能够获得当前ApplicationContextsetApplicationContext。 这里的问题是我得到了XmlWebApplicationContext而不是已安排作业的GenericXmlApplicationContext。因此,我无法调用getBean来检索插件中定义的bean。

我很清楚为什么会发生这一切。但我找不到一个干净,可重复使用的解决方案来处理它。我已经看过OSGi,但是我们正在现有的应用程序上实现这个插件系统,而不是从头开始创建一个新的应用程序,将整个应用程序迁移到OSGi将是太多的工作要做。你知道OSGi和其他插件框架如何处理这种情况吗?

非常感谢你的帮助

2 个答案:

答案 0 :(得分:2)

我不确定我是否得到了所有这些弹簧问题,但我已经用OSGi做了这些事情。

人们通常没有意识到,您可以在现有应用程序中嵌入OSGi,而无需对现有代码进行任何更改。理查德·霍尔在此描述http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html(API是100%标准化的)。

拥有框架,然后您可以在框架中运行插件。您必须确保框架导出所有应用程序包(请参阅org.osgi.framework.system.packages.extra启动属性)。然后,插件和应用程序可以通过服务进行通信。

我从未使用过Quartz,但我对调度有一些经验。我使用类似cron的属性注册Runnable服务:

   @Component(properties="cron=1 * * * *")
   public void SomeImpl implements Runnable {
     public void run() {
        ...
     }
   }

然后,您需要根据其cron规范创建一个调用该服务的包。)

答案 1 :(得分:0)

我同意是一个很好的方法,但也许你可以简单地创建一个巨大的应用程序上下文(统治它们)?而不是基于pluginApplicationContext.xml文件手动启动新的子应用程序上下文,只需添加:

<import resource="classpath:/pluginApplicationContext.xml"/>

这将找到所有插件并将其bean合并到单个应用程序上下文中。从架构的角度来看,这是一种更糟糕的方法,但如果您在启动时发现所有插件,它将会起作用。