Spring如何在运行时选择接口的实现

时间:2019-02-02 17:36:29

标签: java spring hibernate spring-data-jpa spring-data

我想知道spring数据JPA框架如何选择JpaRepository的实现。

enter image description here

如上图所示,有两个类正在实现JpaRepository。仅举一个例子。

在在线演示示例中没有看到任何表明使用该特定类的示例。

3 个答案:

答案 0 :(得分:2)

在有帮助的情况下给出更广泛的解释。

当您的应用程序启动春季初始化应用程序上下文;即集豆类,使您的应用程序中。

作为的一部分(当@EnableJpaRepositories是本)弹簧数据扫描类路径与注释所有接口@Repository。当你的资料库接口扩展这会是这样JpaRepository(或CrudRepository或任何其派生的)。

有关每个接口发现它将注册了“存储库厂”豆。一种特殊的bean,它知道如何创建其他bean。在这种情况下,它知道如何实例化存储库接口的实现。

时,遇到的第一个时间代码“自动钢丝”存储库接口此触发器工厂bean实例化一个特殊的代理类:(1)实现存储库接口,(2)靶向选择的实现类的一个实例,通常为SimpleJpaRepository(如@ sairamch04解释)。代理是实际被连线到调用代码(因为它实现了你的资料库接口)的对象。因此,当您调用存储库接口时,您实际上是在调用代理并将代理转发到实现中。它也可以转发到其他对象,具体取决于您是否已自定义存储库或选择使用QueryDSL。但是在简单的情况下,调用将转发到实现对象SimpleJpaRepository

HTH

答案 1 :(得分:1)

Spring数据默认使用JpaRepositoryFactory来为您的存储库找到正确的实现。您可以通过配置@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)

定义自定义工厂

JpaRepositoryFactory选择实现的方式

@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {

    if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
        return QuerydslJpaRepository.class;
    } else {
        return SimpleJpaRepository.class;
    }
}

isQueryDslExecutor的源代码开始,如果您的存储库实现了QuerydslPredicateExecutor,则使用QuerydslJpaRepository的实现。

private boolean isQueryDslExecutor(Class<?> repositoryInterface) {

    return QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
}

答案 2 :(得分:1)

@ sairamch04说的还好。我只能补充一点,当通过@Query批注或使用标准jpa方法名称定义查询时,将创建一个代理对象来执行查询。这些代理的创建在工厂对象中,例如提到的JpaRepositoryFactory。否则,它会退回到诸如SimpleJpaRepository之类的实现中。有关存储库的更多信息,可以在spring-data-commons中调用RepositoryFactorySupport.getReporitory()方法。