在EJB 3.1中,我可以在为该bean获取的TimerService实例上使用TimerService#getTimers()获取特定bean的所有计时器。
然而,我真正需要的是系统范围的版本。即我想在EJB容器中有一个所有计时器的列表。
这样的事情可能吗?
答案 0 :(得分:6)
EJB 3.1中根本没有官方API。
如果您只使用注释和/或接口来标记超时方法,则可以对类路径上的所有类执行运行时遍历,并检查是否存在此批注或接口。这至少可以为你提供理论上可以与它们相关的定时器的bean。
不幸的是,这仍然不会为你提供这些bean的实际计时器。在EJB 3.1中,只能从会话上下文中请求时间信息,因为您似乎已经知道每个bean都是私有的。这意味着只有bean本身才能看到它具有的定时器。
作为Nayan建议的替代方法,您可以让您的bean实现一种方法,为您提供此信息。然后,您可以使用界面或自定义注释标记此方法。
在系统范围内扫描所有计时器类时,首先尝试发现所有可以与其关联的计时器的bean,然后尝试查找它们是否具有所需的注释或接口。如果他们没有后一种情况,您可以记录警告。这种方法的优点是定时器不太可能穿过裂缝。
另一种方法,但非常脆弱,是破解容器保存的任何私有结构来存储计时器信息。对于持久性计时器,至少存在可以检查的持久性存储,并且容器中的某个位置必须具有您所追求的结构。它必须在那里,因为容器本身必须意识到这一点。通常,容器有一些私有API来实现这一点,你可以通过反思技巧来破解它。
也可以是容器为此提供专有API。例如。在Java EE 5中,在Servlet容器中进行编程登录是不可能的,但是JBoss AS有一个专有的API,可以让你做到这一点。
答案 1 :(得分:2)
EJB 3.2有一个名为" getAllTimers()"。
的方法https://docs.oracle.com/javaee/7/api/javax/ejb/TimerService.html#getAllTimers--
描述: 返回与打包调用程序bean的同一模块中的Bean关联的所有活动计时器。这些包括以编程方式创建的计时器和自动创建的计时器。
答案 2 :(得分:1)
以下是用于获取系统所有现有计时器信息的示例代码片段。
//---
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());
}
}
//---
答案 3 :(得分:1)
你只能看到自己班级的计时器。使用EJB Scheduler,您无法列出应用程序的所有计时器。
@Resource
private TimerService timerService;
for (Timer timer : timerService.getTimers()) {
// do anything
}
使用Quartz,您可以通过Scheduler.getJobNames / triggerNames获取应用程序的所有作业/触发器。