Java 从EJB无状态会话bean调用CDI会话范围的生产者方法
我想使用Java 从EJB无状态会话bean调用CDI会话范围的生产者方法,java,jakarta-ee,cdi,Java,Jakarta Ee,Cdi,我想使用@inject@current user跨所有层(即web层、EJB层)注入当前用户。为此,我采用了以下CDI生产者方法: @Named @SessionScoped public class UserController { @Resource SessionContext sessionContext; @EJB UserDao userDao; @Produces @Current public User getCurrentUser() { S
@inject@current user
跨所有层(即web层、EJB层)注入当前用户。为此,我采用了以下CDI生产者方法:
@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{}
现在,我想将当前用户注入EJB无状态会话bean,如下所示:
@Stateless
public class SomeBackendService {
@Inject @Current
private User user;
}
我的问题:当前用户对象是否总是在会话更改后重新注入,因为无状态会话bean的依赖项通常在创建时注入一次,并且该bean可能会在不同的会话中汇集和使用?尽管我没有尝试过这种确切的情况,在CDI中,豆子通常不会重新注入。相反,将插入一个知道其上下文的代理 通过这种机制,可以在应用程序范围的bean中注入会话范围的bean。应用程序范围bean的每个用户都会访问同一个bean和同一个代理,但是代理会为每个用户动态地将对它的调用解析为不同的bean 因此,即使
@Stateless
的作用域基本上是“应用程序”,在您的“SomeBackendService”中代表用户的代理仍有可能委托给正确的会话作用域版本
p、 美国
如果层实际上指的是web中的模块和作为EAR一部分的EJB模块,那么它会稍微复杂一点,因为CDI在模块之间并不总是像预期的那样工作(特别是在JBoss as中)。这部分是由于“应用程序”的含义不明确,因此应用程序范围在EAR中。根据设计,无状态会话bean不应该有状态“User”,它无论如何都是无状态的
如果您希望EJB具有状态,那么请改用@Stateful。是的,对于每个称为容器的业务方法,将重新注入SLSB的所有依赖项。以下是EJB 3.1规范中保证这一点的文本:
“如果会话bean使用依赖注入,那么容器会在创建bean实例之后,在对bean实例调用任何业务方法之前,注入这些引用。”-第4.3.2节
我也有这种怀疑,我贴了一个问题来解释这种情况
完全忘记了代理。我试过了,效果如预期。谢谢