Jakarta ee CDI1.2(WildFly 8.2),javax.enterprise.inject.Instance<;someface>;不获取不直接实现SomeFace的bean

Jakarta ee CDI1.2(WildFly 8.2),javax.enterprise.inject.Instance<;someface>;不获取不直接实现SomeFace的bean,jakarta-ee,dependency-injection,ejb,cdi,wildfly,Jakarta Ee,Dependency Injection,Ejb,Cdi,Wildfly,我已经在解决将bean实现注入到javax.enterprise.inject.Instance中的问题。我有两个bean(EJB单例),它们扩展了一个实现SomeFace的抽象类——请参见下面的场景 public interface SomeIFace { void doStuff(); } 然后有一个抽象类采用了SomeIFace,如下所示: public abstract class SomeAClass implements SomeIFace { @Resourc

我已经在解决将bean实现注入到
javax.enterprise.inject.Instance
中的问题。我有两个bean(EJB单例),它们扩展了一个实现SomeFace的抽象类——请参见下面的场景

public interface SomeIFace {

    void doStuff();
}
然后有一个抽象类采用了
SomeIFace
,如下所示:

public abstract class SomeAClass implements SomeIFace {

    @Resource
    private TimerService ts;

    public TimerService getTimerService() {
        return ts;
    }

    @Timeout
    public void timeout() {
        doStuff();
    }
}
@Singleton
@Startup
@TransactionManagement(TransactionManagementType.BEAN)
public class SomeClass extends SomeAClass {

    /**
     * {@inheritDoc}
     */
    @Override
    public void doStuff() {
        ...
    }
}
托管bean的实际实现扩展了抽象类
SomeAClass
,如下所示:

public abstract class SomeAClass implements SomeIFace {

    @Resource
    private TimerService ts;

    public TimerService getTimerService() {
        return ts;
    }

    @Timeout
    public void timeout() {
        doStuff();
    }
}
@Singleton
@Startup
@TransactionManagement(TransactionManagementType.BEAN)
public class SomeClass extends SomeAClass {

    /**
     * {@inheritDoc}
     */
    @Override
    public void doStuff() {
        ...
    }
}
然后在另一个类中,我想获得实现
SomeIFace
的所有托管bean的引用,即:

@Inject
@Any
private Instance<SomeIFace> beans;
@Inject
@任何
私有实例bean;
问题是
bean
是空的

当我再次显式地将
SomeIFace
添加到实现bean类(即
公共类SomeClass扩展SomeAClass实现SomeIFace
)时,
bean
不是空的,并且会出现一个引用

有人能解释一下,为什么我需要再次直接在bean实现上重复
SomeIFace
接口以使CDI 1.2正常工作吗?在以前的CDI版本中,它运行良好

提前谢谢你

吉里

更新:


这种奇怪的注入问题只发生在EJB单例bean中(
@javax.EJB.Singleton
)。当bean被
@javax.inject.Singleton
@javax.enterprise.context.ApplicationScoped
注释时,就不需要重复接口声明,bean被发现了。但是,
TimerService
不能注入到非EJB bean中

似乎新行为如中所述:

:托管bean的无限制bean类型集包含bean类、每个超类以及它直接或间接实现的所有接口。(...) :会话bean的无限制bean类型集包含bean的所有本地接口及其超级接口。如果会话bean没有接口视图,则不受限制的bean类型集包含bean类和所有超类。(……)

注意托管bean和会话bean的bean类型定义的差异

  • 对于托管(非EJB)bean,规范明确声明“所有直接或间接”实现的接口都是bean的bean类型。对我来说,这意味着
    SomeIFace
    (由
    SomeAClass
    实现,由
    SomeClass
    扩展)将是
    SomeClass
    的bean类型,如果
    SomeClass
    是托管(非EJB)bean
  • 对于会话(EJB)bean,规范在我看来有点模糊。然而,对我来说,“bean的所有本地接口”读起来就像接口
    SomeIFace
    只是EJB
    SomeClass
    的一种bean类型,如果
    SomeClass
    直接实现它(而不是只扩展
    SomeAClass
    ,后者反过来又实现
    SomeIFace
  • 但是还要注意,如果您将
    SomeIFace
    直接添加到
    SomeClass
    ,那么bean就不能再通过
    @injectsomeclass
    注入了!这就像只有在“会话bean没有接口视图”的情况下,bean类本身是bean类型——否则,只有“bean的所有本地接口及其超级接口”(以及
    java.lang.Object
    )是bean类型

因此,您观察到的行为符合规范。

似乎新行为如以下所述:

:托管bean的无限制bean类型集包含bean类、每个超类以及它直接或间接实现的所有接口。(...) :会话bean的无限制bean类型集包含bean的所有本地接口及其超级接口。如果会话bean没有接口视图,则不受限制的bean类型集包含bean类和所有超类。(……)

注意托管bean和会话bean的bean类型定义的差异

  • 对于托管(非EJB)bean,规范明确声明“所有直接或间接”实现的接口都是bean的bean类型。对我来说,这意味着
    SomeIFace
    (由
    SomeAClass
    实现,由
    SomeClass
    扩展)将是
    SomeClass
    的bean类型,如果
    SomeClass
    是托管(非EJB)bean
  • 对于会话(EJB)bean,规范在我看来有点模糊。然而,对我来说,“bean的所有本地接口”读起来就像接口
    SomeIFace
    只是EJB
    SomeClass
    的一种bean类型,如果
    SomeClass
    直接实现它(而不是只扩展
    SomeAClass
    ,后者反过来又实现
    SomeIFace
  • 但是还要注意,如果您将
    SomeIFace
    直接添加到
    SomeClass
    ,那么bean就不能再通过
    @injectsomeclass
    注入了!这就像只有在“会话bean没有接口视图”的情况下,bean类本身是bean类型——否则,只有“bean的所有本地接口及其超级接口”(以及
    java.lang.Object
    )是bean类型

因此,您观察到的行为符合规范。

Hmm听起来不正确。这些都是同一场战争吗?这里涉及到JAR文件吗?是的,所有的JAR文件都在同一场战争中,实际上在同一个JAR文件中也发生了Glassfish,并且发生在任何EJB上(单音或无状态),在我的测试期间,我能够注入实例bean,但是一旦我引入一个接口来定义本地视图,该bean不再出现在beans@Inject实例bean的列表中。解决这个问题的一种方法是直接用接口显式地标记EJB实现。这些都是同一场战争吗?这里有JAR文件吗?是的,都在