2012-12-06 2 views
2

GuiceServletContextListener에서 guice로 묶인 저지 자원을 대체하는 메소드를 찾고 있습니다. 내가 작업을 얻으려고 내 코드 :저스 자원을 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()); 
    } 
} 

하지만, 구현 인터페이스처럼 guice 만 bind(BookImpl.class) 작업의를 저지 자원을 결합 할 수는 없지만 불행하게도이 작동하지 않습니다. 그러나 이러한 바인딩은 덮어 쓰기가 불가능합니다. 을 bind(BookUserImpl.class)으로 다시 정의하려고 시도하면 오류가 Conflicting URI templates. The URI template /books/{key} for root resource class. 인 반면 @Path는 고유해야합니다. 내 유스 케이스에 대한 해결책이 있습니까?

답변

0

경고. 단지 Guines.createInjector (Stage.PRODUCTION, ...)에서 Modules.override가 작동하지 않으므로 개발에만주의해서 사용해야합니다. 두 개의 컨텍스트 리스너를 만들어야하며, 여하튼 (mrough 프로파일로 말하면) 적절한 구현으로 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 and Book 구현 바인딩과 관련이 없으며 서블릿을 Jersey 컨테이너에 바인딩/등록하는 것과 관련이 있다고 생각합니다. 전체 stacktrace 붙여 넣기, guice stacktraces 장황하고 매우 도움이됩니다.

관련 문제