stone2083

          Spring Data JPA 代碼分析

          背景
          接上文:Spring Data JPA 簡(jiǎn)單介紹
          本文將從配置解析,Bean的創(chuàng)建,Repository執(zhí)行三個(gè)方面來(lái)簡(jiǎn)單介紹下Spring Data JPA的代碼實(shí)現(xiàn)

          友情提醒:
          圖片均可放大

          配置解析
          1. parser類(lèi)
          Spring通過(guò)Schema的方式進(jìn)行配置,通過(guò)AbstractRepositoryConfigDefinitionParser進(jìn)行解析。其中包含對(duì)NamedQuery的解析。
          解析的主要目的,是將配置文件中的repositories和repository元素信息分別解析成GlobalRepositoryConfigInformation和SingleRepositoryConfigInformation。
          詳見(jiàn)下圖
          2. Information

          CommonRepositoryConfigInformation:
          xml中repositories的通用配置,一般對(duì)應(yīng)其中的attributes
          SingleRepositoryConfigInformation:
          xml中repository的配置信息,對(duì)應(yīng)其中的attributes
          GlobalRepositoryCOnfigInformation:
          一組SingleRepositoryConfigInfomation信息,包含所有的Single信息
          在JPA實(shí)現(xiàn)中,針對(duì)Single,有兩份實(shí)現(xiàn),一份是自動(dòng)配置信息,一份是手動(dòng)配置信息,分別對(duì)應(yīng)圖中的Automatic和Manual。
          SimpleJpaRepositoryConfiguration是JPA中的所有配置信息,包含所有的Jpa中的SingleRepositoryConfigInformation。
          3. Query Lookup Strategy
          CreateQueryLookupStrategy:對(duì)應(yīng)repositories元素
          query-lookup-strategy的create值,主要針對(duì)method query方式
          DeclaredQueryLookupStrategy:對(duì)應(yīng)use-declared-query值,主要針對(duì)帶有@Query注解的查詢(xún)方式
          CreateIfNotFoundQueryLookupStrategy:對(duì)應(yīng)create-if-not-found值(default值),結(jié)合了上述兩種方式


          Bean的創(chuàng)建

          主要包含兩個(gè)類(lèi)
          RepositoryFactoryBeanSupport, Spring Factory Bean,用于創(chuàng)建Reposiory代理類(lèi)。其本身并不真正做代理的事情,只是接受Spring的配置,具體交由RepositoryFactorySupport進(jìn)行代理工作
          RepositoryFactorySupport, 真正做Repository代理工作,根據(jù)JpaRepositoryFactoryBean的定義找到TargetClass:SimpleJpaRepository實(shí)現(xiàn)類(lèi),中間加入3個(gè)攔截器,一個(gè)是異常翻譯,一個(gè)是事務(wù)管理,最后一個(gè)是QueryExecutorMethodInterceptor。
          QueryExecutorMethodInterceptor是個(gè)重點(diǎn),主要做特定的Query(查詢(xún)語(yǔ)句)的操作。

          Repository執(zhí)行
          1. 主要執(zhí)行類(lèi)
          在看上面Bean定義的時(shí)候,其實(shí)已經(jīng)明白了執(zhí)行過(guò)程:
          1. 將JPA CRUD規(guī)范相關(guān)的方法交給SimpleJpaRepository這個(gè)類(lèi)執(zhí)行
          2. 將特殊查詢(xún)相關(guān)的交給QueryExecutorMethodInterceptor執(zhí)行。主要做自定義實(shí)現(xiàn)的部分,method query部分和named query部分。
          具體查詢(xún)類(lèi)詳見(jiàn)下圖。

          2. 查詢(xún)相關(guān)
          主要支持NamedQuery和JPA Query。


          主要執(zhí)行代碼
          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個(gè)步驟:
          1. 如果配置文件中執(zhí)行了接口類(lèi)的實(shí)現(xiàn)類(lèi),則直接交給實(shí)現(xiàn)類(lèi)處理
          2. 判斷是查詢(xún)方法的,交給RepositoryQuery實(shí)現(xiàn),具體又分:NamedQuery,SimpleJpaQuery,PartTreeJpaQuery
          3. 不屬于上述兩個(gè),則直接將其交給真正的targetClass執(zhí)行,在JPA中,就交給SimpleJpaRepository執(zhí)行。

          本文并沒(méi)有做詳細(xì)的分析,只是將核心的組件類(lèi)一一點(diǎn)到,方便大家自行深入了解代碼。

          posted on 2011-08-25 16:28 stone2083 閱讀(5146) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): java

          Feedback

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

          springdata demo教程源代碼下載 :http://zuidaima.com/share/kspringdata-p1-s1.htm  回復(fù)  更多評(píng)論   

          主站蜘蛛池模板: 衡山县| 广河县| 抚宁县| 登封市| 青川县| 万荣县| 津市市| 宁武县| 桂东县| 岗巴县| 年辖:市辖区| 海口市| 胶州市| 峨眉山市| 海盐县| 筠连县| 灌南县| 漯河市| 玛多县| 二手房| 黄骅市| 夹江县| 太康县| 曲周县| 台山市| 淳安县| 新源县| 蓬莱市| 长阳| 漳州市| 易门县| 平乡县| 米林县| 永济市| 谷城县| 咸阳市| 乌拉特中旗| 沂水县| 张掖市| 郓城县| 祁东县|