2016-03-08 3 views
2

Как javax.ejb.TimerService (Glassfish 3.1.2.2) знаете, какой компонент необходимо выполнить?Как javax.ejb.TimerService знает, какой компонент будет вызывать?

В Java EE 6 tutorial мы узнаем, что мы можем определить функции обратного вызова таймера в бина:

@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-код для вызова? this не является параметром createSingleActionTimer.

+0

Я проверяю исходный код Glassfish прямо сейчас, чтобы посмотреть на реализацию TimerService, но для меня это представляет интересный вопрос, поэтому я расскажу об этом здесь для получения экспертной оценки. – DavidS

+0

При дальнейших размышлениях, вероятно, это получение ссылки на объект во время инъекции '@ Resource' из [InjectionPoint] (https://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection. html # d0e1624) объект. Я посмотрю, смогу ли я найти его в исходном коде, если эта проверка когда-либо закончится. – DavidS

+1

История происхождения длинная и скучная, но это сводится к следующему: в контейнере DI ничто действительно не скрыто, и ничто не похоже на то, что кажется. Контейнер имеет более чем несколько механизмов для инъекций, и все они являются контекстно-зависимыми. Все в контейнере точно знает, где оно находится. Возьмите ['EJBContext'] (http://docs.oracle.com/javaee/6/api/javax/ejb/EJBContext.html), например: предоставление контекстной информации в EJB. Опять же, в контейнере ничего не скрывается. – kolossus

ответ

1

Это определяется реализацией, но есть по крайней мере два вероятных стратегий реализации:

  1. Когда контейнер EJB впрыскивает TimerService в экземпляр бина, то TimerService может быть связаны с этим EJB компонент, поэтому, когда таймер должен запускаться, он знает, как найти экземпляр и вызвать метод тайм-аута.
  2. Когда EJB вызывает метод, он может подталкивать метаданные о текущем компоненте и методе EJB к ThreadLocal, а когда методы запускаются в TimerService, он находит текущий компонент EJB и создает на нем таймеры.
+0

Спасибо, Брет.Этот ответ на мой вопрос, в частности, «Это реализация определена». Если я действительно хочу знать, как Glassfish это делает, я могу сам прочитать исходный код. Ваши предложения о том, как это сделать, помогут мне прочитать код. – DavidS

0

Согласно §13.2 из EJB Спецификации:

Таймеры могут быть созданы для сеансных, одноэлементных сеансовых компонентов, управляемые сообщениями компонентов [88]. Таймеры не могут быть созданы для сессионных компонентов с состоянием [89].

Ответ на ваш вопрос для синглтон-сессионных бобов самоочевиден.

Для сессионных bean-компонентов без состояния не имеет значения, какой экземпляр bean вызывается, поскольку у них нет состояния. То же самое относится к компонентам, управляемым сообщениями.

+0

Извините, Стив, мой вопрос был неясным. Я не имел в виду «Какой боб из пула фанатов без гражданства», я имел в виду «Какой bean_at all_». Я могу вызвать 'timerService.createSingleActionTimer' из дюжины типов различного типа без учета состояния, но как таймер знает, какой callback для вызова, так как мы не предоставляем ссылку на компонент, который его вызывал? – DavidS

Смежные вопросы