1

我有一个 Spring Web 应用程序,它applicationContext.xml通过ContextLoaderListener. XmlWebApplicationContext应用程序上下文有一个 Quartz 调度程序(使用SchedulerFactoryBeanlike here定义),但没有触发器或作业详细信息。

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

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

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

非常感谢你的帮助

4

2 回答 2

2

我不确定我是否遇到了所有这些春季问题,但我已经用 OSGi 完成了这些事情。

人们通常没有意识到的是,您可以将 OSGi 嵌入到现有应用程序中,而无需对现有代码进行任何更改。Richard Hall 在这里描述了它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 实现 Runnable {
     公共无效运行(){
        ...
     }
   }

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

于 2012-03-25T14:51:00.330 回答
0

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

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

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

于 2012-03-28T11:23:22.800 回答