在 EJB 3.0 (WebLogic 11gR1) 上模拟 @Startup

Simulate @Startup on EJB 3.0 (WebLogic 11gR1)

我的目标是设置一个在启动时启动 运行 的计划作业。

在 EJB 3.1 上,我可以做类似的事情:

@Startup
@Stateless
public class SchedulePoller {

    @Resource
    TimerService timerService;

    @PostConstruct
    public void defineScheduler() {
        timerService.createTimer(60000, 60000, null);
    }

    @Timeout
    public void checkSchedule(Timer timer) {
        System.out.println("time: " + new Date());
    }
}

现在我的问题是 @Startup 在 EJB 3.0 中不可用,EJB 3.0 是 WebLogic 11gR1 (10.3.5) 支持的最新版本。这意味着未构造 Bean,因此未调用 defineScheduler 方法。

我读到一个可能的解决方案是定义一个 HttpServlet,注入我的 Bean,覆盖 init 方法并将 <load-on-startup> 放入 web.xml 文件。 我无法使用此方法,因为我的项目是一个 EJB 模块并且我没有 Web 上下文。

到目前为止我想到的唯一其他解决方案是将 Bean 更改为 @MessageDriven 并在启动后将消息放入队列,但这需要在每次部署时执行额外操作。

有什么方法可以复制 @Startup 注释吗?最好的选择是在启动时自动启动 Bean,但我也可以考虑将脚本添加到 StartWebLogic.cmd 或任何其他 "automatic" 方式。

谢谢。

不,EJB 3.0 没有其他选项。你说你的项目是一个 EJB 模块,但我的建议仍然是创建另一个 WAR 模块来驱动你的启动。我会使用 ServletContextListener 而不是 load-on-startup servlet,因为您实际上并不希望在 WAR 中有一个端点,您只想(ab)将其用于应用程序启动通知。

我不得不创建另一个扩展名为 "Dynamic Web Module" 的项目,只是为了使用此信息编辑 web.xml

<listener>
    <listener-class>it.project.scheduler.InitServletContainer</listener-class>
</listener>

在我现有的项目中,我添加了监听器实现

public class InitServletContainer implements ServletContextListener {

    @EJB
    private transient SchedulePollerLocal schedulerBean;

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        schedulerBean.defineScheduler();
    }

}

最后,我不得不将这个项目添加到 EAR