java - 从 EJB 无状态 session bean 调用 CDI session 范围的生产者方法

标签 java jakarta-ee cdi

我想使用 @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/

相关文章:

java - 用于针对 Java servlet 进行身份验证的非 Java Web 应用程序

Java EE 单例反射注入(inject)

java正则表达式检查日期格式

java - 无法解析配置 ':app:_debugApkCopy' 的所有依赖项。找不到 com.google.android.gms :play-services-appindexing:10. 0.1

java - 为什么Spring Bean能够在Tomcat Servlet容器中运行而EJB却不能?

java - 在 CDI 中生成可选 Bean

java - 向 jList Java 添加组件

java - 每个类的表继承:获取空值

java - 如何将带有 CDI 的 @Alternative 从 WAR 注入(inject)到 EJB 模块中

java - 如何使用 java cdi 在非默认类上使用限定符