用 guice 覆盖球衣资源



我正在寻找一种方法来覆盖GuiceServletContextListener中以guice为界的jersey资源。我的代码,我正在尝试工作:

//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应该是唯一的。那么我的用例有什么解决方案吗?

我只是不想警告你 Modules.override 在 Guice.createInjector(Stage.PRODUCTION,...) 上不起作用,所以你应该只在开发中小心使用它。您应该创建两个上下文侦听器,并以某种方式(例如通过 maven 配置文件)设置网络.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 堆栈跟踪很详细,非常有用。

最新更新