Java @Singleton会话bean是跨不同会话管理对象的正确位置吗?

Java @Singleton会话bean是跨不同会话管理对象的正确位置吗?,java,rest,jakarta-ee,ejb,java-ee-7,Java,Rest,Jakarta Ee,Ejb,Java Ee 7,我仍在学习合适的JavaEE模式,希望您能给我一些关于解决这个问题的最佳工具的建议 我有一个需要管理多个智能代理实例的系统。客户端可以创建新实例,也可以按名称访问所需实例。多个客户端可以同时访问同一个代理 我们的计划是通过REST接口向代理公开操作,因此调用可能类似于: GET /sessions/ POST /sessions/{name} PUT /sessions/{name}/doanaction 这些会话在重启后不会持续,所以我不寻求资源管理 我的想法是,我们可以使用@Singl

我仍在学习合适的JavaEE模式,希望您能给我一些关于解决这个问题的最佳工具的建议

我有一个需要管理多个智能代理实例的系统。客户端可以创建新实例,也可以按名称访问所需实例。多个客户端可以同时访问同一个代理

我们的计划是通过REST接口向代理公开操作,因此调用可能类似于:

GET  /sessions/
POST /sessions/{name}
PUT  /sessions/{name}/doanaction
这些会话在重启后不会持续,所以我不寻求资源管理

我的想法是,我们可以使用
@Singleton
会话bean来管理名称到代理的映射,然后将其注入到
@Stateless
会话bean中,该会话bean将为REST web服务提供实用方法


我想确保我没有在这里滥用@Singleton。因为多个客户端可以访问同一个代理,所以似乎没有任何方法可以使用JavaEE会话管理来促进跨会话的对象管理。除了@Singleton会话bean之外,我还应该使用其他可注入对象吗?这通常是解决此问题的正确方法吗?谢谢

我认为EJB的任何开箱即用机制都不适合代理的概念,代理是一个有状态的实体,在服务器中有自己的生命周期,同时可供多个客户端访问

无状态会话bean没有状态,有状态会话bean仅用于一个客户端

因此,一种可能的设计是将状态从代理提取到
AgentState
对象中。然后将每个代理的状态存储在
ConcurrentHashMap
中,按代理名称索引。散列映射可以包装在
@Singleton
bean中

然后,REST控制器代码可以按名称检索代理状态,动态实例化一个代理
newMyAgent(agentState)
将状态传递给它,然后执行一些操作

多个客户端可以同时从缓存中检索代理状态。关键是
MyAgent
代码需要通过在代理对象执行复合操作时锁定代理对象来防止代理状态损坏:

类MyAgent{

public void someCompoundOperation() {
    synchronized (agentState) {
        ...
        String propertyA = agentState.getPropertyA();
        ... compare A with something

        agentState.setPropertyA(newA);
        ...
    }
}

这将防止两个客户端读取相同属性值时出现争用情况,并同时执行操作,而不是等待另一个代理完成并释放代理状态。

谢谢,这是我设想的方法。有没有办法让ejb在多台机器上分发代理实例,例如使用@Remote session beans的方式?我也很欣赏对同步访问的谨慎。非常有用的信息!我很高兴我能提供帮助。对于群集,最好将代理状态存储在数据库中,如果每次查询代理状态都有问题,则可以配置群集的二级事务缓存,尽管这样做缓存类型通常是付费产品