条件存储库注入 - Spring Boot

Posted

技术标签:

【中文标题】条件存储库注入 - Spring Boot【英文标题】:conditional repository injection - Spring Boot 【发布时间】:2020-09-19 07:24:10 【问题描述】:

我有两个连接 MongoDBCouchBase 的存储库接口:

public interface UserRepositoryMongo extends MongoRepository<User, Long> 

public interface UserRepositoryCouch extends  CouchbasePagingAndSortingRepository<User, Long> 


有没有办法在条件下将@Autowire 这些存储库替换为UserService? 条件将在application.properties 内。



**Note :**

*These repositories can have custom methods too.*

【问题讨论】:

您是同时激活 MongoDB 和 Couchbase 还是在它们之间切换? 没有。也可以断开连接。但我总是给活跃一个作为条件 是的,如果您可以使用@Profile 或者如果您尝试过使用@Conditionalonproperty 你试过只使用PagingAndSortingRepository吗?如果您只有一个 Spring Data 提供程序处于活动状态,它应该会自动连接它。 PagingAndSortingRepository 无法使用 包中有很多存储库 【参考方案1】:

我们可以使用ConditionalOnPropertyConditionalOnExpression 在两个不同的存储库实现之间切换。

    如果我们想通过简单的属性存在/不存在或属性值来控制自动装配,那么可以使用ConditionalOnProperty

    如果需要复杂的评估,那么我们可以使用ConditionalOnExpression

ConditionalOnProperty(属性的存在/不存在)

@Qualifier("specificRepo")
@ConditionalOnProperty("mongo.url")
public interface UserRepositoryMongo extends MongoRepository<User, Long>


@Qualifier("specificRepo")   
@ConditionalOnProperty("couch.url")
public interface UserRepositoryCouch extends  CouchbasePagingAndSortingRepository<User, Long>

ConditionalOnProperty(基于值)

@ConditionalOnProperty("repo.url", havingValue="mongo", matchIfMissing = true) //this will be default implementation if no value is matching
public interface UserRepositoryMongo extends MongoRepository<User, Long> 


@ConditionalOnProperty("repo.url", havingValue="couch")
public interface UserRepositoryCouch extends  CouchbasePagingAndSortingRepository<User, Long> 

条件表达式

@ConditionalOnExpression("#'$repository.url'.contains('couch')")
public interface UserRepositoryCouch extends  CouchbasePagingAndSortingRepository<User, Long> 

更新

根据您的要求使用CrudRepository/Repository类型注入。

public class DemoService 

    @Autowired
    @Qualifier("specificRepo")
    private CrudRepository repository;

根据创建的 bean,UserRepositoryMongoUserRepositoryCouch 将被自动装配。确保只实例化一个 bean 以避免歧义错误。

【讨论】:

那么,我如何将其自动连接到服务中? 更新了答案以包括注入逻辑。如果需要分页功能,可以使用PagingAndSortingRepository代替CrudRepository 问题是我的包里还有其他的仓库,这种类型的autowire会报错。 如果只需要在其中两个之间使用,则添加一个标记接口,并且可以使用该接口类型进行注入。 更新了第一个代码 sn-p 以显示我在上述评论中的意思。【参考方案2】:

另一个尝试解决这个问题。

根据该属性,自动装配的 customRepository 将是 SimpleMongoRepository 或 SimpleCouchRepository 的一个实例。

    public interface CustomRepository extends CrudRepository<User, Long> 
        User findByLastName(String lastName); //custom methods
    

    @Qualifier("specificRepo")
    @ConditionalOnProperty("mongo.url")
    public interface UserRepositoryMongo extends MongoRepository<User, Long>, CustomRepository
    

    @Qualifier("specificRepo")   
    @ConditionalOnProperty("couch.url")
    public interface UserRepositoryCouch extends  CouchbasePagingAndSortingRepository<User, Long>, CustomRepository
    

    public class UserService 

        @Autowired
        @Qualifier("specificRepo")
        private CustomRepository repository;
    

【讨论】:

以上是关于条件存储库注入 - Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

在Junit 5测试中注入Spring数据存储库

使用 Spring 4 和消息插值配置在 ConstraintValidator 中注入存储库

在 Spring 存储库中注入 EntityManager 时出现 java.lang.NullPointerException

在没有DI框架的情况下注入存储库

手动注入bean时 , 根据条件注入bean

@ServerEndpoint 和 Spring MVC 注入