2013-05-10 79 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