2016-11-17 34 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我真的很高兴它有帮助 - 祝你好运与其他应用程序! –