我有一个 EJB 计时器,每天在一天中的特定时间运行两次。 我希望能够通过网页请求手动触发此计时器,但我不知道如何做到这一点。
我不想让它在 Web 线程中运行,因为计时器可能是一个很长的进程,因此最好让它在后台的 EJB 进程中运行。我可以在 EJB 内获取 TimerService
,但我无法从 Web 上下文访问它。
我必须使用计时器而不是线程。 我正在使用 JBoss 7 和 WebSphere 8.5。
最佳答案
我们有 3 个选项可以在部署应用程序时自动创建计时器。
- 通过调用 EJB 方法创建计时器:Invoke
initializeTimer
在 Web 的ServletContextListener
的contextInitialized
方法中 模块。 - 创建 servlet 并实现 init 方法来调用 EJB
创建计时器的方法。设置
load-on-startup
属性 当 web 模块启动时,servlet 自动启动 servlet 开始了。 - 使用 J2EE 容器的专有 API 来使用 Startup 类。
下面是一个示例,说明如何在部署应用程序时使用 ServletContextListener
(选项 1)自动安排计时器,如下所示:
public class MyLifeCycleEventExample
implements ServletContextListener
{
ServletContext servletContext;
/* Methods from the ServletContextListener */
public void contextInitialized(ServletContextEvent sce)
{
servletContext = sce.getServletContext();
try
{
Context context = new InitialContext();
TimerDemoHome timerDemoHome =
(TimerDemoHome)PortableRemoteObject.narrow(
context.lookup("java:comp/env/TimerDemo"),
TimerDemoHome.class);
TimerDemo timerDemo;
// Use one of the create() methods below to
// create a new instance
timerDemo = timerDemoHome.create();
Date firstDate= new java.util.Date();
// Call any of the Remote methods below to access
// the EJB this code does not check whether the timer
// has already been scheduled.
// You should check this for duplicate timers
timerDemo.initializeTimer( firstDate, 1800000, "MyTimer" );
timerDemo.getTimerInfo();
//Cancel Timer
//timerDemo.cancelTimer("MyTimer");
}
catch(Throwable ex)
{
ex.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent sce)
{
}
protected void log(String msg)
{
System.out.println("[" + getClass().getName() +
"] " + msg);
}
}
但是您需要使用以下配置在 Web 模块 (web.xml) 的部署描述符中注册监听器
<listener>
<listener-class>
TimerWeb.MyLifeCycleEventExample
</listener-class>
</listener>
关于java - 如何以编程方式从线程外部启动 EJB 计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39356067/