Как предполагает @ Андре, объект с конечным автоматом должен быть классом @ApplicationScoped
или @Singleton
в зависимости от того, нужна ли вам функция EJB или нет, на которую клиенты могут зарегистрироваться:
@ApplicationScoped
public class StateMachine {
private List<Client> clients;
@PostConstruct
public void create() {
clients = new LinkedList<Client>();
}
public void register(Client client) {
clients.add(client);
}
public void unregister(Client client) {
clients.remove(client);
if (clients.isEmpty()) {
reset();
}
}
public void reset() {
// resets the singleton, because the container manages its life-cycle
}
}
Класс Client
может относиться к классу @SessionScoped
, который действует до тех пор, пока клиентский сеанс действителен. По первому запросу класса сессий регистрируется в синглтоне. Затем вы можете информировать клиентов о событиях, просматривая список. Всякий раз, когда требуются актуальные данные, класс Client
можно запрашивать с помощью запроса.
@SessionScoped
public class Client {
@Inject private StateMachine machine;
@PostConstruct
public void registerToStateMachine() {
machine.register(this);
}
@PreDestroy
public void unregisterFromStateMachine() {
machine.unregister(this);
}
public void handleEvent(/*..*/) {}
public /*..*/ query() {}
}
Имейте в виду, что вы не можете отправить CDI Event<>
из @ApplicationScoped
в @SessionScoped
объектов, поскольку их контекст недоступен в контексте приложения.