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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18274534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:56:53  来源:igfitidea点击:

Executing task after deployment of Java EE application

javajakarta-eetimer

提问by Oliver

I have a Java EE application which should start a synchronization process with an external system once after its deployment.

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

How could I implement this requirement?

我怎样才能实现这个要求?

采纳答案by Oliver

I tested the suggested solution which uses the @Startupand @PostConstructannotations. It turned out that Glassfish does not complete the deployment of an application until all methods annotated with @PostConstructhave finished. So in my case the deployment would take from several minutes up to an hour.

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

But I figured out a different way to achive what I want. The best solution seems to be a timer callback method which cancels its timer after its execution.

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

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

       timer.cancel();
    }
 }

Using a non-persistent timer allows the timer to be re-created if the application server is restarted.

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

回答by Dev

Below are listed a couple of popular methods for getting lifecycle callbacks in JavaEE apps.

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

Create a javax.servlet.ServletContextListener implementation

创建一个 javax.servlet.ServletContextListener 实现

If you have a web component to your .ear file (embedded .war) or your deployment is a .war by itself you can add a ServletContextListenerto your web.xmland get a callback when the server starts or is shutting down.

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

Example:

例子:

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

}

and then add this configuration to your web.xmldeployment descriptor.
$WAR_ROOT/WEB-INF/web.xml.

然后将此配置添加到您的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>

Create an EJB 3.1 @Startup Bean

创建 EJB 3.1 @Startup Bean

This method uses an EJB 3.1 singleton to get a startup and shutdown callback from the server.

此方法使用 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 */
  }

}

回答by JB Nizet

Using a ServletContextListener, or a servlet that is initialized at startup, for example. Of course, this becomes much harder if you have multiple deployments of the application in a cluster, and only want this process to be run once.

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

回答by Kayaman

You can use the @Startupand @PostConstructannotations to perform tasks on application startup.

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