I am new to CDI and I have an issue which is a bit hard to explain but lets give it a try. I would like to have a cdi producer which produces a request scoped instance of a class called RequestData like here for example (its pseudo-code):
public class MyBean {
private RequestData dataHolder;
@Produces
@RequestScoped
public RequestData getData() {
return dataHolder;
}
}
I know that this cdi producer produces an instance which "lives" in wildfly application server as long as the request context is there (as long the request lasts, lets call it request-singleton instance thingy)
Now I would like to have that RequestData class includes futher cdi producers. Like in this example (again java pseudo-code):
public class RequestData {
private Something1 param1;
private Something2 param2;
...
@Produces
public Something1 getParam1(){
return param1;
}
@Produces
public Something2 getParam2(){
...
}
}
The final question of my issue is how can I force param1 and param2 to be produced from the request-singleton instance in MyBean (what java code / annotations or whatever do I need)?
To sum up MyBean produces RequestData and RequestData is alive the whole request time and futhermore it shall produce param1, param2.
Here some example of a class injecting param1
public class Stuff{
@Inject
public void startup(Something1 param1){
// param1 shall come from MyBean.getData().getParam1()
}
}
Any ideas how to achive this? How to have cdi engine do the MyBean.getData().getParam1() for param1?
This is the wrong approach. CDI is a very powerful injection framework. How you use it for injection depends on how much you understand it.
For this case, it is far easier to use Instance
lazy injection as follows:
@ApplicationScoped //No need to be request scope, CDI is quite smart
public class RequestContextProvider {
@Inject
private HttpServletRequest servletRequest;
@Produces
@Dependent //Make dependent if it can be null, if you are sure it cannot be, just declare it as RequestScoped
public SomethingData createSomethingData(InjectionPoint ip) {
String requestParam = servletRequest.getParameter("something-data");
if(requestParam == null) {
return null;
}
return initSomethingData(requestParam);
}
}
The usage will look something like this:
@RequestScoped //Or whichever scope
public class StuffService {
@Inject
private Instance<SomethingData> somethingData;
public void doStuff() {
//You need to take care here, that the somethingData.get() may return null
somethingData.get().soSomething();
}
}