Jakarta ee 编程会话查找

Jakarta ee 编程会话查找,jakarta-ee,cdi,lookup,conversation-scope,Jakarta Ee,Cdi,Lookup,Conversation Scope,只有知道当前线程是用于处理与所需对话相关的CDI请求的线程,才能通过编程方式获得CDI对话实例吗?如果可能的话,怎么做 特别是,我想做的是: @ConversationScoped public class UnitOfWork {...} public class Client { @Inject transient UnitOfWork uof; ... } public class Room { @Inject transient UnitOfWork uof; ...

只有知道当前
线程
是用于处理与所需对话相关的
CDI请求的线程,才能通过编程方式获得
CDI对话
实例吗?如果可能的话,怎么做

特别是,我想做的是:

@ConversationScoped
public class UnitOfWork {...}

public class Client {
    @Inject transient UnitOfWork uof;
...
}

public class Room {
    @Inject transient UnitOfWork uof;
...
}
但是使用编程机制初始化
uof
实例变量,而不是应用@Inject注释(因为
Client
Room
是实体,它们不支持注入)。
我已经尝试通过以下静态方法获得的
BeanManager
注入
UnitOfWork

public static <B> B getManagedBean(Class<B> type, Annotation... qualifiers) {
    try {
        BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
        Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers);
        Bean<B> bean = (Bean<B>) beanManager.resolve(beans);
        CreationalContext<B> cc = beanManager.createCreationalContext(bean);
        return bean.create(cc);
    } catch (NamingException e) {
        throw new RuntimeException("", e);
    }
}
publicstaticbgetmanagedbean(类类型、注释…限定符){
试一试{
BeanManager BeanManager=InitialContext.doLookup(“java:comp/BeanManager”);

设置对不起,不是真正的答案,但在评论中写的太多了:

实体不支持依赖注入是有原因的,主要是因为它们的生命周期与托管bean的生命周期是解耦的


虽然我确实在实体中看到了DI的用例,但我还是会仔细检查这种方法的好处是否大于风险。您可能会发现自己在某种二级缓存地狱中破解了持久性上下文;)

答案非常接近,但我忽略了它。 是的,可以通过BeanManager获取任何活动上下文(与当前线程关联的上下文)包含的任何bean的bean类实例。 此方法执行以下操作:

public static <B> B getContextualBeanInstance(Class<B> type, Annotation... qualifiers) {
    try {
        BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
        Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers);
        Bean<?> bean = beanManager.resolve(beans);
        CreationalContext<?> cc = beanManager.createCreationalContext(bean);
        return (B) beanManager.getReference(bean, type, cc);
    } catch (NamingException e) {
        throw new RuntimeException("", e);
    }
}
publicstaticbgetContextalBeanistance(类类型、注释…限定符){
试一试{
BeanManager BeanManager=InitialContext.doLookup(“java:comp/BeanManager”);
Set bean=beanManager.resolve(bean);
CreationalContext cc=beanManager.createCreationalContext(bean);
return(B)beanManager.getReference(bean,type,cc);
}捕获(NamingE例外){
抛出新的运行时异常(“,e);
}
}
与我在问题帖中提到的方法的唯一区别是,这个方法使用
BeanManager\getReference(..)
而不是
Bean\create(..)

如果要支持参数化bean类型,请将
type
参数的类型从
Class
更改为
type


如果bean是@Dependent作用域,您应该注意销毁bean类实例以避免内存泄漏。我将解释如何很好地做到这一点。

如果所有注入的属性都是瞬态的,您提到的风险是否适用?这只是一个方面。我认为最大的问题在于您对c没有太多的控制或影响实体的创建/缓存/序列化。这对于您的用例来说是可以的,但如果不可能是错误的话,肯定会让人困惑。
@Entity
类的实例仍然是由持久性单元通过
javax.persistence.Query
实例等以标准方式创建的它们不是简单的POJO,而是具有行为的对象。注入的属性都是瞬时的,在服务定位器的帮助下懒散地初始化。y需要解决的问题是在服务定位器内部。我需要它能够获得与请求相关联的
会话的实例,该请求是服务定位器的所有者当前
线程
。我知道实体本身将缺少CDI的好处,但注入的依赖项不会。因此,当实体必须执行需要CDI的操作时,它会将此功能委托给注入的对象。我缺少什么吗?