Java 定制用于多个数据源的Spring数据存储库bean名称

Java 定制用于多个数据源的Spring数据存储库bean名称,java,spring,mongodb,spring-data,spring-data-mongodb,Java,Spring,Mongodb,Spring Data,Spring Data Mongodb,我有一个利用Spring数据(本例中为MongoDB)与具有相同模式的多个数据库交互的项目。这意味着每个数据库都使用相同的实体和存储库类。例如: public class Thing { private String id; private String name; private String type; // etc... } public interface ThingRepository extends PagingAndSortingReposit

我有一个利用Spring数据(本例中为MongoDB)与具有相同模式的多个数据库交互的项目。这意味着每个数据库都使用相同的实体和存储库类。例如:

public class Thing {
    private String id;
    private String name;
    private String type;
    // etc...  
}

public interface ThingRepository extends PagingAndSortingRepository<Thing, String> {
    List<Thing> findByName(String name);
}

@Configuration
@EnableMongoRepositories(basePackageClasses = { ThingRepository.class })
public MongoConfig extends AbstractMongoConfiguration {
    // Standard mongo config
}
我可以使用不同的
MongoTemplate
实例创建同一存储库的多个实例,但我不知道引用和注入它们的正确方法。我希望能够将各个存储库实例注入到不同的控制器中,如下所示:

@Controller
@RequestMapping("/things/one/")
public class ThingOneController {
    @Resource private ThingRepository thingRepositoryOne;
    ...
}

@Controller
@RequestMapping("/things/two/")
public class ThingTwoController {
    @Resource private ThingRepository thingRepositoryTwo;
    ...
}
这样的配置可能吗?我是否可以控制实例化接口的bean名称,以便使用
@Resource
@Autowired
引用它们


附加问题:这也可以通过自定义存储库工厂来实现吗?

对于一般的
@repository
您可以添加
(value=“someDao”)
来命名创建的Bean,如果
MongoRepository
扩展了
Repository
,这应该可以工作。

使用
@NoRepositoryBean
创建您的存储库接口,我们将自己连接它:

@NoRepositoryBean
public interface ModelMongoRepository extends MongoRepository<Model, String> {
}      
现在,您有两个具有不同的
@Qualifier
名称的bean,每个bean都为不同的数据库配置,并且使用相同的模型

您可以使用
@Qualifier
注入它们:

@Autowired
@Qualifier("one")
private ModelMongoRepository mongoRepositoryOne;

@Autowired
@Qualifier("two")
private ModelMongoRepository mongoRepositoryTwo;
为了简单起见,我已经在configuration类中硬编码了这些值,但是您可以从application.properties/yml中的属性注入它们

编辑以回答评论:

如果您想创建一个自定义实现而不失去spring数据接口存储库的好处,这里有一些修改。规格说明如下:

通常有必要为一些应用程序提供自定义实现 存储库方法。Spring数据存储库允许您轻松地 提供自定义存储库代码并将其与通用CRUD集成 抽象和查询方法功能。丰富知识库 使用自定义功能,首先定义接口和 自定义功能的实现。使用存储库 为扩展自定义接口而提供的接口。最 要找到的类的重要位是 与核心存储库界面(见下文)相比,其上的名称

创建一个新接口,它在技术上与spring数据无关,好的旧接口:

public interface CustomMethodsRepository {
    public void getById(Model model){
}
@NoRepositoryBean
public interface ModelMongoRepository extends MongoRepository<Model, String>, CustomMethodsRepository {
} 
public class ModelMongoRepositoryImpl  implements CustomModelMongoRepository {
    private MongoOperations mongoOperations;

    public ModelMongoRepositoryImpl(MongoOperations mongoOperations) {
        this.mongoOperations = mongoOperations;
    }
    public void getById(Model model){
        System.out.println("test");
    }
}
让您的存储库接口扩展此新接口:

public interface CustomMethodsRepository {
    public void getById(Model model){
}
@NoRepositoryBean
public interface ModelMongoRepository extends MongoRepository<Model, String>, CustomMethodsRepository {
} 
public class ModelMongoRepositoryImpl  implements CustomModelMongoRepository {
    private MongoOperations mongoOperations;

    public ModelMongoRepositoryImpl(MongoOperations mongoOperations) {
        this.mongoOperations = mongoOperations;
    }
    public void getById(Model model){
        System.out.println("test");
    }
}
将Java配置更改为添加
myFactory.setCustomImplementation(new ModelMongoRepositoryImpl())

@Bean
@Qualifier("one")
public ModelMongoRepository modelMongoRepositoryOne() throws DataAccessException, Exception {
    MongoRepositoryFactoryBean<ModelMongoRepository, Model, String> myFactory = new MongoRepositoryFactoryBean<ModelMongoRepository, Model, String>();
    MongoOperations mongoOperations = createMongoOperations("hostname1", 21979, "dbName1", "usdername1", "password1");
    myFactory.setCustomImplementation(new ModelMongoRepositoryImpl(mongoOperations));
    myFactory.setRepositoryInterface(ModelMongoRepository.class);
    myFactory.setMongoOperations(mongoOperations);

    myFactory.afterPropertiesSet();
    return myFactory.getObject();
}
@Bean
@限定词(“一”)
public ModelMongoRepository modelMongoRepositoryOne()引发DataAccessException,异常{
MongoRepositoryFactoryBean myFactory=新的MongoRepositoryFactoryBean();
MongoOperations MongoOperations=createMongoOperations(“hostname1”,21979,“dbName1”,“usdername1”,“password1”);
myFactory.setCustomImplementation(新模型MongoRepositoryImpl(mongoOperations));
setRepositoryInterface(ModelMongoRepository.class);
myFactory.setMongoOperations(mongoOperations);
myFactory.AfterPropertieSet();
返回myFactory.getObject();
}

如果您没有通过Java配置手动连接存储库,则必须将此实现命名为
ModelMongoRepositoryImpl
,以匹配接口
ModelMongoRepository+“Impl”
。它将由spring自动处理。

这对我没有帮助,因为每个存储库都有多个实例正在创建。使用
@Repository(name=“myRepository”)
将产生两个同名的bean。我想确保由存储库工厂bean创建的对象以不同的编程方式命名。您可以这样做@Autowire@Qualifier(“mongoTemplateOne”)。我不是在尝试注入单个
MongoTemplate
对象,我是在尝试注入它们用于创建的存储库。在我提供的示例中,您将如何注入使用任一数据源创建的
ThingRepository
?如何从wired mongoTemplate获取存储库?您可能需要使用工厂手动实例化存储库实现,在这一点上,你可以使用普通的
@Bean
技术来命名它们。@chrylis:你能提供一个例子作为答案吗?我不确定创建工厂bean和存储库实例的最佳方法是什么。我只讨论了手动创建,在这一点上我不能给你很好的建议。Oliver Gierke可能会在几个小时后出现。如果我添加了自定义方法,例如使用
ThingRepository.findByName()
,该怎么办?或者如果我在
ThingRepositoryImpl
类中有自定义实现的方法?我是否需要在Spring将要注入
MongoTemplate
的具体类中手动实现它们?如果是这样的话,那么使用Spring Data的repository factory还有什么意义呢?我明白你的意思,我将更新代码以使用Interface+MongoRepositoryFactoryBeanThanks,这看起来会起作用,但是现在我被如何将
MongoTemplates
注入
ThingRepositoryImpl
中挂起了。我应该自定义实现
findByName(…)
还是其他方法。想法?在这里,我相信这是你一直在寻找的最终解决方案!浏览最后一部分(“编辑以回答评论”)。你可以用最少的代码实现你的目标。这就成功了!在我的例子中,我还必须添加行
myFactory.setRepositoryBaseClass(MyBaseRepository.class)
因为我有一个扩展了
SimpleMongoRepository
的基本存储库类,但是在其他方面,配置是按照描述的那样工作的。这是一个巨大的帮助,谢谢!