Java:了解Oracle WebSockets教程中的CDI

时间:2016-12-23 04:06:38

标签: java websocket cdi

我正在尝试理解以下关于WebSockets的Oracle教程: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html

这是我第一次看到CDI,示波器和注射。我想了解以下代码如何指定每个会话将存在多少个DeviceWebSocketServer和DeviceSessionHandler实例。

以下是Oracle的相关代码:(我添加了打印语句)

package org.example.websocket;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import javax.enterprise.context.ApplicationScoped;   
import javax.inject.Inject;
....

@ApplicationScoped
@ServerEndpoint("/actions")
public class DeviceWebSocketServer {

    @Inject
    private DeviceSessionHandler sessionHandler;

    @OnOpen
    public void open(Session session) {
        System.out.println("OnOpen. Server Endpoint id: " + this);
        sessionHandler.addSession(session);
    }

    ....

}

package org.example.websocket;
import javax.enterprise.context.ApplicationScoped;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.Session;
import org.example.model.Device;
....

@ApplicationScoped
public class DeviceSessionHandler {
    private int deviceId = 0;
    private final Set<Session> sessions = new HashSet<>();
    private final Set<Device> devices = new HashSet<>();


    public void addSession(Session session) {
        System.out.println("Adding session. Session handler id: " + this);
        sessions.add(session);
        for (Device device : devices) {
            JsonObject addMessage = createAddMessage(device);
            sendToSession(session, addMessage);
        }
    }

    ....

}

两个类都使用Application范围,但是对于每个新会话,都会创建一个新的DeviceWebSocketServer实例,而在其所有实例中只使用一个DeviceSessionHandler实例。为了证明这一点,这是我打开两个会话后的打印语句的输出:

信息:OnOpen。服务器端点ID:org.example.websocket.DeviceWebSocketServer@769f6d85

信息:添加会话。会话处理程序ID:org.example.websocket.DeviceSessionHandler@4c8caf5

信息:OnOpen。服务器端点ID:org.example.websocket.DeviceWebSocketServer@5e29b620

信息:添加会话。会话处理程序ID:org.example.websocket.DeviceSessionHandler@4c8caf5

因此,如果范围没有确定每个会话的实例数,那么这是如何确定的?

提前致谢!

1 个答案:

答案 0 :(得分:0)

CDI是基于代理的。底层引用可能不同,但实例被认为是相同的。当您多次打开onOpen时,您是否看到所有收集的条目?