背景
接上文:
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執行。
本文并沒有做詳細的分析,只是將核心的組件類一一點到,方便大家自行深入了解代碼。