2012-02-13 1 views
3

Учитывая следующий код в модуле сервлета Guice configureServlets():Инъекционных много украшенных экземпляров с Guice - при смешивании HessianServlet с Guice

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

Что бы быть лучшим/простым решением, чтобы правильно внедрить все это? (например, инъекционные поля в различных декорированных классах A, B, C ...)

Я думал об использовании именованных поставщиков, но я бы предпочел не определять новый класс провайдера для каждого A, B, C .. . Идеальное решение было бы таким образом общим.


НА СМЕСЬ Мешковины С Guice ...

Чтобы уточнить вопрос, реальный код использует веб-сервисы с Гессом. После копания в сети в настоящее время нет правильный ответ на эту проблему (я видел много уродливых хаков), и решение, данное Guillaume подходит для счета в этом точном случае.

Чтобы подвести итог оригинальной проблеме: для реализации веб-сервиса с использованием Hessian необходимо реализовать HessianServlet, который является GenericServlet; однако Guice может связывать только HttpServlet. Хитрость была, таким образом, чтобы осуществить тонкую оболочку 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); 
    } 
} 

и призвание:

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

полное решение, таким образом, в этом случае, чтобы придать 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; 
} 
+0

Простите мое невежество, но что это за предмет Decorator? Не можете ли вы просто привязать подачу («/ a») с помощью (A.class)? Затем инъекция на A будет выполнена автоматически. То же самое касается B, C, Z. Я чувствую, что у меня что-то не хватает. –

+0

Ну, декоратор здесь, чтобы добавить общую функциональность поверх всех украшенных классов A, B, C ... Добавление непосредственно этой функции к A, B, C нарушит преимущество наличия этого декоратора. Кроме того, декоратор может быть изменен динамически; здесь я взял простой пример только с одним декоратором. –

ответ

3

Вы можете использовать requestInjection(Object instance) на каждом из ваших декораторов.

+0

В моем случае мне нужно только вставлять декорированные экземпляры, поэтому вызываем 'serve ("/a ").с (новый Decorator (добавленный (новый A()))) будет делать это с помощью 'injected()' вспомогательной функции, просто вызывающей 'requestInjection()' и возвращающей экземпляр. Но почему-то я плохо себя чувствую, и у меня создается впечатление, что это неправильно использует DI. –

+0

Думаю, я понимаю, что вы чувствуете. Вы хотите как-то сказать «служить» («/ a *») с помощью (Decorator.class) .using (A.class); (синтаксис неверен, но он как бы выражает то, что вы хотите). К сожалению, мои знания о Гизе не доходят до такой степени. –

1

Я создал небольшой проект с открытым исходным кодом, который позволяет легко интегрировать hessian и guice. Вы можете использовать конфигурацию на основе аннотаций, как это: WebService:

@HessianWebService 
public class UserServiceImpl implements UserService { 
    ... 
} 

Guice конфигурации:

public class WebServiceGuiceServletContextListener extends GuiceServletContextListener { 
    @Override 
    protected Injector getInjector() { 
     return Guice.createInjector(
       /* your guice modules */ 
       new HessianWebServicesModule("your web service implementations package") 
     ); 
    } 
} 

или ручным способом с использованием EDSL:

public class WebServiceGuiceServletContextListener extends GuiceServletContextListener { 
    @Override 
    protected Injector getInjector() { 
     return Guice.createInjector(
       /* your guice modules */ 
       new HessianWebServicesModule(){ 
        @Override 
        protected void configureHessianWebServices() { 
         serveHessianWebService(UserService.class).usingUrl("/Users"); 
        } 
       } 
     ); 
    } 
} 

Больше информации, параметры конфигурации и полные примеры приведены здесь: https://bitbucket.org/richard_hauswald/hessian-guice/