我有一个Spring applicationContext.xml
在ContextLoaderListener
中加载XmlWebApplicationContext
的Spring Web应用程序。应用程序上下文有一个Quartz调度程序(使用SchedulerFactoryBean
定义,如here),但没有触发器或作业详细信息。
在加载这个主应用程序上下文的过程中,我加载了一些包含自己的pluginApplicationContext.xml
文件的“插件”JAR。
每个pluginApplicationContext.xml
都作为主GenericXmlApplicationContext
的子项加载到XmlWebApplicationContext
。
这些插件可能包含Quartz作业(QuartzJobBean
),这些作业在上面讨论的调度程序中进行了调度。调度必须通过Quartz API以编程方式完成,但这对我来说很好。当作业被触发时,它很好地由Quartz实现,因为它扩展了QuartzJobBean
,我能够获得当前ApplicationContext
到setApplicationContext
。
这里的问题是我得到了XmlWebApplicationContext
而不是已安排作业的GenericXmlApplicationContext
。因此,我无法调用getBean
来检索插件中定义的bean。
我很清楚为什么会发生这一切。但我找不到一个干净,可重复使用的解决方案来处理它。我已经看过OSGi,但是我们正在现有的应用程序上实现这个插件系统,而不是从头开始创建一个新的应用程序,将整个应用程序迁移到OSGi将是太多的工作要做。你知道OSGi和其他插件框架如何处理这种情况吗?
非常感谢你的帮助
答案 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)
我同意osgi是一个很好的方法,但也许你可以简单地创建一个巨大的应用程序上下文(统治它们)?而不是基于pluginApplicationContext.xml
文件手动启动新的子应用程序上下文,只需添加:
<import resource="classpath:/pluginApplicationContext.xml"/>
这将找到所有插件并将其bean合并到单个应用程序上下文中。从架构的角度来看,这是一种更糟糕的方法,但如果您在启动时发现所有插件,它将会起作用。