背景
接上文:
Spring Data JPA 简单介绍
本文将从配置解析,Bean的创建,Repository执行三个方面来简单介绍下Spring Data JPA的代码实现
友情提醒:
图片均可放大
配置解析
1. parser类
     
         
                | 
             Spring通过Schema的方式进行配置,通过AbstractRepositoryConfigDefinitionParser进行解析。其中包含对NamedQuery的解析。 
             解析的主要目的,是将配置文件中的repositories和repository元素信息分别解析成GlobalRepositoryConfigInformation和SingleRepositoryConfigInformation。 
             详见下图 | 
         
     
     
     
2. Information
     
         
               
              | 
             CommonRepositoryConfigInformation: 
             xml中repositories的通用配置,一般对应其中的attributes 
             SingleRepositoryConfigInformation: 
             xml中repository的配置信息,对应其中的attributes 
             GlobalRepositoryCOnfigInformation: 
             一组SingleRepositoryConfigInfomation信息,包含所有的Single信息 
             在JPA实现中,针对Single,有两份实现,一份是自动配置信息,一份是手动配置信息,分别对应图中的Automatic和Manual。 
             SimpleJpaRepositoryConfiguration是JPA中的所有配置信息,包含所有的Jpa中的SingleRepositoryConfigInformation。 | 
         
     
3. Query Lookup Strategy
   | CreateQueryLookupStrategy:对应repositories元素query-lookup-strategy的create值,主要针对method query方式 DeclaredQueryLookupStrategy:对应use-declared-query值,主要针对带有@Query注解的查询方式 CreateIfNotFoundQueryLookupStrategy:对应create-if-not-found值(default值),结合了上述两种方式  | 
Bean的创建
     
         
               
              | 
         
         
             主要包含两个类 
             RepositoryFactoryBeanSupport, Spring Factory Bean,用于创建Reposiory代理类。其本身并不真正做代理的事情,只是接受Spring的配置,具体交由RepositoryFactorySupport进行代理工作 
             RepositoryFactorySupport, 真正做Repository代理工作,根据JpaRepositoryFactoryBean的定义找到TargetClass:SimpleJpaRepository实现类,中间加入3个拦截器,一个是异常翻译,一个是事务管理,最后一个是QueryExecutorMethodInterceptor。 
             QueryExecutorMethodInterceptor是个重点,主要做特定的Query(查询语句)的操作。 | 
         
     
Repository执行
1. 主要执行类
     
         
                | 
             在看上面Bean定义的时候,其实已经明白了执行过程: 1. 将JPA CRUD规范相关的方法交给SimpleJpaRepository这个类执行 2. 将特殊查询相关的交给QueryExecutorMethodInterceptor执行。主要做自定义实现的部分,method query部分和named query部分。 具体查询类详见下图。 | 
         
     
2. 查询相关
  | 主要支持NamedQuery和JPA Query。 | 
主要执行代码
QueryExecutorMethodInterceptor#invoke(MethodInvocation invocation)
 1 public Object invoke(MethodInvocation invocation) throws Throwable {
 2 
 3             Method method = invocation.getMethod();
 4 
 5             if (isCustomMethodInvocation(invocation)) {
 6                 Method actualMethod = repositoryInformation.getTargetClassMethod(method);
 7                 makeAccessible(actualMethod);
 8                 return executeMethodOn(customImplementation, actualMethod,
 9                         invocation.getArguments());
10             }
11 
12             if (hasQueryFor(method)) {
13                 return queries.get(method).execute(invocation.getArguments());
14             }
15 
16             // Lookup actual method as it might be redeclared in the interface
17             // and we have to use the repository instance nevertheless
18             Method actualMethod = repositoryInformation.getTargetClassMethod(method);
19             return executeMethodOn(target, actualMethod,
20                     invocation.getArguments());
21         }
主要分3个步骤:
1. 如果配置文件中执行了接口类的实现类,则直接交给实现类处理
2. 判断是查询方法的,交给RepositoryQuery实现,具体又分:NamedQuery,SimpleJpaQuery,PartTreeJpaQuery
3. 不属于上述两个,则直接将其交给真正的targetClass执行,在JPA中,就交给SimpleJpaRepository执行。
本文并没有做详细的分析,只是将核心的组件类一一点到,方便大家自行深入了解代码。