部署Java EE应用程序后执行任务

我有一个Java EE应用程序,它应该在部署后与外部系统一起启动同步过程。

我怎么能实现这个要求?

下面列出了一些在JavaEE应用程序中获取生命周期回调的流行方法。

创建一个javax.servlet.ServletContextListener实现

如果您的.ear文件(嵌入式.war)有一个Web组件,或者您的部署本身是.war,您可以将ServletContextListener添加到web.xml并在服务器启动或关闭时获取回调。

例:

 package com.stackoverflow.question import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; public class MyServletContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent contextEvent) { /* Do Startup stuff. */ } @Override public void contextDestroyed(ServletContextEvent contextEvent) { /* Do Shutdown stuff. */ } } 

然后将此配置添加到web.xml部署描述符中。
$WAR_ROOT/WEB-INF/web.xml

   com.stackoverflow.question.MyServletContextListener   

创建EJB 3.1 @Startup Bean

此方法使用EJB 3.1 singleton从服务器获取启动和关闭回调。

 import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.ejb.Startup; import javax.ejb.Singleton; @Singleton @Startup public class LifecycleBean { @PostConstruct public void init() { /* Startup stuff here. */ } @PreDestroy public void destroy() { /* Shutdown stuff here */ } } 

您可以使用@Startup@PostConstruct注释在应用程序启动时执行任务。

我测试了使用@Startup@PostConstruct注释的建议解决方案。 事实certificate,在使用@PostConstruct注释的所有方法完成之前,Glassfish不会完成应用程序的部署。 所以在我的情况下,部署需要几分钟到一个小时。

但我想出了一种不同的方式来实现我想要的东西。 最好的解决方案似乎是一个定时器回调方法,它在执行后取消它的定时器。

 @Stateless public class SynchronisationService { @Schedule(hour = "*", minute = "*", persistent = false) protected void init(Timer timer) { doTheSync(); timer.cancel(); } } 

如果重新启动应用程序服务器,则使用非持久性计时器可以重新创建计时器。

例如,使用ServletContextListener或在启动时初始化的servlet。 当然,如果您在群集中对应用程序进行多次部署,并且只希望此过程运行一次,则会变得更加困难。