Spring + Mongo + Generics +灵活性

以下代码(当然)不起作用,因为标记的行不能编译:

MyClass { //singleton stuff private static MyClass instance; private MyClass () {} public static MyClass getInstance() { if(instance==null) { instance = new MyClass (); } return instance; } // method creating problems public NonGenericSuperClassOfGenericClass create(Class... classes) { if(someCondition) return new GenericClass; // DOES NOT COMPILE else return new OtherGenericClass; } } 

因此,我实际上不知道“创造”是否会回归

 GenericClass 

要么

 OtherGenericClass 

它有不同数量的参数。

发生这种情况是因为我使用Spring而我计划使用MongoDB ,但将来我可能需要切换到不同的东西(例如Hibernate)。

GenericClass类是这样的:

  GenericClass 

要么

  GenericClass 

其中PersistentType1 / 2是我最终需要存储在数据库中的类,而GenericClass是一种访问Mongo API的代理。 事实上,它看起来像:

  public MongoTemplate getTemplate(); public void save(T toInsert); public List select(Query selectionQuery); public T selectById(ID id); public WriteResult update(Query selectionQuery, Update updatedAttributes); public void delete(T toRemove); public void delete(Query selectionQuery); 

怎么办? 从控制器(或实体,如果你挑剔)我需要实例化存储库并调用任何方法。 这导致控制器与MongoDB耦合,即它们显式地必须实例化这样的GenericClass,其实际上称为MongoRepository并且严格依赖于Mongo(实际上它是具有两个“自由度”的通用)。

所以,我决定创建MyClass,这是另一个隔离控制器的代理。 通过这种方式,Controller可以获取MyClass的单​​个实例,并让它创建相应存储库的新实例。 特别是,当“somecondition”为真时,这意味着我们想要使用MongoRepository(当它为false时,可能需要实例化Hibernate代理,即HibernateRepository)。 但是,MongoRepository是通用的,因此它需要某种forms的实例化,我希望将其作为参数传递。

不幸的是,generics在编译时得到解决,因此我认为它们对我不起作用。

我该如何解决这个问题?

为了将底层持久性存储与应用程序逻辑分离,我将使用DAO方法。

使用所需的方法定义DAO的接口,例如保存,更新等。然后为您可能需要的每个持久性提供程序提供实现,例如,UserAccess可能是您可以实现为HibernateUserAccess和MongoUserAccess的接口。 在每个实现中,您注入适当的模板,例如Mongo或Hibernate,并使用它来完成持久性操作。

您可能遇到的问题是您的加载操作将返回User的实例,这需要在持久性提供程序之间变化,即JPA注释将与MongoDB所需的Spring Data注释不同(漏洞抽象)。

我可能会通过创建一个用户界面来表示持久性操作的结果并为每个持久性提供程序提供一个实现来解决这个问题。 要么是这样,要么返回从JPA或Mongo加载的结果构建的公共模型。