Почему 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
.