我可以将 EJB Stateless Bean 与 CDI 一起使用来维护用户会话吗?
基于这篇文章 http://www.adam-bien.com/roller/abien /entry/ejb_3_1_killed_the 我在我的应用程序中使用 @Named @Stateless bean 与数据库通信(在此处注入 EntityManager)并显示信息一个 jsf 页面。自 Java EE 5 以来,这是一个很大的便利,但我有一个问题。
使用此类 bean 来维护用户会话(购物车等)是否安全?我读了一本关于 ejb 3.0 的书,我知道同一个无状态 bean 可以用于许多客户端。
使用具有所有 ejb 功能(事务、线程安全等)的托管 bean 的最佳方法是什么?我的意思是除了 Java EE 5 中的托管 bean + ejb 接口以及实现 + ejb 注入之外,还有其他方式吗?
我使用 GlassFish 3.1 WebProfile
Based on this post http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the I use in my app @Named @Stateless bean for communication with a database (injecting EntityManager here) and display information on a jsf page. It's great facilitation since Java EE 5, but I have one question.
Is it secure to use such beans for maintaining a user session (shopping cart etc)? I read a book about ejb 3.0 and I know that the same stateless bean could be used with many clients.
What's the best approach to use a managed bean with all ejb features (transactions, thread safety etc)? I mean any other way than managed bean + ejb interface with implementation + ejb injection as in Java EE 5?
I use GlassFish 3.1 WebProfile
添加达菲莫的建议;与使用 HTTP 会话相比,使用有状态会话 Bean 还有一些额外的注意事项。
HTTP 会话基本上具有类似映射的结构。它可直接用于会话中的所有线程(请求)。这使得操作多个项目成为相对不安全的行为。可以在会话本身上进行同步,但这是一个有风险的操作,可能会导致整个应用程序死锁。 HTTP 会话允许您声明事件侦听器,该事件侦听器会在对 http 会话进行任何类型的修改时触发。
Stateful session bean 当然有一个 bean 结构。它具有一种自动同步功能,因为只有线程可以同时在 bean 中处于活动状态。通过注释,您可以声明其他线程在并发访问时是否等待(如果是,等待多长时间)或立即抛出异常。
通常每个用户只有一个 http 会话,而单个用户可以同时使用多个有状态会话 Bean。有状态会话 bean 的一个特殊优点是它们有一种机制可以在超时后钝化其状态,这可以释放服务器的内存(当然以磁盘空间为代价)。有状态会话 bean 不直接具有 http 会话所具有的事件侦听器类型。
我认为最初有状态会话 bean 的“会话”方面是维护与远程非 Web 客户端(Swing、另一个 AS 等)的会话。这很像创建 http 会话来维护与远程 Web 客户端的会话。由于非 Web 客户端可以请求并保留有状态会话 Bean 的多个代理,因此 Web 类比实际上更类似于最近引入的
会话范围
。在远程 Web 客户端与服务器通信的情况下,服务器在内部与有状态会话 Bean 通信,这些概念极大地重叠。远程 Web 客户端仅了解 http 会话(通过 JSESSIONID),而不了解有状态会话 Bean 的会话。因此,如果 http 会话丢失,您通常将无法再次将远程客户端与特定的有状态会话 Bean 连接。因此,在这种情况下,HTTP 会话始终处于领先地位,您不妨将购物车项目存储在单个 (http) 会话作用域 bean 中。
在一种特定情况下,有状态会话 Bean 在内部通信中会派上用场,那就是如果您需要 JPA 的
扩展持久性上下文
。例如,如果实体上的锁定需要在请求之间持续,则可以使用此功能(如果您的库存有限并且不想在用户实际使用时立即看到“缺货”消息,这对于购物车可能很方便)结账)。Adding to the advice of duffymo; there are some additional considerations for using stateful session beans vs using the HTTP session.
The HTTP session basically has a map like structure. It's directly available to all threads (requests) that are part of the session. This makes manipulating several items a relatively unsafe action. It's possible to synchronize on the session itself, but this is a risky operation that can potentially dead-lock your entire application. The HTTP session does allow you to declare event listeners, which fire upon any kind of modification of the http session.
The Stateful session bean of course has a bean structure. It has a kind of auto synchronization feature, as only thread can be active in the bean at the same time. Via annotations you can declare if other threads wait (and if so, for how long) or immediately throw an exception in the face of concurrent access.
Where there is normally only one http session per user, a single user can make use of multiple stateful session beans at the same time. A particular advantage of stateful session beans is that they have a mechanism to passivate their state after some timeout, which can free up your server's memory (at the cost of disk space of course). Stateful session beans do not directly have the kind of event listeners that the http session does have.
I think that originally the "session" aspect of stateful session beans was to maintain a session with remote non-web clients (Swing, another AS, etc). This is much like the http session was created to maintain a session with remote web clients. Since a non-web client can request and hold on to multiple proxies for stateful session beans, the web analogy is actually more akin to that of the recently introduced
conversation scope
.In the case of remote web clients talking to a server, where the server internally talks to a stateful session bean, the concepts greatly overlap. The remote web client only knows about the http session (via the JSESSIONID) and nothing about the stateful session bean's session. So if the http session was lost, you typically would not be able to connect the remote client with the specific stateful session bean again. The HTTP session in this case is thus always leading and you might as well store your shopping cart items inside a single (http) session scoped bean.
There is one specific case where stateful session beans come in handy for internal communication, and that's if you need JPA's
extended persistence context
. This can be used if e.g. locks on entities need to last between requests (which is possibly handy for a shopping cart if you have limited stock and don't want to confront the user with an "out of stock" message as soon as he actually checks out).