Search code examples
javadesign-patternsdependency-injectionguicehessian

Injecting many decorated instances with Guice -- on mixing HessianServlet with Guice


Given the following code in a Guice servlet module configureServlets():

serve("/a").with(new Decorator(new A()));
serve("/b").with(new Decorator(new B()));
...
serve("/z").with(new Decorator(new Z()));
...

What would be the best / easiest solution to properly inject all this? (i.e. injecting fields in the various decorated classes A, B, C...)

I was thinking using named providers, but I would prefer not having to define a new provider class for each A, B, C... The ideal solution would be thus generic.


ON MIXING HESSIAN WITH GUICE...

To help precise the question, the real code uses web-services with Hessian. After digging on the net there is currently no proper answer on this problem (I've seen many ugly hacks), and the solution given by Guillaume fits the bill on this precise case.

To summarize the original problem: to implement a web-service using Hessian, one must implement an HessianServlet, which is a GenericServlet; however Guice can only bind HttpServlet. The trick was thus to implement a thin wrapper HessianHttpServlet:

class HessianHttpServlet extends HttpServlet {
    public HessianHttpServlet(HessianServlet hessianServlet) {
        this.hessianServlet = hessianServlet;
    }
    @Override public void init(ServletConfig config) throws ServletException {
        hessianServlet.init(config);
    }
    @Override public void service(ServletRequest request, ServletResponse response) {                 
        hessianServlet.service(request, response);
    }
}

And calling:

serve("/a").with(new HessianHttpServlet(new WebServiceA()));

The complete solution is thus in that case to inject WebServiceX :

void configureServlet() {
    serve("/a").with(new HessianHttpServlet(inject(new WebServiceA())));
    serve("/b").with(new HessianHttpServlet(inject(new WebServiceB())));
    ...
    serve("/z").with(new HessianHttpServlet(inject(new WebServiceZ())));
}
private HessianServlet inject(HessianServlet hessianServlet) {
    requestInjection(hessianServlet);
    return hessianServlet;
}

Solution

  • You can use requestInjection(Object instance) on each of your decorators.