stone2083

Spring Data JPA 代码分析

背景
接上文: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执行。

本文并没有做详细的分析,只是将核心的组件类一一点到,方便大家自行深入了解代码。

posted on 2011-08-25 16:28 stone2083 阅读(5120) 评论(1)  编辑  收藏 所属分类: java

Feedback

# re: Spring Data JPA 代码分析 2015-07-02 17:40 zuidaima

springdata demo教程源代码下载 :http://zuidaima.com/share/kspringdata-p1-s1.htm  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: