我在builder()里调试了一下代码,程序执行到该方法倒数第二行代码时,可以BeanDefinitionBuilder#beanClass就是org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean。
从上面两段代码分析来看,不管用户创建多少个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; } }这段代码我们会关注两个地方,一个是构造函数,构造函数的参数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; }