我正在尝试理解以下关于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
因此,如果范围没有确定每个会话的实例数,那么这是如何确定的?
提前致谢!
答案 0 :(得分:0)
CDI是基于代理的。底层引用可能不同,但实例被认为是相同的。当您多次打开onOpen时,您是否看到所有收集的条目?