在JEE

时间:2017-04-15 07:48:01

标签: java-ee polymorphism cdi producer

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

我有一个Controller类,当调用启动时,应该根据参数使用Producer注入有状态bean。这个提到的有状态bean本身包含一个注入的bean。

说实话,不确定这是否有效,任何反馈都非常赞赏=)

这是一些虚拟代码,应该有助于理解我想要做的事情(基于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为null。我怎样才能将其投入使用?

BR和THX! 斯蒂芬

1 个答案:

答案 0 :(得分:1)

好吧,让我们退一步看看吧。 首先,不要自己调用生产者。让CDI完成工作,然后继续告诉它注入的位置。您的Controller 可能看起来像这样(但可能不会,您的帖子中存在多处误解)。

@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 就可以控制创建,因此无法注入任何内容!这是null来自的地方。

现在,如果你有一个制片人......

1)必须将它放在bean类中(假设这没关系)

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

3)生产者通常通过new创建实例,因此CDI无法注入任何内容。如果需要,您可能需要研究另一种方法(生成器通常用于将非CDI对象转换为bean因此,他们不需要注入生产的豆类。)

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

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