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

2022-09-02 12:03:04

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

如何实现此要求?


答案 1

下面列出了几种在 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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee">

    <listener>
      <listener-class>com.stackoverflow.question.MyServletContextListener</listener-class>
    </listener>

</web-app>

创建一个 EJB 3.1 @Startup Bean

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

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 */
  }

}

答案 2

我测试了使用 和 注释的建议解决方案。事实证明,Glassfish在完成所有注释的方法之前不会完成应用程序的部署。因此,就我而言,部署将需要几分钟到一个小时。@Startup@PostConstruct@PostConstruct

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

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

       timer.cancel();
    }
 }

使用非持久性计时器允许在重新启动应用程序服务器时重新创建计时器。