0

这个问题毫无疑问,实际上是一个提示。

您是否知道会话 EJB 在每次业务方法调用之前重新注入所有依赖项?好吧,直到几分钟前我才知道,这让我很头疼。

我认为依赖注入只发生在实例的创建中,但事实并非如此。EJB 3.1 规范说:

“如果会话 bean 使用依赖注入,则容器会在创建 bean 实例之后以及在 bean 实例上调用任何业务方法之前注入这些引用。” 第 4.3.2 节

不知何故,这个定义可以赋予无状态会话 Bean 具有会话状态的能力,这正是我所需要的。例如,如果您在 SLSB 中注入一个 @SessionScoped bean,而与您的请求处理的池实例无关,那么 SessionScoped bean 将始终符合当前客户端的会话。换句话说,SLSB 实例不可能拥有另一个客户端的 SessionScoped bean。

如果两个用户交替使用相同的 SLSB 实例,这使得 SLSB 通过 @Inject 接收登录用户作为实例字段而不会导致任何问题。例如:

@Stateless
public class StatelessSessionBean{
    @Inject
    @LoggedInUser
    protected User loggedInUser;//@SessionScoped

    public void test(){
        System.out.println("ejb:"+this);
        System.out.println("user:"+this.loggedInUser);
    }
}

然后,“test”方法的各种调用的结果是这样的:

User 1 invoke
17:02:20,800 INFO  [stdout] (http--0.0.0.0-8080-5) ejb:AccessControlBean@406189
17:02:20,801 INFO  [stdout] (http--0.0.0.0-8080-5) user:User 1

User 2 invoke
17:02:56,227 INFO  [stdout] (http--0.0.0.0-8080-8) ejb:AccessControlBean@406189
17:02:56,228 INFO  [stdout] (http--0.0.0.0-8080-8) user:User 2

User 2 invoke
17:03:24,376 INFO  [stdout] (http--0.0.0.0-8080-8) ejb:AccessControlBean@406189
17:03:24,378 INFO  [stdout] (http--0.0.0.0-8080-8) user:User 2

User 1 invoke
17:03:24,517 INFO  [stdout] (http--0.0.0.0-8080-6) ejb:AccessControlBean@1c05227
17:03:24,518 INFO  [stdout] (http--0.0.0.0-8080-6) user:User 1

User 1 invoke
17:04:24,045 INFO  [stdout] (http--0.0.0.0-8080-1) ejb:AccessControlBean@406189
17:04:24,047 INFO  [stdout] (http--0.0.0.0-8080-1) user:User 1

User 2 invoke
17:04:24,179 INFO  [stdout] (http--0.0.0.0-8080-8) ejb:AccessControlBean@1c05227
17:04:24,179 INFO  [stdout] (http--0.0.0.0-8080-8) user:User 2

请注意,即使调用相同的实例,字段“loggedInUser”也会根据调用该方法的用户而正确地变化。

4

0 回答 0