我正在寻找一种方法来覆盖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());
}
}
但不幸的是,这不起作用,而我无法将jersey绑定到类似接口的guice资源,只有bind(BookImpl.class)
工作。但这种绑定是不可能覆盖的。如果我尝试使用bind(BookImpl.class)
覆盖bind(BookUserImpl.class)
,则会收到错误Conflicting URI templates. The URI template /books/{key} for root resource class.
,而@Path应该是唯一的。那么我的用例有什么解决方案吗?
答案 0 :(得分: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是冗长的,非常有用。