Событие CDI сработало, но не получено всеми потоками / сеансами - PullRequest
0 голосов
/ 25 июня 2018

У меня есть простая установка с одним сеансом, который поддерживает файл JSF xhtml. В рамках этого я запускаю событие, объясняя, что и тот же сеанс, и любой другой сеанс получат событие при отправке.

Однако, как ни странно, я вижу, что во время срабатывания события его получает только текущий сеанс, а не другие сеансы. Я проверяю наличие двух разных сессий, используя два разных браузера (в данном случае Safari и Firefox).

Правильно ли я понимаю концепцию событий на основе CDI?

Бин, поддерживающий сессию:

package testevent;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Named
@SessionScoped
public class TestEventSession implements Serializable {
  private String message = "Start Message";
  private String receivedMessage = "";

  @Inject
  @ForTest Event<String> messageEvent;

  Logger LOG = LogManager.getLogger();

  public void messageChanged(@Observes(notifyObserver = Reception.IF_EXISTS) @ForTest String message) {
    LOG.info("messageChanged <-- "+message);
    this.receivedMessage = message;
  }

  public String getReceivedMessage() {
    return receivedMessage;
  }

  public String getMessage() {
    LOG.info("getMessage --> "+message);
    return message;
  }

  public void setMessage(String message) {
    LOG.info("setMessage <-- "+message);
    this.message = message;
    LOG.info("Firing Message Change");
    messageEvent.fire(message);
    LOG.info("Done Firing Message Change");
  }
}

Файл xhtml:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  >
  <f:view transient="false">
    <h:body>
      <h:form>
        <h:inputText value="#{testEventSession.message}" />
        <h:outputText value="#{testEventSession.receivedMessage}" />
        <h:commandButton value="Submit"/>
        <h:button value="Refresh" />
      </h:form>
    </h:body>
  </f:view>
</html>

Используемый классификатор является очень простым:

package testevent;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ForTest {
}

Как часть результатов отладки, вы можете видеть, что только метод наблюдателя в текущем потоке / сеансе получает событие:

10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO  testevent.TestEventSession - Firing Message Change
10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO  testevent.TestEventSession - messageChanged <-- Start Message #3
10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO  testevent.TestEventSession - Done Firing Message Change

Обратите внимание, что это было протестировано с TomEE 7.0.3, который использует предположительно OpenWebBeans 1.7.3.

Относящиеся

Обновление

Возможно, это предполагаемая функция, однако я не смог найти это явно указано в спецификации CDI. Хотя представленный пример, кажется, имеет смысл только тогда, когда Observer только наблюдает за запущенными событиями в одном сеансе. В случае Produces в нем четко говорится о взаимодействии с областями действия. Я думаю, что это скорее некоторая документация, запаздывающая в официальной спецификации.

Пока что другие решения кажутся:

  • Регистрация и отслеживание сеансовых компонентов вручную
  • Использование JMS / Message-Driven Beans (MDB).

1 Ответ

0 голосов
/ 25 июня 2018

На стороне наблюдателя только текущая активная сессия будет ловить его по спецификации.Если вы хотите транслировать все сеансы, вам нужно отслеживать их в реестре.

5.5.6 CDI 2.0:

Получите контекстный экземпляр компонента, который объявляетметод наблюдателя в соответствии с контекстным экземпляром компонента.

Контекстный экземпляр определен в 6.5.3 как

экземпляр, обслуживаемый контекстом текущей области.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...