Java CDI生成在运行时创建的实例

Java CDI生成在运行时创建的实例,java,jakarta-ee,cdi,Java,Jakarta Ee,Cdi,我是cdi生产者模式的新手,到目前为止,我已经看到了一些例子,它们产生了在类的初始化点已经知道的简单内容。现在我必须生成一个在运行时创建的实例,并填充一些在运行时也会发生的数据。这是我目前的做法,但对我来说并不是那么好。。。是否有更好的方法,请帮助我了解一些模式和实践 public class myBean { private DataHolder dataHolder; @Produces public DataHolder { // dataHolder is null

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

 public class myBean {
 private DataHolder dataHolder;

  @Produces
  public DataHolder {
   // dataHolder is null until I later init instance 
   return dataHolder;
  }
}
在我的代码中的某个时刻,我将数据持有者设置为新的istance,并通过以下操作允许进一步的注入使用运行时数据:

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

这看起来有点傻:)有更好的办法吗?还是一种制作cdi材料的好模式?

一种方法是:

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder) 
{
   return dataHolder;      
}
另一种方法是将您获得的信息用作生产者方法的信息,例如注入点或您在其中获得的其他信息

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder, InjectionPoint injectionPoint, ClassA a, ClassB b) 
{
   String stringA = a.function();
   dataHolder.someFunction(stringA);
   return dataHolder;      
}
我使用最后一种方法创建了我的设备,它包含了我所需要的一切,并且不需要做任何其他事情。 有关这方面的一些资源,请访问 和


编辑:我很难找到这些信息,但CDI生产者的工作方式是,您声明为参数的所有内容(例如:getCoder)都将在调用时注入。因此,您可以注入服务,帮助您在运行时收集信息。

一种方法是:

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder) 
{
   return dataHolder;      
}
另一种方法是将您获得的信息用作生产者方法的信息,例如注入点或您在其中获得的其他信息

@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder, InjectionPoint injectionPoint, ClassA a, ClassB b) 
{
   String stringA = a.function();
   dataHolder.someFunction(stringA);
   return dataHolder;      
}
我使用最后一种方法创建了我的设备,它包含了我所需要的一切,并且不需要做任何其他事情。 有关这方面的一些资源,请访问 和


编辑:我很难找到这些信息,但CDI生产者的工作方式是,您声明为参数的所有内容(例如:getCoder)都将在调用时注入。因此,您可以注入可以帮助您在运行时收集信息的服务。

您的方法确实很笨拙,因为如果在初始化之前的任何时间注入
数据持有者
,它将返回
null
(如果您生成一个
@依赖的
对象),甚至崩溃(使用任何其他作用域)

我建议您在或中阅读一些生产者方法

现在,我来谈谈我的看法。最干净的方法是让制作人的主体每次都做所有的创作工作。这意味着:

  • 向producer方法添加参数(注意:它们必须是可注入bean)
  • MyBean
    类中创建
    DataHolder
    所需的参数,并从创建开始读取这些参数(生产者必须随时可用)
  • 将检索这些参数所需的逻辑放入producer方法
  • 如果您坚持返回一个
    @Dependent
    bean,那么您的生产者可以返回
    null
    ——如果您愿意,您可以使用它。然后,注入点可以期望一个可能的空值,该空值可以解释为“尚未初始化”。或者,如果您需要不同的作用域(
    @ApplicationScoped
    @RequestScoped
    ,…),那么可能更容易创建数据持有者的第二个虚拟实现,这同样意味着“尚未实现”


    旁注:任何在CDI中手动创建的对象(例如使用
    新建
    )都不会自动解析其注入点。这意味着,如果您在使用
    new
    创建
    DataHolder
    本身时向
    DataHolder
    中注入任何内容,那么将出现
    null
    ,您的方法确实很笨拙,因为如果在初始化之前的任何时候注入
    DataHolder
    ,它将返回
    null
    (如果生成一个
    @依赖的
    对象)或甚至崩溃(使用任何其他作用域)

    我建议您在或中阅读一些生产者方法

    现在,我的观点是。最干净的方法是让制作人的作品主体每次都做所有的创作工作。这意味着:

  • 向producer方法添加参数(注意:它们必须是可注入bean)
  • MyBean
    类中创建
    DataHolder
    所需的参数,并从创建开始读取这些参数(生产者必须随时可用)
  • 将检索这些参数所需的逻辑放入producer方法
  • 如果您坚持返回一个
    @Dependent
    bean,那么您的生产者可以返回
    null
    ——如果您愿意,您可以使用它。然后注入点可以期望一个可能的null值,该值可以解释为“尚未初始化”。或者,如果您需要不同的作用域(
    @ApplicationScoped
    @RequestScoped
    ,…)然后可能更容易创建数据持有者的第二个虚拟实现,这同样意味着“尚未实现”


    旁注:任何手动创建的对象(例如,使用
    新建
    )在CDI中,不会自动解析它的注入点。这意味着,如果在使用
    new
    创建
    DataHolder
    本身时,向
    DataHolder
    中注入任何内容,则会出现
    null

    @new
    被弃用,因为CDI 1.1-我强烈建议不要这样做。它被重放了由
    @Dependent
    @New
    制作的ced被弃用,因为CDI 1.1-我强烈反对。它被
    @Dependent
    取代。嗨,谢谢你的回答。但是我想知道,有没有可能让制作人制作一个实例,进一步制作一些其他东西?我想你会
    >否决
    o类对于您生成的实例,则不能再作为此类的生产者(CDI将不会获取该实例)