我想使用 @Inject @Current User
跨所有层(即 web 层、EJB 层)注入(inject)当前用户。为此,我有以下 CDI Producer 方法:
@Named
@SessionScoped
public class UserController {
@Resource SessionContext sessionContext;
@EJB UserDao userDao;
@Produces @Current
public User getCurrentUser() {
String username = sessionContext.getCallerPrincipal().getName();
User user = userDao.findByUsername(username);
}
}
@Qualifier
@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface Current{}
现在,我想将当前用户注入(inject)到一个 EJB 无状态 session bean 中,如下所示:
@Stateless
public class SomeBackendService {
@Inject @Current
private User user;
}
我的问题:当前用户对象是否总是在 session 更改后重新注入(inject),因为无状态 session bean 的依赖项通常在创建时注入(inject)一次,并且该 bean 可能被合并并跨不同的 session 使用?
最佳答案
虽然我没有尝试过这种确切的情况,但在 CDI 中通常不会重新注入(inject) bean。相反,注入(inject)了一个知道其上下文的代理。
通过这种机制,可以在应用程序范围的 bean 中注入(inject) session 范围的 bean。应用程序作用域 bean 的每个用户都访问相同的 bean 和相同的代理,但代理随后会动态地将对它的调用解析为每个用户的不同 bean。
因此,即使 @Stateless
的范围基本上是“应用程序”,在您的“SomeBackendService”中代表 User
的代理仍然有可能委托(delegate)给正确的 session 范围版本。
附:
如果使用层,您实际上是指 Web 中的模块和作为 EAR 一部分的 EJB 模块,它会稍微复杂一些,因为 CDI 并不总是按预期工作模块(尤其是在 JBoss AS 中)。这部分是由于“应用程序”以及应用程序范围在 EAR 中的含义不明确。
关于java - 从 EJB 无状态 session bean 调用 CDI session 范围的生产者方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6973028/