2012-09-02 34 views
4

我剛閱讀Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean各種管理豆類和他們的關係非常好的解釋,正如我在我的應用程序面臨一個惱人的問題,我想知道,如果有可能控制或影響豆的開始方式和時間。的Java EE 6:管理豆的控制啓動與依賴關係:CDI,EJB

在我的Java EE應用程序,我使用EJB,CDI和JSF2作爲視圖技術。通過SPI,來自第三方的服務被引導,並且它配置作業執行器,該作業執行器啓動作業並處理其他與計時器相關的事情。當工作執行者完成自舉時,立即執行一項工作。這項工作使用CDI注入來訪問一些bean,其中一個bean使用EJB。

的問題是,現在大部分時間在Java EE 6服務器(JBoss的7.1.1)開始EJB仍然不可用,則該程序試圖訪問它。引發異常並且作業失敗,並且構建服務以停用失敗的作業。那麼,取消一個faild工作似乎不是太糟糕。該工作再次啓動和運行的唯一解決方案是取消部署並重新部署。不幸的是,這是一項手動任務,不能通過編程來完成。

而且,爲了使事情不好:在極少數情況下,這不會發生。

所以,我現在的問題是:我可以以某種方式控制EJB和CDI bean的初始化和部署,以便我可以確保在CDI bean初始化之前初始化所有EJB bean?

我在EARs application.xml中將initialize-in-order設置爲true,並設置了EJB的順序,以便它們以我需要的方式初始化(​​EJB核心,然後是EJB業務,然後是WAR),但基於CDI的服務作爲JAR放置在lib文件夾中。從Java EE 6 Tutorial

+0

你嘗試使用'CDI的Events'功能後,使CDI服務啓動? – Tair

+0

例如在EJB'@ PostConstruct'中觸發一個由您的服務觀察到的事件。 – Tair

+0

@tair no。我沒有意識到我可以爲自己開發CDI事件:)你是說我可以從服務所依賴的所有EJB中激發事件,然後採取行動?例如阻止或釋放工作? – Joysn

回答

6

摘錄了一些修改:

@Singleton 
@Startup 
public class BeanA { ... } 

@Qualifier 
@Target({FIELD, PARAMETER}) 
@Retention(RUNTIME) 
public @interface EjbStarted {} 

@Singleton 
@Startup 
@DependsOn("BeanA", "BeanB", "BeanC") 
public class LastBean { 
    @Inject @EjbStarted Event<String> event; 

    @PostConstruct 
    public void startService() { 
     // At this moment PrimaryBean is ready for use 
     event.fire("LastBean"); 
    } 
} 

public class CDIService { 
    public void start(@Observes @EjbStarted String name) { 
     if("LastBean".equals(name)) { 
      startService(); 
     } 
    } 
} 

更新:雖然在思考的問題,我不知怎麼忘了要在CDI豆初始化順序,所以答案是有點斷章取義,我們對此深感抱歉這:)

更新2:新增如何EJB的

+0

沒問題,我學會了你對DependsOn東西答案:)好了,最初的問題是,由作業調度器開始工作時開始運行在一個BPMN2流程引擎的過程實例和任務有使用EJB的。而我的問題是當EJB尚未到位時執行流程實例。也許如果我創建一個EJB取決於所需的EJB,然後檢查該EJB是否可用?我可以通過JNDI做這個檢查嗎?那麼我可以將任務添加到執行此檢查並正常退出的流程定義中。 – Joysn

+0

我已經更新了一個CDI事件的例子,只是爲了演示事件功能。更簡單的方法是隻'@注入LastBean'和'@PostConstruct startService()''中CDIService' - 這是定義啓動依存關係的另一種方式 – Tair