在 JEE 中使用 CDI 使用生产者和多态性添加有状态 bean

Add a stateful bean using a producer and polymorphism with CDI in JEE

我是 JEE CDI 的新手,但昨晚尝试了一半以找到问题的解决方案。

我有一个控制器 Class,当调用启动时,它应该根据参数使用生产者注入有状态 bean。这个提到的有状态 bean 本身包含一个注入的 bean。

老实说,不确定这是否有效,非常感谢任何反馈=)

这是一些虚拟代码,应该有助于理解我想要做什么(基于 oin https://docs.jboss.org/weld/reference/1.0.0/en-US/html/producermethods.html)。可能我现在完全搞砸了很多东西......但是我找不到如何解决这种问题的例子或者我无法理解它=/

控制器(主要服务)

@Singleton
@Startup
public class Controller
{

    private IEngine engine;

    @PostConstruct
    private void startup(int typeID) 
    {
        Factory f = new Factory();
        engine = f.getEngine(typeID)
    }

 }

工厂

public class Factory
{
    @Produces
    public IEngine getEngine(int typeID) 
    {
        if(typeID==1)
        {
          return new EngineA();
        }    
        else
        {
          return new EngineB();
        }

    }

用于多态的 IEngine 接口

public interface IEngine 
{
    void startUp();
}

这里是EngineA的例子,EngineB类似

@Stateful
public class EngineA implements IEngine
{

    @Inject
    private CoinManager cm;

    //@Override
    public void startUp() 
    {
      cm.doSomeThing();
    }
}

不幸的是,即使有效,也不允许我在 EngineA 中使用 @injection。事实上,EngineA 中的 cm 为空。我怎样才能让它发挥作用?

BR 和 THX! 斯特凡

好吧,我们退一步来看。 首先,不要自己调用生产者。让 CDI 完成这项工作,然后继续告诉它在哪里注入它。你的Controller可能看起来像这样(但它可能不会,你的post中有很多误解)。

@Singleton
@Startup
public class Controller
{
    @Inject // just tell CDI to give you this
    // it won't be this easy here, but it is just to give you an idea
    private IEngine engine;

}

使用 CDI,您希望尽可能避免通过new创建实例。原因是,一旦您自己创建了一个实例,CDI not 就可以控制创建,因此无法向其中注入任何东西!这就是您的 null 的来源。

现在,如果您有制作人...

1)它必须放在一个bean中class(假设这样就OK)

2) 生产者方法的任何参数都必须是可注入的

3) 生产者通常通过 new 创建实例,因此 CDI 无法注入任何东西。如果您需要,您可能需要研究另一种方法(生产者通常用于将非 CDI 对象到 bean 中,因此他们不需要注入到生产的 bean 中)。

你的生产者有一个参数 int typeID 意味着 CDI 甚至能够通过这个方法调用和实例化任何东西,它需要有这个可注入的(我想对于 int 你需要另一个生产者)。或者,您可以将检索 typeID 的逻辑直接放在生产者方法中,而不是将其作为参数传递。

总而言之,您要采用的方法取决于您检索 int typeID 的方式和时间,以及它是否可以在运行时更改。在任何情况下,我建议你放弃生产者方法,而是看看 Instance<?>@Qualifier 的结合。那应该给你足够的多功能性和动态分辨率。