javax.ejb.TimerService 如何知道要调用哪个 bean?

How does javax.ejb.TimerService know which bean to call?

javax.ejb.TimerService (Glassfish 3.1.2.2) 如何知道要执行哪个 bean?

Java EE 6 tutorial 中,我们了解到可以在企业 bean 中定义计时器回调:

@Timeout
public void timeout(Timer timer) {
    System.out.println("TimerBean: timeout occurred");
}

然后我们可以像这样安排编程计时器:

@Resource
TimerService timerService;
...
// Sets a programmatic timer that will expire in 1 minute (6,000 milliseconds):
long duration = 6000;
Timer timer = timerService.createSingleActionTimer(duration, new TimerConfig());

TimeService 如何知道要调用哪个 bean?一个bean中只能有一个注解方法,但是它怎么知道调用哪个bean呢? this 不是 createSingleActionTimer 的参数。

它是实现定义的,但至少有两个似是而非的实现策略:

  1. 当 EJB 容器将 TimerService 注入 bean 实例时,TimerService 可以绑定到该 EJB 组件,因此当计时器需要触发时,它知道如何定位实例并调用超时方法。
  2. 当 EJB 调用方法时,它可以将有关当前 EJB 组件和方法的元数据推送到 ThreadLocal 上,而当在 TimerService 上调用方法时,它会定位当前 EJB 组件并基于该组件创建计时器。

根据 EJB 规范的 §13.2:

Timers can be created for stateless session beans, singleton session beans, message-driven beans[88]. Timers cannot be created for stateful session beans[89].

您的单例会话 bean 问题的答案不言而喻。

对于无状态会话 bean,调用哪个 bean 实例没有区别,因为它们没有状态。这同样适用于消息驱动的 bean。