在使用spring-data-jpa对于dao层或者叫做数据仓库层,我们只需要定一个简单的repository接口,就能完成一些基本的curd操作。但本质上spring帮我们做了很多事情。
spring-data-jpa,使用起来更加得心应手。这是一个开启Srping JPA的代码配置的注解。这个套路在spring里面已经司空见惯。
basePackages/basePackageClasses 指定扫描repository 的包路径repositoryBaseClass 指定repository的基类,默认是SimpleJpaRepository哦。打开注解 @EnableJpaRepositories的源码发现,它的核心是导入了一个JpaRepositoriesRegistrar(jpa仓库登记员)的类。

可以看出这个登记员的核心方法是registerBeanDefinitions,我们在该方法里面设置一个断点。看下方法的调用栈信息。

refreshContext阶段ConfigurationClassPostProcessor进行处理的。@Configuration注解加载BeanDefinitionBeanDefinitionJpa Repository的登记员登记BeanDefinition 当然实际的逻辑是它的支撑类在执行。找到了口子之后,我们再来详细地分析下registerBeanDefinitions的源代码。由于贴图比较占篇幅,这段过程就以文字描述为主了。请读者对照下spring源码。
首先有个最基础的判断,只有使用EnableJpaRepositories注解,才会执行注册数据仓库的逻辑。

接着构建一个数据仓库配置代表RepositoryConfigurationDelegate 构建过程的关键信息就是填充了一个默认数据仓库配置类DefaultRepositoryConfiguration,这个是类是每个repository一个,找repository的方式很粗暴,

然后代表执行registerRepositoriesIn将BeanDefinition注册到注册中心。
delegate.registerRepositoriesIn(registry, extension);
RepositoryBeanDefinitionBuilder 依据DefaultRepositoryConfiguration创建,注意此时创建的BeanDefinition的beanClass是org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBeanBeanDefinition的注册。那啥时候创建repository的呢。答案就藏在JpaRepositoryFactoryBean的afterPropertiesSet方法里。同样afterPropertiesSet逻辑也是由支撑类RepositoryFactoryBeanSupport (和JpaRepositoryFactoryBean是父子关系)实现的。我们将断点设置在这个方法里,来看下它的调用栈。
ApplicationContext 中有感知的方法 ,调用初始化方法(afterPropertiesSet和initMehod)afterPropertiesSetRepositoryFactoryBeanSupport#afterPropertiesSet首先创建了一个数据仓库工厂(JpaRepositoryFactory)。然后调用工厂的getRepository方法,实际逻辑还是他的父类RepositoryFactorySupport中。最核心的是使用了spring aop的动态代理生成了repository实例。注意JpaRepositoryFactory的getRepositoryBaseClass方法硬编码为SimpleJpaRepository,这个类实现了常见的CURD操作。
整个过程下来。给我感受最深的就是spring代码非常条理清楚,有条不稳,层次分明 读好的源码就好像是在读一篇有理有据的议论文。这对我们在写业务代码是很有帮助的。由于本篇关注的是整个repository bean的创建过程,所以其中很多地方都是一带而过。比如spring aop的动态代理,factory bean, bean的初始化,都可以详细展开。

原文:https://www.cnblogs.com/javalunjian/p/14732419.html