2

我不明白为什么 CDI 使用注入不适用于 websockets,使用 undertow。

下面是我为一个简单的 websocket 端点提供的代码。

@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());
    }

}

当然问题是注入的属性为空。对于下面描述的无状态 bean 的部署和注入,我当然没有问题。有没有办法解决这个问题,如果我只是初始化我需要的 bean 属性,我可能会遇到什么问题?因为这绝对有效。

RetrieveAccessor retrieveAccessor = new.... {code}

4

2 回答 2

3

在 @ServerEndpoint 注释类上进行注入的一种简单方法是设置一个自定义配置器,该配置器通过覆盖 getEndpointInstance(Class endpointClass) 方法以使用 CDI 实例化来处理端点实例的创建。

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

带注释的端点:

@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();
    }
}
于 2016-11-11T15:10:42.630 回答
1

Undertow 只是一个 servlet 容器。Weld(或 OWB)提供 CDI 支持。我不确定您如何实例化 Undertow,但您需要利用 Weld(或其他一些 CDI 实现)。

这是一个如何做到这一点的例子。利用CDI 扩展来查找端点,一旦你拥有它们,你就可以在 Undertow 中注册它们

随意利用吊床来实现这一点。

于 2016-10-09T15:33:24.827 回答