2013-05-10 19 views
1

我有一個我希望運行的非客戶端應用程序。它將沒有客戶端,但它會進行HTTP調用並充當其他服務的客戶端。它可能會運行幾個小時或幾天(但它不需要定期運行 - 只是一次性)。如何在Java EE中使用CDI編寫main()?

由於標準上下文依賴注入(CD)和標準JAX-RS客戶端(自Java EE 7以來的新增功能)的好處,我想在Java EE 7容器中運行它。擁有諸如JMS,JPA之類的服務也不錯。

問題是如何以標準方式編寫/註釋主要方法? @Inject上的方法是不好的,因爲這樣的方法必須很快返回。 @Schedule是不理想的,因爲它定期運行,除非我以編程方式確定當前系統時間。

我能想到的最好方法是在@Inject方法中設置一個Timer方法,並用@Timeout註釋我的主方法。

不知何故,這似乎有點脆弱或不雅。 有沒有更好的標準方式來啓動服務?一些註釋會導致它開始並開始行動?

此外,如何在取消部署時中斷和關閉服務的最佳標準方式是

+0

你的問題有點曲折。如果您正在應用程序容器中運行應用程序,那麼爲什麼要定義一個主要方法?使用['@ Schedule'](http://docs.oracle.com/javaee/6/api/javax/ejb/Schedule.html)方法創建一個啓動的單例EJB。 – Perception 2013-05-10 21:55:59

+0

@Perception蜿蜒是我缺乏清晰度的反映,因此是一個問題。 '@ Schedule'需要一段時間。我應該什麼時候註釋該方法?我不希望它定期運行。該方法需要運行一次。如果'@ Schedule'接受部署後的時間間隔,那將是完美的,但事實並非如此。我可以使用'@Schedule ... myfunc(定時器定時器)'並取消傳入的定時器並使用'TimerService'設置間隔定時器來運行'@Timeout ... mymain()'聲音。 – necromancer 2013-05-10 22:00:51

+0

不知道你是否編輯了你的問題,或者我錯過了底部。會發誓它讀不同。無論如何,一個想法 - 使用一個啓動,單身bean,並在其@PostConstruct方法中創建一個計時器。或者,嵌入像Quartz這樣的第三方庫,並安排一個非重複的作業,以便在部署應用程序時啓動作業。該工作的計劃要求是什麼(應用程序部署,特定日期,按需運行?)。 – Perception 2013-05-10 22:20:03

回答

2

如果你可以使用EJB與(或代替)CDI,然後嘗試@Singleton + @Startup註解爲bean,並@PostConstruct爲您main()方法。

@Singleton 
@Startup 
public class YourBean { 

@Stateless 
public static class BeanWithMainMethod{ 

    @Asynchronous 
    public void theMainMethod(){ 
     System.out.println("Async invocation"); 
    } 
} 

    @EJB 
    private BeanWithMainMethod beanWithMainMethod; 

    @PostConstruct 
    private void launchMainMethod(){ 
     beanWithMainMethod.theMainMethod(); 
    } 
} 
+0

我認爲容器會殺死它,如果@ PostConstruct沒有及時返回。你用長時間運行的方法試過這個嗎? – necromancer 2013-05-11 20:28:09

+0

如果MainMethod長時間未返回,則部署將失敗,因此,更好的做法是使用@Asyncronous或CDI事件。 – gluckonavt 2013-05-12 02:42:02

+0

感謝您的澄清,upvoted爲更正(如果您可以編輯您的答案太好了!) – necromancer 2013-05-12 03:04:34

3

當PostConstruct是長時間運行,分離與事件:

@Singleton 
@Startup 
public class YourBean{ 
@Inject 
private Event<XXX> started; 
@PostConstruct 
private void theMainMethod(){ 
    started.fire(new XXX()); 
} 
public void handleStarted(@Observes XXX started) { 
    // the real main method. 
} 

}

+0

謝謝@JanGalinski通過其他選項的使用方式一個'@Asynchronous public void handleStarted()'但我不能從'@ PostConstruct'方法中異步調用它。你認爲哪個更好 - 「@ Asynchronous」或「@ Observes」?任何想法,我需要做什麼來在同一個bean中的'@ PostConstruct'中對同一個bean中的方法進行異步調用?同時感謝您的好建議。 – necromancer 2013-05-11 21:42:07

+0

那麼,沒有標準的方法來請求取消一個'@ Observes'方法。通過'@ Asynchronous',可以通過返回的'Future'來請求取消該方法。雖然這可以用非標準方式進行模擬,但在將來的Java EE版本中,程序員很可能會請求標準的取消請求實際上在線程處於阻塞調用時中斷線程,這將極大地提高其響應性並清理結構。這個預期的功能不能由程序員自己實現。因此'@ Asynchronous'贏得IMO。 – necromancer 2013-05-11 23:09:29