2

这可能更像是一个概念问题而不是技术问题,但是我希望您可以就如何继续向我提供一些建议。我们正在开发一个大型 Java EE 7 应用程序,该应用程序无状态地工作并从客户端获取请求。每个请求都包含一个会话 ID,每个会话都包含大量特定于会话的域对象。我们创建了一个 RequestScoped 类,其中包含我们领域对象的所有生产者方法。当请求带有会话 ID 时,我们调用生产者上的 setter 方法来设置生产者 CDI bean 中的会话 ID。现在,如果链上的 RequestScoped 类之一需要域对象之一,它在类的开头有一个 @Inject 定义,以从生产者那里获取域对象。

现在问题来了:假设 Bean A 注入域对象 X 并更改 X 上的一些属性。我是否必须在生产者中调用“更新”方法并将域对象 X 作为参数传递,还是在上下文中自动更新?在请求范围内注入后,CDI 容器会创建一个代理来访问实际的 bean。该代理是否可以像常规参考一样使用?例如,如果我在注入的 bean 上调用一个方法,它会更新代理后面的 bean 吗?

4

1 回答 1

2

我知道这可能会让我被否决,但无论如何我都会回答,因为我希望它对你有价值。听起来你们已经把马车放在马前面一英里处。

Producer 本身与内存数据库有一个连接,以从那里检索域对象并将它们保存在本地变量中以供将来在此请求中使用。

您正在尝试重新发明所谓的复制、分布式会话。不要这样做。使用 @SessionScoped bean 并将业务逻辑保留在您的应用程序中,并让您的基础架构处理应用程序状态。想象一下,多年后,当您的老板想要更新 UI 而您的客户需要新功能时,您会看到这个应用程序。您不仅要维护应用程序,还要维护您构建的一个有缺陷的分布式框架的一团糟:(

相反,您可以使用分布式内存数据库来保存会话状态并在本地缓存它!Apache Tomcat/TomEE 对此有很好的支持(我不确定您使用的是什么应用程序服务器)

看一眼:

我们使用第一个取得了巨大成功。如果 Tomcat 实例遇到它在本地没有的会话 id,它会从数据网格中提取它。处理完请求后,它会将会话更改发布回数据网格。这是非常快的并且可以很好地扩展。

如果您的应用程序服务器不具备执行此操作的能力,那么与其以您正在做的痛苦方式编写应用程序,我将集中您的精力来编写像 memcached-session-manager 这样的会话复制器。祝你好运!

于 2015-11-20T16:28:00.227 回答