打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
程序员应知应会之Spring Data Jpa为什么不用写@Repository注解?

大家知道,在Springboot+Spring Data Jpa的项目里,dao层只需要继承JpaRepository接口,就可以实现Mybatis@Repository+mapper的效果,不需要任何多余的配置,就可以将dao层注入bean。类似于这样:

public interface BookRepository extends JpaRepository<Book, Long>

这样一句话,就可以实现很多的增删改查效果,例如findAll()findById()等等,可以说是非常的简单高效。

那么很多刚开始用Spring Data Jpa的同学就会很不理解,为什么这样一句话,就可以实现那么多的功能呢,不添加一个@Repository,心里总有些不踏实的感觉。

那么我们来看一下,Spring Data Jpa是怎么做到的。

一、JpaRepository的继承结构

首先我们来看看JpaRepository的继承结构。很容易看到JpaRepository的定义:

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>

可以看到JpaRepository继承了两个接口,一个PagingAndSortingRepository和一个QueryByExampleExecutor

这两个接口的定义分别是:

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID>

public interface QueryByExampleExecutor<T>

CrudRepository的定义为

public interface CrudRepository<T, ID> extends Repository<T, ID> 

可以看到,最终的继承结果继承到了Repository里面。

而这一系列的继承,就为我们提供了

save(S entity);

saveAll(Iterable<S> entities);

findById(ID id);

existsById(ID id);

findAll();

findAllById(Iterable<ID> ids);

count();

deleteById(ID id);

delete(T entity);

deleteAll(Iterable<? extends T> entities);

deleteAll();

findOne(Example<S> example);

findAll(Example<S> example);

findAll(Example<S> example, Sort sort);

findAll(Example<S> example, Pageable pageable);

count(Example<S> example);

exists(Example<S> example);

findAll(Sort sort);

findAll(Pageable pageable);

等很多的功能。

二、JpaRepository为什么不需要@Repository注解

经过简单的Debug,我们就可以轻松定位到Spring注入bean的位置,是在org.springframework.context.annotation包里面的
ClassPathScanningCandidateComponentProvider类中的
scanCandidateComponents方法里面,其中关键的代码在下面标蓝的
isCandidateComponent(metadataReader)判断里面。

而这个函数会将目标接口及其父接口一层层的往上对比,如果与该类自身的

includeFilters中的某个filter比中,则会返回true,意味着该实现将会作为beanSpring管理起来,从而可以直接用@Autowired引用。

那么我们先来看看includeFilters里面到底有些什么东西,查询代码可以看到,该类在初始化的时候,添加了ComponentManagedBean。很显然,这与我们的Repository还是毫无关系的。事实上也是如此,在Spring启动时,第一遍扫描并没有把我们的BookRepository注入bean

直到org.springframework.data.repository.config包中的

RepositoryConfigurationDelegate执行的时候,才会开始扫描,而这个类执行的时候,会启动一个继承了ClassPathScanningCandidateComponentProvider类的RepositoryComponentProvider。

而在这个类里面,我们可以看到Repository最终被加载到了includeFilters里面。

此时,再扫描对应的包的时候,继承自Repository的所有dao层类,就被会注入成bean,供人们调用了。

喜欢本文的话,欢迎关注活在信息时代哦:)

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
spring data jpa 利用@Query进行查询
spring-data-jpa 中文文档(1)
Spring认证中国教育管理中心-Spring Data Neo4j教程四
Spring Data JPA 指南
SpringData JPA详解
Spring Data JPA
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服