2014-06-18 3 views
3

JDBI를 사용하여 만든 DAO에 대해 Provider을 설정하려고합니다. JDBI는 Handle 개체 (JDBC Connection의 래퍼)를 사용하며 handle.attach(MyDaoType.class)을 사용하여 DAO를 가져올 수 있습니다.Guice에서 제네릭 형식을 반환하는 공급자 구성

public class DaoProvider<T> implements Provider<T> { 

    private final Class<T> daoType; 
    private final Handle handle; 

    @Injected 
    public DaoProvider(Class<T> daoType, Handle handle) { 
    this.daoType = daoType; 
    this.handle = handle; 
    } 

    @Override 
    public T get() { 
    return handle.attach(daoType); 
    } 
} 

을하지만 Guice와이를 묶는 대단히 어려운 것 같다 오히려 모든 DAO 클래스에 대한 별도의 Provider 구현을 작성하는 것보다 나는 감각이 작업을 수행 할 수 있도록 거라 생각 했어요. I this answer에 제안 된대로 1 번째 생성자 인수에 @Assisted 주석을 사용하여 시도한입니다. 이 같은 공장 정의 :

public interface DAOProviderFactory { 
    <T> DAOProvider<T> create(Class<T> daoType); 
} 

을하지만 요점은 내가 제공 클래스를 확장하고 싶지 않는다는 것입니다 나는이 FactoryModuleBuilder.implemented 메소드를 호출하는 방법을 분명하지 않다.

또한 내가 실제로 원하는 일을 반환하는 제공를 반환하는 공장이 거라고 조금 미친 것 같다!

이것은 스프링 DI 컨테이너로하기가 정말 쉽다는 것을 알았으므로 Guice와 (과) 가능하다고 생각합니다. 누구든지 올바른 방향으로 나를 가리킬 수 있습니까?

+1

이 가능한 솔루션을 살펴보십시오. https://stackoverflow.com/questions/24030609/how-do-i-pass-parameters-into-a-provider-with-guice – condit

+0

@condit으로 인해 나를 이해할 수있었습니다. 그것. 감사. 답변을 추가하려면 나중에 동의 할 것입니다. 나중에 솔루션을 게시 할 것입니다. –

답변

3

덕분에 문제를 해결하기 위해 저를 활성화 뭔가 나를 가리키는 위해 @condit합니다. 사실 아주 간단합니다. 나는이 같은 Handler에 대한 필드 주입을 사용하도록 Provider 구현을 변경 :

public class DAOProvider<T> implements Provider<T> { 

    private @Inject Handle handle; 
    private final Class<T> daoType; 

    public DAOProvider(Class<T> daoType) { 
    this.daoType = daoType; 
    } 

    @Override public T get() { 
    return handle.attach(daoType); 
    } 
} 

그럼 난 난 그냥 이런 식으로 뭔가 할 수있는 바인딩 할 특정 DAO 클래스를 가지고있는 모듈이나 응용 프로그램 :

bind(UserStore.class).toProvider(new DAOProvider<>(UserStore.class)); 
bind(MessageStore.class).toProvider(new DAOProvider<>(MessageStore.class)); 

그러면 Guice는 Handle 인스턴스를 DAOProvider 인스턴스에 자동으로 주입합니다.

+0

그냥 '핸들'을 관리하는 방법을 잘 모르겠지만 DAO를 검색하는 데 "주문형"방법을 사용하는 것이 좋습니다. 그런 식으로'Handle'이 닫히지 않을까 걱정하지 않아도됩니다. 대신'DBI'를 삽입하고'get()'메소드에서'dbi.onDemand (daoType)'을 호출하십시오. – condit

+0

@condit 아주 좋은 생각입니다. 나는 그 곳의 모든 곳에서 핸들을 새고 있었다고 생각한다. 그것은 단지 약간의 데모 앱이므로 아무런 문제가 발생하지 않았지만 어쨌든 생각할 가치가 있습니다. –

-1

나는 이것을 너무 복잡하게 만들고 있다고 생각합니다. get() 메서드를 호출하면 결과를 참조에 저장합니다. 즉, 특정 DAO의 형식을 알 수 있습니다. 즉, DAO 클래스를 알고있는 코드를 작성할 수 있습니다. 내 말은, Guice 자신이 어떻게 작동하는지 생각해 보면, Injector.getInstance(Class<?> type) ... 다른 말로하면,이 메소드는 어쨌든 Class을 전달하지 않고 유형을 유추 할 수 없으므로 사용하면 Class을 전달하십시오!

Handle을 직접 주입하고 싶지 않은 이유를 이해할 수 있습니다. 그렇다면 래퍼를 만드는 것이 가장 좋습니다.

public interface DaoProvider { 
    <T> T provideDao(Class<T> daoType); 
} 

: 그리고

public class JdbiDaoProvider implements DaoProvider { 
    private final Handle handle; 

    @Inject 
    JdbiDaoProvider(Handle handle) { 
    this.handle = handle; 
    } 

    public <T> T provideDao(Class<T> daoType) { 
    return handle.attach(daoType); 
    } 
} 
+0

저에게는 DAO가 필요한 곳이면 어디에서나'Handle'을 주입하고'handle.attach()'를 사용하는 것의 이점이없는 것 같습니다. 그건 괜찮 겠지.하지만 나는'UserDAO' 또는 무엇이든 직접 주입 할 수 있기를 바라고 Guice가 제공 할 수 있어야한다고 생각했다.이는 DAO를 사용해야하는 모든 구성 요소의 코드를 단순화합니다. –

관련 문제