Spring Boot JPA--JpaRepository实现原理

在SpringBoot中,我们只要定义好Entity,配置好DataSource,最后实现JpaRepository接口就可以对数据进行CRUD操作。

@Repository
public interface UserDao extends JpaRepository<User, Integer>{
}

是不是很神奇,我们定义了接口,但却没有实现具体的方法,为啥就可以直接对数据源进行了操作呢?今天我们就来看下JpaRepository的实现原理。以下SpringBoot相关源码都是2.1.4版本

JpaRepositoriesAutoConfiguration

在之前一篇博客Spring Boot JPA–DataSource中,就说明过@EnableAutoConfiguration注解会自动装载spring.factories文件中配置类,其中就包括JpaRepositoriesAutoConfiguration

可以看到JpaRepositoriesAutoConfiguration引入的条件,是存在DataSource以及JpaRepository。同时导入了JpaRepositoriesAutoConfigureRegistrar,我们来看下这个类做了些什么。

JpaRepositoriesAutoConfigureRegistrar

我们先来看下它的继承关系

我们重点关注下ImportBeanDefinitionRegistrar接口,Spring利用这个接口动态注册Bean,可以理解为实现了类似@Service,@Component等注解的功能。

既然是动态注册Bean,那么注册了哪些Bean呢?我们来看下方法registerBeanDefinitions的实现

方法的逻辑很简单,new了一个RepositoryConfigurationDelegate对象,并且调用了其中registerRepositoriesIn的方法。

我们再来看下getConfigurationSource方法,它生成了AnnotationRepositoryConfigurationSource对象。它保存了构建repository所需的相关配置,包括basePackages,即repository所在包路径

我们再看下getConfiguration以及getAnnotation方法,JpaRepositoriesAutoConfigureRegistrar覆写了这两个方法


结合AnnotationRepositoryConfigurationSource的实现,可知它通过解析@EnableJpaRepositories注解来获取构建repository所需的配置。

在了解注册逻辑之前,我们先来看下@EnableJpaRepositories包含了哪些配置。毕竟在做一道菜之前,我们首先需要了解做菜所需的材料。

EnableJpaRepositories

attribute type default explain
value String[] {} 同basePackages
basePackages String[] {} repository所在包路径
basePackageClasses Class<?>[] {} repository所包含的class
includeFilters Filter[] {} 过滤需要处理的repository
excludeFilters Filter[] {} 过滤不需要处理的repository
repositoryFactoryBeanClass Class<?> JpaRepositoryFactoryBean.class 生成repository的工厂类
repositoryBaseClass Class<?> DefaultRepositoryBaseClass.class repository的实现类
entityManagerFactoryRef String entityManagerFactory 生成entityManager的工厂类
transactionManagerRef String transactionManager 生成transactionManager的工厂类
bootstrapMode BootstrapMode BootstrapMode.DEFAULT repository加载模式,默认在初始化时就进行加载

RepositoryConfigurationDelegate

了解了repository注册所需的配置,我们再来看下具体的注册逻辑。

RepositoryConfigurationDelegate是一个委托对象,由它来实现真正的注册流程,具体逻辑在方法registerRepositoriesIn

我们看下关键逻辑的代码

  1. 获取所有的RepositoryConfiguration
  2. postProcess构建beanDefinition
  3. registerBeanDefinition 注册beanDefinition

可以看到1,2两步都在extension中处理,这里的extension就是JpaRepositoryConfigExtension

JpaRepositoryConfigExtension

我们来看下postProcess方法

JpaRepositoryFactoryBean

JpaRepositoryFactory

SimpleJpaRepository

总结

  1. JpaRepositoriesAutoConfiguration导入(import) JpaRepositoriesAutoConfigureRegistrar
  2. JpaRepositoriesAutoConfigureRegistrar.registerBeanDefinitions()
  3. RepositoryConfigurationDelegate.registerRepositoriesIn()
  4. JpaRepositoryConfigExtension.postProcess()
  5. JpaRepositoryFactoryBean.createRepositoryFactory()
  6. JpaRepositoryFactory.getRepository()

Previous
BlockingQueue介绍 BlockingQueue介绍
简介BlockingQueue是java.util.concurrent中的类。通过包名也知道它与并发有关。在学习并发的过程中,我相信大家都听过生产者消费者模型。BlockingQueue可以帮助我们来实现这样一个模型。从数据结构的角度来说
2020-05-10
Next
Spring Boot JPA--命名策略 Spring Boot JPA--命名策略
废话不多说,先来看下例子,首先定义一个Entity @Entity @Getter @Setter public class User { @Id @GeneratedValue(strategy = GenerationT
2020-04-11