2016-11-17 64 views
1

對於我正在處理的一個小型項目,我一直試圖實現某些DAO模式,以便與我的數據庫交互,並且已經開始使用Guice(第一次使用)爲我處理DI。現在,我有這樣的類層次結構:使用Guice和DAO模式的依賴注入

enter image description here

DAOImpl需要一類類型的引用,所以我的數據庫客戶端(蒙戈/嗎啡),可以做一些初始化的工作,並通過實例嗎啡提供BasicDAO。以下是相關類的片段:

public class DAOImpl<T> implements DAO<T> { 
    private static final Logger LOG = LoggerFactory.getLogger(DAOImpl.class); 
    private static final String ID_KEY = "id"; 
    private final org.mongodb.morphia.dao.DAO morphiaDAO; 

    @Inject 
    public DAOImpl(Datastore ds, Class<T> resourceClass) { 
    morphiaDAO = new BasicDAO(resourceClass, ds); 

    LOG.info("ensuring mongodb indexes for {}", resourceClass); 
    morphiaDAO.getDatastore().ensureIndexes(resourceClass); 
    } 
} 

public class UserDAO extends DAOImpl<User> { 
    @Inject 
    public UserDAO(Datastore ds) { 
    super(ds, User.class); 
    } 

    public User findByEmail(String email) { 
    return findOne("email", email); 
    } 
} 

我知道,我需要告訴吉斯綁定相關的類每個通用DAOImpl即得到擴展,但我不確定如何做到這一點。這看起來好像可能已經回答,但它不是爲我點擊。我已經試過以下一些:

public class AppInjector extends AbstractModule { 
    @Override 
    protected void configure() { 
    bind(com.wellpass.api.dao.DAO.class).to(DAOImpl.class); 

// bind(new TypeLiteral<SomeInterface<String>>(){}).to(SomeImplementation.class); 
// bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {}); 
// bind(new TypeLiteral<DAO<User>>() {}).to(UserDAO.class); 

    bind(new TypeLiteral<DAO<User>>(){}).to(new TypeLiteral<DAOImpl<User>>() {}); 
    } 
} 

這些都是一些我見過的錯誤:

com.google.inject.CreationException: Unable to create injector, see the following errors: 

1) No implementation for org.mongodb.morphia.Datastore was bound. 
    while locating org.mongodb.morphia.Datastore 
    for the 1st parameter of com.wellpass.api.dao.UserDAO.<init>(UserDAO.java:12) 
    at com.wellpass._inject.AppInjector.configure(AppInjector.java:18) 

2) java.lang.Class<T> cannot be used as a key; It is not fully specified. 
    at com.wellpass.api.dao.DAOImpl.<init>(DAOImpl.java:19) 
    at com.wellpass._inject.AppInjector.configure(AppInjector.java:14) 

任何幫助將非常感激。

回答

2

如果你想注射部位如下所示:

@Inject 
public DAOConsumer(DAO<User> dao) { 
} 

與您UserDAO類的實例,然後

bind(new TypeLiteral<DAO<User>>() {}).to(UserDAO.class); 

correct syntax注入。

至於你的其他錯誤:

1) No implementation for org.mongodb.morphia.Datastore was bound.

這是因爲Datastore是一個接口。您需要將接口綁定到實現,實例或Provider<Datastore>

爲了解決如何做到這一點,請考慮手動完成這些操作所需的步驟,而不需要額外增加Guice的複雜程度。一旦你100%理解了這一點,你可以嘗試設計一個適當反映morphia初始化步驟的對象圖。

爲了讓您一開始,在morphia quick tour對如何得到Datastore對象的實例指南:

final Morphia morphia = new Morphia(); 

// tell Morphia where to find your classes 
// can be called multiple times with different packages or classes 
morphia.mapPackage("org.mongodb.morphia.example"); 

// create the Datastore connecting to the default port on the local host 
final Datastore datastore = morphia.createDatastore(new MongoClient(), "morphia_example"); 
datastore.ensureIndexes(); 

從他們的代碼,你可以看到有獲得所需要的至少兩個依賴Datastore

  1. 一個Singleton Morphia
  2. 一個Singleton MongoClient

你將不得不編寫一些代碼來設置它,可能使用Guice的Provider類。

+0

嘿,只是想循環回來,說謝謝。我通過自己手動注入Deps來開始新穎的老式方式,並一直致力於解決方案。關於'TypeLiteral'的回答讓我大部分時間都在那裏,但是因爲我的'DAO'是一個由'DAOImpl'實現的接口,最終爲我工作的是:bind(new TypeLiteral >( ){ })。(UserDAO.class); bind(new TypeLiteral >(){ })。to(PersonDAO.class); bind(Mongo.class).to(MongoClient.class);' – Justin

+0

而對於'Datastore',我最終制作了一個像你所建議的提供者,並使用@ @Singleton'註釋: '@Provides @Singleton public Datastore datastoreProvider(MongoClient mongoClient,ServerConfig config)Morphia morphia = new Morphia(); return morphia.createDatastore(mongoClient,config.getMongoConfig()。getDatabase()); }' – Justin

+0

@Justin我真的很高興它有幫助 - 祝你好運與其他應用程序! –