在JEE中使用生产者和多态与CDI添加有状态bean [英] Add a stateful bean using a producer and polymorphism with CDI in JEE

查看:163
本文介绍了在JEE中使用生产者和多态与CDI添加有状态bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm really new to JEE CDI but tried half of last night to find a solution to a problem.

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

I have a Controller Class that, when startup is called, should inject a stateful bean using a Producer depending on a parameter. This mentioned stateful bean itself contains an injected bean itself.

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

To be honest, not sure if this works at all, any feedback is highly appreciated=)

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

Here is some dummy code that should help understand what I want to do (based oin https://docs.jboss.org/weld/reference/1.0.0/en-US/html/producermethods.html). Probably I totally messed up a lot of stuff now... but I was not able to find an example how this kind of problem can be solved or I was not able to understand it=/

控制器(主要服务)

@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接口

IEngine interface for polymorphism

public interface IEngine 
{
    void startUp();
}

以下是EngineA的示例,EngineB很简单

Here is an Example of EngineA, EngineB is simuliar

@Stateful
public class EngineA implements IEngine
{

    @Inject
    private CoinManager cm;

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

不幸的是,即使工作,这也不允许我在EngineA中使用@injection。实际上,EngineA中的cm为null。我该如何使用它?

Unfortunately this, even if working, is not allowing me to use @injection in EngineA. In fact, cm in EngineA is null. How can I bring this to work?

BR和THX!
Stefan

BR and THX! Stefan

推荐答案

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

Alright, let's take a step back and look at it. Firstly, do not invoke producers yourself. Let CDI do the job and just go ahead and tell it where to inject it. Your Controller could look like this (but it probably won't, there are multiple misunderstanding in your 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 就可以控制创建,因此无法注入任何内容!这是你的 null 来自的地方。

With CDI, you want to avoid creating instances via new when possible. The reason is, once you yourself create an instance, CDI does not have control over creation and hence cannot inject anything into it! This is where your null comes from.

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

Now, if you have a producer...

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

1) It has to be placed in a bean class (assuming this is OK)

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

2) Any parameter of producer method has to be injectable

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

3) Producers usually do create instances via new, therefore CDI cannot inject anything in. If you need that, you might want to look into another approach (producers are often used to turn non-CDI objects into bean, therefore they have no need for injection into produced beans).

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

Your producer has a parameter int typeID meaning for CDI to even be able to call and instantiate anything via this method, it needs to have this injectable (for int you would need another producer I imagine). Or, you could place a logic retrieving that typeID directly inside producer method instead of passing it as param.

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

To sum up, the approach you will want to take depends on how and when do you retrieve your int typeID and if it can change during runtime. In any case I would suggest you drop producer method and instead take a look at Instance<?> in combination with @Qualifier. That should give you enough versatility and dynamic resolution.

这篇关于在JEE中使用生产者和多态与CDI添加有状态bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆