I want to implement a painting service using Java EE and JBoss Application Server.
Imagine a method called via an URL
http://mypaint.com/apply?image=1&action=line&from=10,10&to=100,10
which applies an action to the image with the id 1. The action is “draw a line from point (10,10) to point (100,10)”.
The “apply” method looks like this:
@Inject
private ImageProcessorServer processors
@GET
@Path("/apply")
public Response apply(
@QueryParam(value = "image") int imageId,
@QueryParam(value = "action") String action,
//some parameters more...
) {
… //check if user is allowed to access the image
ImageProcessor processor = processors.get(imageId);
//get image processor by image id
processor.apply(action/*, from, to*/);
}
The “ImageProcessorServer” looks like this:
@Singleton
@Startup
public class ImageProcessorServer {
private Map<Integer, ImageProcessor> processors =
new HashMap<Integer, ImageProcessor>();
@Lock(LockType.WRITE)
public ImageProcessor get(int imageId) {
ImageProcessor processor = processors.get(imageId);
if(processor == null) {
processor = new ImageProcessor(imageId);
processors.put(imageId, processor);
}
return processor;
}
}
It’s a singleton to make sure, that only one ImageProcessor per Image is generated (generation under mutual exclusion → Write-Lock).
Now the Problem: How can I inject my Data Access Objects (for manipulating my database) in my ImageProcessor class? DAOs are simple stateless beans. My ImageProcessor should look like this:
public class ImageProcessor {
@Inject
private ActionDao actionDao;
private Image image;
public ImageProcessor(int imageId) { … }
public void apply(String action, ...) {
//change image
//actionDao.persist(actionObject)
}
}
But this does not work. The ActionDao is NULL.
My current solution is to pass the DAOs as parameter in every method that is using DAOs, like this:
public ImageProcessor(int imageId, ImageDao dao) { … }
public void apply(String action, …, ActionDao dao, ImageDao dao2, …) {
//change image
//dao.persist(actionObject)
}
It is important that the requests with the same image id share the same image processor. A client can have multiple requests with different image ids.
Under this link
Using Dependency Injection in POJO's to inject EJB's
is said that one can use a factory. But I don’t know how to work this out. Can someone provide code for this?
Does someone know an elegant way to solve my problem?
In your case you can manually lookup your bean. to do so you can add an static util method to get the bean manager :
and then you can manually lookup your bean in singleton EJB, then all injections will happen in your bean:
after looking up the bean set the image id using a setter method and then put it in your map.
Try to make a util class for manually looking for beans, then you can reuse it in whole project.
Also Seam3, Myface CODI and DeltaSpike have some utilities to do these routine processes.
Fore more info take a look at this sample.