在 Java EE 7 CDI 应用程序中更新注入的域对象
Update injected domain object in Java EE 7 CDI Application
这可能更像是一个概念性问题,而不是技术性问题,但我希望您能就如何进行提供一些建议。
我们正在开发一个大型 Java EE 7 应用程序,该应用程序可以无状态运行并且正在接收来自客户端的请求。每个请求都包含一个会话 ID,每个会话都包含大量特定于会话的域对象。
我们创建了一个 RequestScoped class,其中包含我们领域对象的所有生产者方法。当请求带有会话 ID 时,我们调用生产者的 setter 方法来在生产者 CDI bean 中设置会话 ID。
现在,如果链上的 RequestScoped classes 之一需要域对象之一,它在 class 的开头有一个 @Inject 定义,以从生产者那里获取域对象。 Producer 本身有一个到内存数据库的连接,以从那里检索域对象并将它们保存在局部变量中以供将来在此请求中使用。
现在问题是:假设 Bean A 注入域对象 X 并更改 X 的一些属性。我是否必须在我的生产者中调用 "update" 方法并将域对象 X 作为参数传递,或者是它在上下文中自动更新?
在请求范围内注入后,CDI 容器创建一个代理来访问实际的 bean。该代理是否可以像常规参考一样使用?例如。如果我在注入的 bean 上调用一个方法,它会更新代理后面的 bean 吗?
我知道这可能会让我失望,但无论如何我都会回答,因为我希望它对你有价值。听起来你们已经把马车放在马前面一英里处了。
The Producer itself has a connection to an inmemory DB to retrieve the domain objects from there and keep them in a local variable for future use in this request.
您正在尝试重新发明所谓的复制、分布式会话。不要这样做。使用@SessionScoped bean 并将业务逻辑保留在您的应用程序中,并让您的基础架构处理应用程序状态。想象一下多年后您正在查看此应用程序,当您的老板想要 UI 更新并且您的客户需要新功能时。您不仅要维护应用程序,还要维护您构建的一团乱七八糟的分布式框架:(
相反,您可以使用分布式内存数据库来保存会话状态并将其缓存在本地! Apache Tomcat/TomEE 对此有很好的支持(我不确定你使用的是什么应用程序服务器)
看看:
- https://github.com/magro/memcached-session-manager(使用 Couchbase、Redis、Memcached、Hazelcast、GridGrain 或 Apache Geode)
- http://community.gemstone.com/display/gemfire/Setting+Up+GemFire+HTTP+Session+Management+for+Tomcat(特定于 Gemfire)
我们使用第一个取得了巨大的成功。如果 Tomcat 实例遇到它在本地没有的会话 ID,它会从数据网格中提取它。处理完请求后,它将会话更改发布回数据网格。这非常快并且可以很好地缩放。
如果您的应用程序服务器不有能力做到这一点,与其以您正在做的痛苦方式编写应用程序,我会集中精力编写一个会话像 memcached-session-manager 这样的复制器。祝你好运!
这可能更像是一个概念性问题,而不是技术性问题,但我希望您能就如何进行提供一些建议。 我们正在开发一个大型 Java EE 7 应用程序,该应用程序可以无状态运行并且正在接收来自客户端的请求。每个请求都包含一个会话 ID,每个会话都包含大量特定于会话的域对象。 我们创建了一个 RequestScoped class,其中包含我们领域对象的所有生产者方法。当请求带有会话 ID 时,我们调用生产者的 setter 方法来在生产者 CDI bean 中设置会话 ID。 现在,如果链上的 RequestScoped classes 之一需要域对象之一,它在 class 的开头有一个 @Inject 定义,以从生产者那里获取域对象。 Producer 本身有一个到内存数据库的连接,以从那里检索域对象并将它们保存在局部变量中以供将来在此请求中使用。
现在问题是:假设 Bean A 注入域对象 X 并更改 X 的一些属性。我是否必须在我的生产者中调用 "update" 方法并将域对象 X 作为参数传递,或者是它在上下文中自动更新? 在请求范围内注入后,CDI 容器创建一个代理来访问实际的 bean。该代理是否可以像常规参考一样使用?例如。如果我在注入的 bean 上调用一个方法,它会更新代理后面的 bean 吗?
我知道这可能会让我失望,但无论如何我都会回答,因为我希望它对你有价值。听起来你们已经把马车放在马前面一英里处了。
The Producer itself has a connection to an inmemory DB to retrieve the domain objects from there and keep them in a local variable for future use in this request.
您正在尝试重新发明所谓的复制、分布式会话。不要这样做。使用@SessionScoped bean 并将业务逻辑保留在您的应用程序中,并让您的基础架构处理应用程序状态。想象一下多年后您正在查看此应用程序,当您的老板想要 UI 更新并且您的客户需要新功能时。您不仅要维护应用程序,还要维护您构建的一团乱七八糟的分布式框架:(
相反,您可以使用分布式内存数据库来保存会话状态并将其缓存在本地! Apache Tomcat/TomEE 对此有很好的支持(我不确定你使用的是什么应用程序服务器)
看看:
- https://github.com/magro/memcached-session-manager(使用 Couchbase、Redis、Memcached、Hazelcast、GridGrain 或 Apache Geode)
- http://community.gemstone.com/display/gemfire/Setting+Up+GemFire+HTTP+Session+Management+for+Tomcat(特定于 Gemfire)
我们使用第一个取得了巨大的成功。如果 Tomcat 实例遇到它在本地没有的会话 ID,它会从数据网格中提取它。处理完请求后,它将会话更改发布回数据网格。这非常快并且可以很好地缩放。
如果您的应用程序服务器不有能力做到这一点,与其以您正在做的痛苦方式编写应用程序,我会集中精力编写一个会话像 memcached-session-manager 这样的复制器。祝你好运!