且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JSF请求作用域bean继续在每个请求上重新创建新的有状态会话bean吗?

更新时间:2023-10-11 20:14:58

有状态会话bean(SFSB)并不完全是你的意思认为他们是。您似乎认为它们的行为类似于会话作用域的JSF托管bean。这是不真实的。 EJB中的术语会话与您考虑过的HTTP会话具有完全不同的含义。

Stateful session beans (SFSB) are not exactly what you think they are. You seem to think that they behave somehow like session scoped JSF managed beans. This is untrue. The term "session" in EJBs has an entirely different meaning than the HTTP session which you've had in mind.

EJB中的会话必须在事务上下文中解释。只要客户端存在,事务(基本上,数据库会话)就存在于SFSB的情况下。 SFSB的客户端在您的特定示例而不是 webbrowser,但是JSF托管bean实例本身,恰好是注入SFSB的实例。由于您已将JSF托管bean放在请求范围中,因此将在每个HTTP请求上与JSF托管bean一起重新创建SFSB。

The "session" in EJBs must be interpreted in transactional context. The transaction (basically, the DB session) lives in case of SFSB as long as the client lives. The SFSB's client is in your particular example not the webbrowser, but the JSF managed bean instance itself, exactly the one where the SFSB is been injected. Since you have put the JSF managed bean in the request scope, the SFSB will be recreated on every HTTP request together with the JSF managed bean.

作为示例,尝试将JSF托管bean放在视图范围内。例如,视图范围对于同一页面上的多步骤表单非常有用。每当视图回发到自身时,那么将重用相同的JSF托管bean实例,并且此实例允许您访问SFSB的相同实例,就像创建bean时一样,这是不在别处分享。只要客户端(视图作用域的JSF托管bean)存在,SFSB事务就会存在。

As an example, try to put the JSF managed bean in the view scope. The view scope is useful for a multi-step form on the same page, for example. Everytime when the view postbacks to itself, then the same JSF managed bean instance will be reused and this instance gives you access to the same instance of the SFSB as it is when the bean was created, which is not shared elsewhere. The SFSB transaction lives as long as the client (the view scoped JSF managed bean) lives.

无状态会话bean(SLSB)可以在别处共享,但那不应该'无论如何,因为它意图被视为无国籍。这个功能节省了容器时间和内存来创建和存储它们。容器可以只有一个池。更重要的是,在视图,会话或应用程序范围内的JSF托管bean中注入的SLSB实例不一定需要在每个HTTP请求中引用与在JSF托管bean创建期间完全相同的实例。它甚至可以是完全不同的实例,具体取决于容器池中的可用实例。只要对SLSB上的单个方法调用,事务就会生效(默认情况下)。

A stateless session bean (SLSB) can be shared elsewhere, but that shouldn't matter as it's intented to be treated as stateless anyway. This "feature" saves the container time and memory to create and store them. The container can just have a pool of them. Even more, the SLSB instance which is been injected in a view, session or application scoped JSF managed bean does not necessarily need to refer exactly the same instance on every HTTP request as it was during JSF managed bean's creation. It can even be a completely different instance, depending on the available instances in the container's pool. The transaction lives (by default) as long as a single method call on the SLSB.

这就是说,SFSB不适合您记住已记录 - 的特定情况在用户。它更安全真的没有意义。只需将JSF托管bean放在会话范围内,让它自己记住登录用户,并使用SLSB执行任何业务操作(例如与数据库交互),并仅在需要真正的有状态会话bean(我假设您现在了解它们究竟是什么:) :)。

That said, a SFSB is unsuitable for your particular case of "remembering a logged-in user". That it's "more secure" makes really no sense. Just put the JSF managed bean in the session scope and let it remember the logged-in user by itself and make use of a SLSB to do any business actions (such as interacting with the DB) and use SFSB only when you want a real stateful session bean (I assume that you now understand what exactly they are :) ).

  • When is it necessary or convenient to use Spring or EJB3 or all of them together?
  • Why Stateless session beans?
  • JSF Service Layer