CDI生成实例在运行时创建

时间:2017-04-05 05:37:04

标签: java java-ee cdi

我是cdi生产者模式的新手,到目前为止,我已经看到了在类的初始化点生成简单内容的示例。现在我必须生成一个在运行时创建的实例,并填充一些也在运行时发生的数据。这是我目前的方法,但对我来说它不是很好......有更好的方法,所以请帮我解决一些模式和做法

 public class myBean {
 private DataHolder dataHolder;

  @Produces
  public DataHolder {
   // dataHolder is null until I later init instance 
   return dataHolder;
  }
}

在我的代码中的某个时刻,我将dataHolder设置为新的istance并允许进一步注入以通过执行此操作来使用运行时数据:

dataHolder = new DataHolder(data1, data2, data3);

看起来有点吱吱:)有更好的方法吗?还是制作cdi东西的好模式?

2 个答案:

答案 0 :(得分:2)

你的方法确实很笨拙,因为如果在初始化之前任何时候注入DataHolder,它将返回null(如果你产生@Dependent个对象)甚至崩溃(与任何其他范围)。

我建议您在CDI specWeld doc中阅读有关制作人方法的内容。

现在,我接受了这个。最干净的方法是让生产者的身体每次完成所有创造工作。这意味着:

  1. 向生产者方法添加参数(注意:它们必须是可注射的豆类)
  2. DataHolder课程中创建MyBean所需的参数,因为它已经创建并阅读它们(它们必须始终可供制作人使用)
  3. 将检索这些参数所需的逻辑放入生产者方法
  4. 如果您坚持返回@Dependent bean,则允许您的制作人返回null - 如果您愿意,可以使用它。然后,注入点可以期望可能的空值,其可以被解释为“尚未初始化”。或者,如果您需要不同的范围(@ApplicationScoped@RequestScoped,...),则可能更容易创建DataHolder的第二个虚拟实现,这将再次表示“尚未实现”。

    旁注: CDI中任何手动创建的对象(例如使用new会自动解决注入点。这意味着,如果您在使用DataHolder创建DataHolder本身时将任何注入 new,则会null

答案 1 :(得分:0)

一种方法是:

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder) 
{
   return dataHolder;      
}

另一种方法是使用你得到的作为生产者方法的信息,例如InjectionPoint或你进入它的其他东西。

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder, InjectionPoint injectionPoint, ClassA a, ClassB b) 
{
   String stringA = a.function();
   dataHolder.someFunction(stringA);
   return dataHolder;      
}

我用最后一种方法用我需要的东西创建我的设备,不需要做任何其他事情。 可以在以下找到一些资源来查看它 byteslounge.comJboss docs

编辑:我很难找到这些信息,但是CDI制作人的工作方式就是你所声明的所有参数例如:getCoder将在通话时注入。因此,您可以注入可以帮助您在运行时收集信息的服务。