Jakarta ee 如何在JavaEE中使用CDI编写main()?

Jakarta ee 如何在JavaEE中使用CDI编写main()?,jakarta-ee,cdi,seam3,weld,java-ee-7,Jakarta Ee,Cdi,Seam3,Weld,Java Ee 7,我有一个无客户端的应用程序,我希望运行。它将没有客户端,但它将进行HTTP调用并充当其他服务的客户端。它可能会运行几个小时或几天(但不需要定期运行——只需一次) 我想在JavaEE7容器中运行它,因为标准上下文依赖注入(CD)和标准JAX-RS客户机(自JavaEE7以来新增)的好处。拥有JMS、JPA等服务也很好 问题是如何以标准方式编写/注释main方法@Inject不好,因为此类方法必须快速返回@Schedule并不理想,因为除非我以编程方式确定当前系统时间,否则它会定期运行 我能想到的最

我有一个无客户端的应用程序,我希望运行。它将没有客户端,但它将进行HTTP调用并充当其他服务的客户端。它可能会运行几个小时或几天(但不需要定期运行——只需一次)

我想在JavaEE7容器中运行它,因为标准上下文依赖注入(CD)和标准JAX-RS客户机(自JavaEE7以来新增)的好处。拥有JMS、JPA等服务也很好

问题是如何以标准方式编写/注释main方法<方法上的code>@Inject不好,因为此类方法必须快速返回<代码>@Schedule并不理想,因为除非我以编程方式确定当前系统时间,否则它会定期运行

我能想到的最好办法是在
@Inject
方法中设置一个一次性
计时器
,并用
@Timeout
注释我的主要方法

不知何故,这似乎有点脆弱或不雅有没有更好的标准方式启动服务?一些只会导致服务启动并开始运行的注释


此外,如何在取消部署时中断和关闭服务的最佳标准方法是什么?

如果您可以将
EJB
与(或代替)
CDI
,然后为bean尝试
@Singleton
+
@Startup
注释,并为
main()尝试
@PostConstruct
方法

@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();
    }
}

如果您可以将
EJB
CDI一起使用(或代替
CDI
),那么请为bean尝试
@Singleton
+
@Startup
注释,并为
main()
方法尝试
@PostConstruct

@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();
    }
}

当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.
}
@Singleton
@启动
公共类YourBean{
@注入
私人活动开始;
@施工后
私有void主方法(){
启动。点火(新XXX());
}
公共无效句柄已开始(@XXX已开始){
//真正的主要方法。
}

}

当后期构造长期运行时,与事件解耦:

@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.
}
@Singleton
@启动
公共类YourBean{
@注入
私人活动开始;
@施工后
私有void主方法(){
启动。点火(新XXX());
}
公共无效句柄已开始(@XXX已开始){
//真正的主要方法。
}

}

你的问题有点迂回。如果您在应用程序容器中运行应用程序,那么为什么要定义main方法?只要用一个方法创建一个启动单例EJB。@这种曲解反映了我的不清晰,因此产生了这个问题<代码>@Schedule
需要一段时间。我应该在什么时候注释该方法?我不希望它定期运行。该方法需要精确运行一次。如果
@Schedule
在部署后接受一个完美的间隔,但实际上并非如此。我可以使用
@时间表吗。。。myfunc(计时器计时器)
并取消传入计时器,然后使用
TimerService
设置一个间隔计时器以运行
@Timeout。。。mymain()
听起来很复杂。不知道你是编辑了你的问题还是我遗漏了底部。我发誓它读起来不一样。总之,有一个想法——使用一个启动单例bean,并在其@PostConstruct方法中创建一个计时器。或者,嵌入第三方库(如Quartz),并安排一个非重复性作业,以便在部署应用程序时启动该作业。作业的日程要求是什么(应用程序部署、特定日期、按需运行?。@感知可能是您的感知;-)我没有编辑,如果我这样做了编辑将是可用的。我确实在你上次评论后编辑了我的用户名。计划要求为“应用程序部署”。谢谢你的建议。我不想使用第三方库,但我会尝试使用
@PostConstruct
计时器。@Perception(续)关于关机,让
@PreDestroy
设置一个标志并等待main方法持有的锁,当main注意到标志并结束时,该锁会被释放,这样可以吗?基本上,我想在取消部署时停止,在没有任何其他手动或非标准技术的情况下开始部署。如果您在应用程序容器中运行应用程序,那么为什么要定义main方法?只要用一个方法创建一个启动单例EJB。@这种曲解反映了我的不清晰,因此产生了这个问题<代码>@Schedule需要一段时间。我应该在什么时候注释该方法?我不希望它定期运行。该方法需要精确运行一次。如果
@Schedule
在部署后接受一个完美的间隔,但实际上并非如此。我可以使用
@时间表吗。。。myfunc(计时器计时器)
并取消传入计时器,然后使用
TimerService
设置一个间隔计时器以运行
@Timeout。。。mymain()
听起来很复杂。不知道你是编辑了你的问题还是我遗漏了底部。我发誓它读起来不一样。总之,有一个想法——使用一个启动单例bean,并在其@PostConstruct方法中创建一个计时器。或者,嵌入第三方库(如Quartz),并安排一个非重复性作业,以便在部署应用程序时启动该作业。作业的日程要求是什么(应用程序部署、特定日期、按需运行?。@感知可能是您的感知;-)我没有编辑,如果我这样做了编辑将是可用的。我确实在你上次评论后编辑了我的用户名。计划要求为“应用程序部署”。谢谢你的建议。我不想使用第三方库,但我会尝试使用
@PostConstruct
计时器。@Perception(续)关于关机,让
@PreDestroy
设置一个标志并等待main方法持有的锁,当main注意到标志并结束时,该锁会被释放,这样可以吗?基本上,我希望在取消部署时停止,在部署时开始,而不需要任何其他手动操作