【问题标题】:How to get all EJB timers?如何获取所有 EJB 计时器?
【发布时间】:2010-12-25 12:38:18
【问题描述】:

在 EJB 3.1 中,我可以在为该 bean 获得的 TimerService 实例上使用 TimerService#getTimers() 获取特定 bean 的所有计时器。

然而,我真正需要的是系统范围的版本。 IE。我想要一份 EJB 容器中所有计时器的列表。

这样的事情可能吗?

【问题讨论】:

    标签: ejb ejb-3.1


    【解决方案1】:

    在 EJB 3.1 中根本没有用于此的官方 API。

    如果您只使用注解和/或接口来标记超时方法,您可以对类路径上的所有类进行运行时遍历,并检查此注解或接口是否存在。这至少会给你理论上可以有与之关联的计时器的bean。

    不幸的是,这仍然不会为您提供这些 bean 的实际计时器。在 EJB 3.1 中,只能从会话上下文中请求时间信息,您似乎已经知道,会话上下文对于每个 bean 都是私有的。这意味着只有 bean 本身才能看到它有哪些计时器。

    作为 Nayan 建议的替代方案,您可以让您的 bean 实现一种方法来为您提供此信息。然后,您可以使用接口或自定义注释标记此方法。

    在您对所有计时器类的全系统扫描中,您首先尝试发现所有可以与它们关联的计时器的bean,然后尝试找出它们是否具有所需的注释或接口。如果他们没有后一种情况,您可以记录警告。这种方法的优点是计时器不太可能漏掉。

    还有另一种方法,但非常脆弱,是侵入容器保存的任何私有结构以存储计时器信息。对于持久计时器,至少有可以检查的持久存储,并且容器中的某处必须有您所追求的结构。它必须在那里,因为容器本身必须意识到这一点。通常一个容器有一些私有的 API 来达到这个目的,你可以通过反射技巧来破解它。

    容器也可以为此提供专有 API。例如。在 Java EE 5 中,不可能在 Servlet 容器中进行编程登录,但 JBoss AS 有一个专有的 API 可以让您做到这一点。

    【讨论】:

    • 不完全是我希望得到的答案,但足够公平。 EJB 计时器在 3.1 中得到了极大的改进,但遗憾的是没有获得所有计时器列表的有用信息。我会尝试建议的方法。
    • @Arjan,像往常一样很好的答案!这个功能真的很高兴看到。我问过here,Reza 谈到了 TimerService 与 EJB 的分离。
    • 只是为了完成这个讨论 - 在这里你可以找到功能请求Discovering all timers within the container
    【解决方案2】:

    EJB 3.2 有一个名为“getAllTimers()”的方法。

    https://docs.oracle.com/javaee/7/api/javax/ejb/TimerService.html#getAllTimers--

    说明: 返回与打包调用者 bean 的同一模块中的 bean 关联的所有活动计时器。其中包括以编程方式创建的计时器和自动创建的计时器。

    【讨论】:

      【解决方案3】:

      以下是获取系统所有现有计时器信息的示例代码片段。

      //---
      
      private void viewSystemTimers(){
      
              Collection<Timer> allTimers = sessionContext.getTimerService().getTimers();
      
              Iterator<Timer> iterator = allTimers.iterator();
      
              while (iterator.hasNext()) {
      
                  Timer timer = (Timer) iterator.next();
      
                  System.out.println("SYSTEM TIMER : "+timer.getInfo());
              }
          }
      
      //---
      

      【讨论】:

      • 嗯,这基本上是我在问题中提到的方法。我的印象是这并没有给我所有的计时器,而只是给我与你的示例中的 sessionContext 关联的 bean 的计时器。 sessionContext 仅适用于一个 bean。
      • 尝试用一种通用的方式(系统范围)来管理系统中的定时器。有一个专门的 bean 负责创建/查看/取消,这样你就可以获得系统中存在的所有计时器。
      【解决方案4】:

      您只能看到自己班级的计时器。使用 EJB 调度程序,您无法列出应用程序的所有计时器。

      @Resource
      private TimerService timerService;
      
      for (Timer timer : timerService.getTimers()) {
          // do anything
      }
      

      使用 Quartz,您可以通过 Scheduler.getJobNames/triggerNames 获取应用程序的所有作业/触发器。

      【讨论】:

        猜你喜欢
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 2011-01-07
        • 2015-04-06
        相关资源
        最近更新 更多