在使用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
注解加载BeanDefinition
BeanDefinition
Jpa 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.JpaRepositoryFactoryBean
BeanDefinition
的注册。那啥时候创建repository的呢。答案就藏在JpaRepositoryFactoryBean
的afterPropertiesSet
方法里。同样afterPropertiesSet
逻辑也是由支撑类RepositoryFactoryBeanSupport
(和JpaRepositoryFactoryBean
是父子关系)实现的。我们将断点设置在这个方法里,来看下它的调用栈。
ApplicationContext
中有感知的方法
,调用初始化方法(afterPropertiesSet
和initMehod
)afterPropertiesSet
RepositoryFactoryBeanSupport#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