2012-12-06 68 views
2

我正在尋找一種方法來覆蓋Guice在GuiceServletContextListener中界定的球衣資源。我的代碼,我試圖讓工作:用guice覆蓋球衣資源

//Define Jersey resource interface 
@Path("/books/{key}") 
public interface BookDocument { 

    public BookDAO getDao(); 

    public void setDao(BookDAO dao); 
} 

//Define default implementation 
public class BookImpl implements Book { 

    @Override 
    public BookDAO getDao() { 
     return dao; 
    } 

    @Inject 
    @Override 
    public void setDao(BookDAO dao) { 
     this.dao = dao; 
    } 
} 

//User wants to inject his implementation, so he define it 
public class BookUserImpl implements Book { 

    @Override 
    public BookDAO getDao() { 
     return dao; 
    } 

    @Inject 
    @Override 
    public void setDao(BookDAO dao) { 
     this.dao = dao; 
    } 
} 

//Inject default implementation of resource 
public class ApplicationResourcesModule extends AbstractModule 
{ 
    @Override 
    protected void configure() 
    { 
     bind(Book).to(BookImpl); 
    } 
} 

//But user wants to inject his implementation, so he bind it in users AbstractModule 
public class ApplicationResourcesModuleUser extends AbstractModule 
{ 
    @Override 
    protected void configure() 
    { 
     bind(Book).to(BookUserImpl); 
    } 
} 

//Bind all resources 
public class JerseyGuiceConfig extends GuiceServletContextListener 
{ 
    @Override 
    protected Injector getInjector() 
    { 
     //Override default binding by user bindings. 
     return Guice.createInjector(Modules.override(new ApplicationResourcesModule()).with(new ApplicationResourcesModuleUser()), new JerseyServletModule()); 
    } 
} 

但不幸的是,這並不工作,但我不能在吉斯結合球衣資源,如接口的實現,只有bind(BookImpl.class)工作的。但是這種綁定是不可能覆蓋的。如果我嘗試用bind(BookUserImpl.class)覆蓋bind(BookImpl.class),則會收到錯誤Conflicting URI templates. The URI template /books/{key} for root resource class.,而@Path應該是唯一的。那麼我的用例有沒有解決方案?

回答

0

我只是不想警告你Modules.override不能在Guice.createInjector(Stage.PRODUCTION,...)上工作,所以你應該小心使用它只用於開發。您應該創建兩個上下文監聽器,並以某種方式(通過maven配置文件可以說)通過適當的實現來設置web.xml。

最好使用:

//Inject default implementation of resource 
public class MainModule extends AbstractModule 
{ 
    @Override 
    protected void configure() 
    { 
     if(currentStage().equals(Stage.PRODUCTION) { 
      install(new ApplicationResourcesModuleUser()); 
     } else { 
      install(new ApplicationResourcesModule()); 
     } 
    } 
} 

//Bind all resources 
public class JerseyGuiceConfigPROD extends GuiceServletContextListener 
{ 
    @Override 
    protected Injector getInjector() 
    { 
     //Override default binding by user bindings. 
     return Guice.createInjector(Stage.PRODUCTION, new MainModule(), new JerseyServletModule()); 
    } 
} 

public class JerseyGuiceConfigDEV extends GuiceServletContextListener 
{ 
    @Override 
    protected Injector getInjector() 
    { 
     //Override default binding by user bindings. 
     return Guice.createInjector(Stage.DEVELOPMENT, new MainModule(), new JerseyServletModule()); 
    } 
} 

您可以使用@ImplementedBy註解來讓你的界面說的默認實現應該的。因此,您不必顯式地綁定它,如果綁定它,它將覆蓋註釋綁定。

@Path("/books/{key}") 
@ImplementedBy(BookImpl.class) 
public interface Book { 

    public BookDAO getDao(); 

    @Inject //it is enough to put the injection here, i think 
    public void setDao(BookDAO dao); 
} 

我認爲這個問題與Book和Book實現綁定無關,而是綁定/註冊servlet到Jersey容器。你能不能粘貼整個堆棧跟蹤,guice stacktraces是非常有幫助的。