Почему CDI не работает в одноэлементном классе

Одноэлементный класс запускает событие, но контейнер не вызывает прослушиватель событий CDI.

Ниже creatData() в одноэлементном классе DataLoaderSessionBean вызывает метод loadUsers(), а loadUsers(), в свою очередь, запускает событие, которое предполагает вызов XMLDataListener.UserData(), но вызов так и не происходит. Однако, если я изменю класс с Singleton на сеансовый компонент с сохранением состояния или без сохранения состояния, все будет работать хорошо.

      @Record
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)

public class DataLoaderSessionBean {

    @Inject
    @UserXMLData
    Event<DataEvent> userData;
    
    private final static int LOAD=0;

    private void loadUsers() {
        DataEvent event = new DataEvent();
        event.setCommand(LOAD);
        userData.fire(event);
    }
    
    @PostConstruct
    public void createData() {
        loadUsers();
        .........
    }
}

Вот прослушиватель событий. Метод userData() в этом классе прослушивателя событий не вызывается контейнером.

      @Record
@SessionScoped
public class XMLDataListener implements Serializable {

    private static final long serialVersionUID = -2230122751970858111L;
    private final static int LOAD=0;
    public void UserData(@Observes @UserXMLData DataEvent event) {
        int cmd = event.getCommand();
        switch(cmd){
            case LOAD: loadUsers();
            break;
            ..........
            
        }
    }
}

Интерфейс слушателя:

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

Данные события

      public class DataEvent implements Serializable {
    
   private static final long serialVersionUID = -2230122751970857224L;
   private int command;

    public DataEvent() {
    }

    public int getCommand() {
        return command;
    }

    public void setCommand(int command) {
        this.command = command;
    }   
}

Есть идеи, почему эта функциональность хорошо работает для сеансовых компонентов, а не для синглтона?

Спасибо

1 ответ

Это поведение требуется спецификацией CDI 2.0, раздел 10.5.

Если нет активного контекста для области, к которой принадлежит bean-компонент,
объявляющий метод наблюдателя, то метод наблюдателя
не должен вызываться.

The @PostConstructМетод синглтона вызывается при запуске в контексте приложения, поэтому сеанс не активен. Чтобы вызвать метод наблюдателя XMLDataListenerдолжны быть объявлены с аннотацией @ApplicationScoped.

Другие вопросы по тегам