2017-04-15 39 views
1

我对JEE CDI非常陌生,但是昨天尝试了一半来找到问题的解决方案。使用生产者和多态性添加一个有状态bean,并在JEE中使用CDI

我有一个控制器类,当调用启动时,应根据参数使用生产者注入一个有状态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是simuliar

@Stateful 
public class EngineA implements IEngine 
{ 

    @Inject 
    private CoinManager cm; 

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

不幸的,即使工作,没有让我在EngineA使用@injection。实际上,EngineA中的cm为空。我怎样才能使这个工作?

BR和THX! Stefan

回答

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类(假设这是OK)

2)生产方法的任何参数必须注射

3)生产者通常通过new创建实例,因此CDI不能注入任何东西。如果你需要这样做,你可能需要考虑另一种方法(生产者通常用于将非CDI对象转换为bean,因此他们不需要注入生产的豆类)。

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

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

相关问题