jpa 代理Repository原理
刚接触jpa的时候,我就被他惊艳了,心想 还写什么sql啊!!”、“还用什么mybatis啊”、”还建什么表啊!
我们写Repository 普遍继承一个JpaRepository接口,而用的时候直接注入就行了,这么玄学的吗?
原来JpaRepository接口只是它的外壳,其真正实现类是simplejpaReository ,
{$Proxy} 说明启动了代理
有注入ioc容器,我们来断一下ConfigurationClassBeanDefinitionReader.loadBeanDefinitions() 方法
扫描所以需要配置的类了但是 没有发现我们自己Repository, 因为spring 扫描有一定规则,比如扫描 @Compose,@Controller,等注解的
说明他是通过Jpa某个类 来处理的,这里我停滞了一段时间来搜索相关的信息,
发现ImportBeanDefinitionRegistrar接口 可以动态注入Bean
发现
RepositoryConfigurationSourceSupport implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware
JpaRepositoriesAutoConfigureRegistrar extends RepositoryConfigurationSourceSupport
加断点 看看
发现了新大陆extension.registerBeansForRoot(registry, configurationSource);上下文配置
RepositoryBeanDefinitionBuilder builder =new RepositoryBeanDefinitionBuilder(registry, extension, resourceLoader,environment);动态注册器
扫描Repository 具体扫描新建扫描器,并加入过滤器 扫描所继承Repository接口 并不是Jparepository哦 有的Repository @NoRepositoryBean注解 并不注入
返回到上面
扫描完成后,以我们的类名为Beanname,BeanDefinition为JpaRepositoryFactoryBean
JpaRepositoryFactoryBean关系图发现实现了InitializingBean接口,忍住激动继续走
Spring 中AbstractAutowireCapableBeanFactory类中的invokeInitMethods 调用我们的afterPropertiesSet() 来初始化Bean
判断是否实现了InitializingBean 设置代理Object target = getTargetRepository(information); 通过获取SimpleJpaRepository 我们可以重写这个方法 来获得自定义的类
result.addAdvice 来实现我们自定义的方法的
总结:
spring boot @EnableAutoConfiguration 扫描 spring.factories文件 JpaRepositoriesAutoConfiguration 这Jpa的配置类
IOC容器再过 configClass.getImportBeanDefinitionRegistrars() 获取JpaRepositoriesAutoConfigureRegistrar 再注册我们自己自定义的Repository
以我们的类名为Beanname,BeanDefinition为JpaRepositoryFactoryBean
然后 对Bean进一步处理 afterPropertiesSet() 设置代理 处理自定义方法
篇幅原因,就分析到这了吧
未经本人同意 不能转载