2012-03-23 58 views
1

我有一個彈出的Web應用程序,其中applicationContext.xml通過ContextLoaderListener加載到XmlWebApplicationContext中。應用程序上下文有一個Quartz調度程序(用SchedulerFactoryBean定義,如here),但沒有觸發器和作業詳細信息。如何讓Quartz作業在多ApplicationContext環境中運行?

在這個主應用程序上下文的裝載,我加載包含自己pluginApplicationContext.xml文件中的一些「插件」的JAR文件。 作爲主要的XmlWebApplicationContext的孩子,每個pluginApplicationContext.xml被加載在GenericXmlApplicationContext中。

這些插件可能含有石英作業被調度上面討論的調度器內(QuartzJobBean)。調度必須通過Quartz API以編程方式完成,但這對我來說很好。當作業被觸發時,它很好地被Quartz實例化,並且因爲它擴展了QuartzJobBean,所以我能夠獲得當前的ApplicationContextsetApplicationContext。 這裏的問題是,我得到XmlWebApplicationContext而不是已經安排作業的GenericXmlApplicationContext。因此,我不能調用getBean來檢索插件中定義的bean。

我很明白爲什麼會發生這一切。但是我找不到一個乾淨的,可重用的解決方案來處理它。我已經看到了OSGi,但是我們正在現有的應用程序上實現這個插件系統,而不是從頭開始創建一個新的插件系統,並且將整個應用程序遷移到OSGi將是很難完成的工作。你知道OSGi和其他插件框架如何處理這種情況嗎?

非常感謝您的幫助

+0

目前還不清楚。我知道你有一個pluginApplicationContext.xml插件,插件中定義的bean不能從主要上下文訪問。是對的嗎? – jddsantaella 2012-03-23 17:44:17

回答

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,但我有一些調度經驗。我註冊一個Runnable服務:用cron類似性質:

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

然後,您將需要做的是,根據它的cron規範調用服務)捆綁。

+0

感謝Peter這篇**非常有趣的文章!事實上,它現在不能解決我的問題,但它有助於理解嵌入到現有應用程序中的插件系統的問題。 – 2012-03-26 08:58:45

0

我同意是一個很好的方法,但也許你可以簡單地創建一個巨大的應用程序上下文(來統治它們)?相反,基於pluginApplicationContext.xml文件只需添加手動啓動新的子應用程序上下文:

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

而這會發現所有的插件和他們的豆合併成一個單一的應用程序上下文。從架構的角度來看,這是一種更糟糕的方法,但是如果您在啓動時發現所有插件,它就可以工作。

+0

感謝Tomasz爲您解答。如果'pluginApplicationContext.xml'文件位於應用程序啓動時加載的JAR中(在Spring之前......如何?)在其他'ClassLoader'中,該方法是否可以工作? JAR插件不在'WEB-INF/lib'文件夾中,我們希望將它們保留在Webapp歸檔之外,因爲這些插件是客戶特定的,Webapp不是。 – 2012-04-06 15:48:21

+0

@FlorentPaillard:如果您的客戶的JAR /類在啓動Spring的'ClassLoader'中可見,它就可以工作。這很容易嘗試。 – 2012-04-06 15:59:27

+0

我不認爲這是可能的。 Spring由'WebappClassLoader'中的servlet容器自動加載。由於我的客戶類/ JAR位於server/webapp標準目錄之外,因此它們必須在啓動時通過'WebappClassLoader'的子類'ClassLoader'進行「加載」,以便它們不可見。我錯過了什麼嗎? – 2012-04-06 16:28:33

相關問題