Java CDI生成在运行时创建的实例
我是cdi生产者模式的新手,到目前为止,我已经看到了一些例子,它们产生了在类的初始化点已经知道的简单内容。现在我必须生成一个在运行时创建的实例,并填充一些在运行时也会发生的数据。这是我目前的做法,但对我来说并不是那么好。。。是否有更好的方法,请帮助我了解一些模式和实践Java CDI生成在运行时创建的实例,java,jakarta-ee,cdi,Java,Jakarta Ee,Cdi,我是cdi生产者模式的新手,到目前为止,我已经看到了一些例子,它们产生了在类的初始化点已经知道的简单内容。现在我必须生成一个在运行时创建的实例,并填充一些在运行时也会发生的数据。这是我目前的做法,但对我来说并不是那么好。。。是否有更好的方法,请帮助我了解一些模式和实践 public class myBean { private DataHolder dataHolder; @Produces public DataHolder { // dataHolder is null
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
(如果您生成一个@依赖的
对象),甚至崩溃(使用任何其他作用域)
我建议您在或中阅读一些生产者方法
现在,我来谈谈我的看法。最干净的方法是让制作人的主体每次都做所有的创作工作。这意味着:
MyBean
类中创建DataHolder
所需的参数,并从创建开始读取这些参数(生产者必须随时可用)@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将不会获取该实例)