这个问题毫无疑问,实际上是一个提示。
您是否知道会话EJB在每次业务方法调用之前重新注入所有依赖项?好吧,直到几分钟前我才知道,这让我很头疼。
我认为依赖注入只发生在实例的创建中,但是,这不是事实。 EJB 3.1的规范说:
“如果会话bean使用依赖注入,容器会在创建bean实例之后,以及在bean实例上调用任何业务方法之前注入这些引用。”第4.3.2节
不知何故,这个定义可以为无状态会话Bean提供一个具有会话状态的能力,这正是我所需要的。例如,如果您在SLSB中注入@SessionScoped bean,而不管池的哪个实例处理您的请求,则SessionScoped bean始终将符合当前客户端的会话。换句话说,SLSB实例不可能拥有另一个客户端的SessionScoped bean。
这使得SLSB可以通过@Inject将记录的用户作为实例字段接收,如果两个用户交替使用相同的SLSB实例,则不会导致任何问题。例如:
@Stateless
public class StatelessSessionBean{
@Inject
@LoggedInUser
protected User loggedInUser;//@SessionScoped
public void test(){
System.out.println("ejb:"+this);
System.out.println("user:"+this.loggedInUser);
}
}
然后,“测试”方法的各种调用的结果是:
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”字段也会根据调用该方法的用户而有所不同。