Выпуск CDI для инъекций Websocket Bean

Я не понимаю, почему использование инъекций CDI не работает с websockets, используя undertow.

Ниже приведен код для простой конечной точки веб-сокета.

@ServerEndpoint("/")
public class TestWebSocketEndpoint {

    @Inject
    private RetrieveAccessor retrieveAccessor;

    private final Logger logger = Logger.getLogger(this.getClass().getName());

    @OnOpen
    public void onConnectionOpen(Session session) {
        logger.info("Connection opened ... " + session.getId());
    }

    @OnMessage
    public String onMessage(String message) {

        if (!message.isEmpty()) {
            return message;
        }

        System.out.println("RETRIEVE BEAN -> " + retrieveAccessor);
        if (retrieveAccessor != null) {
            return "BEAN NOT NULL";
        }
        return ":(";
    }

    @OnClose
    public void onConnectionClose(Session session) {
        logger.info("Connection close .... " + session.getId());
    }

}

Конечно, проблема в том, что введенное свойство имеет значение null. Конечно, у меня нет проблем с использованием остальной части вещей для этого развертывания и внедрения bean-компонента без состояния, описанного ниже. Есть ли обходной путь для этого, с какими проблемами я мог бы столкнуться, если бы я просто инициировал нужные мне свойства, которые являются бобами? Потому что это определенно работает.

RetrieveAccessor retrieveAccessor = new.... {code}

2 ответа

Решение

Простой способ заставить внедрение работать с вашими аннотированными классами @ServerEndpoint - это установить пользовательский конфигуратор, который обрабатывает создание вашего экземпляра конечной точки, переопределив метод getEndpointInstance(Class endpointClass) для создания экземпляра с помощью CDI.

https://tyrus.java.net/documentation/1.13/user-guide.html

Аннотированная конечная точка:

@ServerEndpoint(value = "/", configurator = CDIEndpointConfigurator.class)
public class TestWebSocketEndpoint {
   ...
}

Пользовательский конфигуратор:

public class CDIEndpointConfigurator extends ServerEndpointConfig.Configurator {

    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
        return CDI.current().select(endpointClass).get();
    }
}

Undertow является только контейнером сервлетов. Weld (или OWB) обеспечивает поддержку CDI. Я не уверен, как вы создаете экземпляр Undertow, но вам нужно использовать Weld (или какую-то другую реализацию CDI).

Вот один пример, как это сделать. Используйте расширение CDI, чтобы найти конечные точки, и как только вы их получите, вы можете зарегистрировать их в Undertow

Не стесняйтесь использовать гамак для этого.

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