我是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东西的好模式?
答案 0 :(得分:2)
你的方法确实很笨拙,因为如果在初始化之前任何时候注入DataHolder
,它将返回null
(如果你产生@Dependent
个对象)甚至崩溃(与任何其他范围)。
我建议您在CDI spec或Weld doc中阅读有关制作人方法的内容。
现在,我接受了这个。最干净的方法是让生产者的身体每次完成所有创造工作。这意味着:
DataHolder
课程中创建MyBean
所需的参数,因为它已经创建并阅读它们(它们必须始终可供制作人使用)如果您坚持返回@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.com 和 Jboss docs
编辑:我很难找到这些信息,但是CDI制作人的工作方式就是你所声明的所有参数例如:getCoder将在通话时注入。因此,您可以注入可以帮助您在运行时收集信息的服务。