SpringBoot 自动配置:Spring Data JPA (3)

我在builder()里调试了一下代码,程序执行到该方法倒数第二行代码时,可以BeanDefinitionBuilder#beanClass就是org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean。

截屏2021-01-27 21.16.40.png


从上面两段代码分析来看,不管用户创建多少个JpaRepository,最终注入Spring容器的bean都是来自JpaRepositoryFactoryBean工厂来创建。每个开发人员自定义的JpqRepository又都是针对不同的领域模型的,比如说UserRepository,OrderRepository,OrderLineItemRepository。

使用用户自定义的JpaRepository @Autowired private BookRepository bookRepository;

当你定义了的BookRepository后,在使用时又是如何从Spring容器中获取bean的。上面既然说了BeanDefinitionBuilder会和JpaRepositoryFactoryBean建立联系,那我们还是从JpaRepositoryFactoryBean入手。

public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID> extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> { //构造函数,这里repositoryInter就是你自定义的JpaRepository public JpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) { super(repositoryInterface); } @Override protected RepositoryFactorySupport doCreateRepositoryFactory() { Assert.state(entityManager != null, "EntityManager must not be null!"); return createRepositoryFactory(entityManager); } //这个方法会返回JpaRepositoryFactory protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { JpaRepositoryFactory jpaRepositoryFactory = new JpaRepositoryFactory(entityManager); jpaRepositoryFactory.setEntityPathResolver(entityPathResolver); jpaRepositoryFactory.setEscapeCharacter(escapeCharacter); if (queryMethodFactory != null) { jpaRepositoryFactory.setQueryMethodFactory(queryMethodFactory); } return jpaRepositoryFactory; } }

截屏2021-01-27 21.30.11.png


这段代码我们会关注两个地方,一个是构造函数,构造函数的参数repositoryInterface就是用户自定义的接口,一个是createRepositoryFactory(),Spring要创建JpaRepository的实现类,会先创建一个JpaRepositoryFactory,然后具体接口的实现类,或者叫做代理会交给该工厂类实现。

public class JpaRepositoryFactory extends RepositoryFactorySupport { }

JpaRepositoryFactory继承了抽象类RepositoryFactorySupport,而RepositoryFactorySupport又实现了两个Spring接口BeanClassLoaderAware,BeanFactoryAware。

RepositoryFactorySupport位于spring-data-common.jar内。

RepositoryFactorySupport#getRepository public <T> T getRepository(Class<T> repositoryInterface, RepositoryFragments fragments) { //repositoryInterface为用户自定义的JpaRepository,这里为BookRepository。 RepositoryMetadata metadata = this.getRepositoryMetadata(repositoryInterface); RepositoryComposition composition = this.getRepositoryComposition(metadata, fragments); RepositoryInformation information = this.getRepositoryInformation(metadata, composition); this.validate(information, composition); //target为SimpleJpaRepository。 Object target = this.getTargetRepository(information); ProxyFactory result = new ProxyFactory(); result.setTarget(target); result.setInterfaces(new Class[]{repositoryInterface, Repository.class, TransactionalProxy.class}); if (MethodInvocationValidator.supports(repositoryInterface)) { result.addAdvice(new MethodInvocationValidator()); } result.addAdvisor(ExposeInvocationInterceptor.ADVISOR); this.postProcessors.forEach((processor) -> { processor.postProcess(result, information); }); if (DefaultMethodInvokingMethodInterceptor.hasDefaultMethods(repositoryInterface)) { result.addAdvice(new DefaultMethodInvokingMethodInterceptor()); } ProjectionFactory projectionFactory = this.getProjectionFactory(this.classLoader, this.beanFactory); Optional<QueryLookupStrategy> queryLookupStrategy = this.getQueryLookupStrategy(this.queryLookupStrategyKey, this.evaluationContextProvider); result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory, queryLookupStrategy, this.namedQueries, this.queryPostProcessors, this.methodInvocationListeners)); composition = composition.append(RepositoryFragment.implemented(target)); result.addAdvice(new RepositoryFactorySupport.ImplementationMethodExecutionInterceptor(information, composition, this.methodInvocationListeners)); //repository为SimpleJpaRepository T repository = result.getProxy(this.classLoader); return repository; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfpgy.html