Reputation: 139
I am new to cdi producer pattern and so far I have seen examples producing simple content already known at initialization point of a class. Now I have to produce an instance created at runtime and filled with some data which also happens at runtime. Here is my current approach but to me it aint that good... Is there a better approach so please help me out with some patterns and practices
public class myBean {
private DataHolder dataHolder;
@Produces
public DataHolder {
// dataHolder is null until I later init instance
return dataHolder;
}
}
At some point in my code I set the dataHolder to new istance and allow futher injections to use runtime data by doing this:
dataHolder = new DataHolder(data1, data2, data3);
That looks kinda cheep :) is there a better way? or a nice pattern for producing cdi stuff?
Upvotes: 1
Views: 1313
Reputation: 6753
Your approach is indeed clumsy because if there is an injection of DataHolder
any time before you initialize it - it will return null
(if you produce a @Dependent
object) or even crash (with any other scope).
I suggest you do some reading on Producer methods either in CDI spec or Weld doc.
Now, my take on this. The cleanest approach would be to let the body of the producer work do all the creation job every time. That means either:
DataHolder
in your MyBean
class ever since it's creation and read them (they have to be available to producer at all times)If you stick with returning a @Dependent
bean, your producer is allowed to return null
- you can make use of that if you so wish. The injection point can then expect a possible null value which can be interpreted as 'not yet initialized'. Or, if you need different scope (@ApplicationScoped
, @RequestScoped
, ...) then it's probably easier to create a second dummy implementation of DataHolder
which will, again, mean 'not yet implemented'.
Side note: Any manually created object (e.g. using new
) in CDI will not have it's injection points resolved automatically. That means, if you inject anything into DataHolder
while creating the DataHolder
itself using new
, there will be null
.
Upvotes: 2
Reputation: 1803
One way would be to do this:
@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder)
{
return dataHolder;
}
another way would be to use what you get as informations for the producer method, such as the InjectionPoint or what else you reach into it.
@Produces
@RequestScoped
public Coder getCoder(@New DataHolder dataHolder, InjectionPoint injectionPoint, ClassA a, ClassB b)
{
String stringA = a.function();
dataHolder.someFunction(stringA);
return dataHolder;
}
I used the last method to create my device with everything I need and need to do nothing else. Some resources to look at it can be found at byteslounge.com and Jboss docs
EDIT: The information was quite hard to find for me, but a CDI Producer works in the way that everything you declare as parameter for e.g: getCoder will be injected at call-time. So you can inject services that can help you to collect information at runtime.
Upvotes: 0