Java:在Oracle WebSockets教程中理解CDI

Java:在Oracle WebSockets教程中理解CDI,java,websocket,cdi,Java,Websocket,Cdi,我试图了解以下有关WebSocket的Oracle教程: 这是我第一次看到CDI、scopes和injection。我想了解以下代码如何指定每个会话将存在多少DeviceWebSocketServer和DeviceSessionHandler实例 以下是Oracle的相关代码:(我添加了打印语句) package org.example.websocket; 导入javax.websocket.OnOpen; 导入javax.websocket.Session; 导入javax.websock

我试图了解以下有关WebSocket的Oracle教程:

这是我第一次看到CDI、scopes和injection。我想了解以下代码如何指定每个会话将存在多少DeviceWebSocketServer和DeviceSessionHandler实例

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

package org.example.websocket;
导入javax.websocket.OnOpen;
导入javax.websocket.Session;
导入javax.websocket.server.ServerEndpoint;
导入javax.enterprise.context.ApplicationScoped;
导入javax.inject.inject;
....
@适用范围
@ServerEndpoint(“/actions”)
公共类设备WebSocketServer{
@注入
私有设备sessionHandler sessionHandler;
@奥诺彭
公开作废开放(会议){
System.out.println(“OnOpen.Server端点id:+this”);
sessionHandler.addSession(会话);
}
....
}
包org.example.websocket;
导入javax.enterprise.context.ApplicationScoped;
导入java.util.HashSet;
导入java.util.Set;
导入javax.websocket.Session;
导入org.example.model.Device;
....
@适用范围
公共类DeviceSessionHandler{
专用int设备ID=0;
私有最终集会话=新HashSet();
私有最终设置设备=新HashSet();
公共会话(会话){
System.out.println(“添加会话.会话处理程序id:+this”);
添加(会话);
用于(设备:设备){
JsonObject addMessage=createAddMessage(设备);
发送会话(会话,添加消息);
}
}
....
}
这两个类都使用应用程序作用域,但对于每个新会话,都会创建一个新的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

那么,如果作用域不确定每个会话的实例数,那么如何确定


提前谢谢

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

谢谢您的回答John。你是说只有一个DeviceWebSocketServer实例,但是有多个引用?在此上下文中,“条目”指的是什么?谢谢几乎。代理指向该bean的引用。即使创建了多个bean实例,CDI也将管理底层引用的状态。这就是为什么建议使用
@PostConstruct
@PreDestroy
而不是由施工人员进行施工的原因。
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);
        }
    }

    ....

}