我是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! 斯蒂芬
答案 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
。这应该给你足够的多功能性和动态分辨率。