簡(jiǎn)介
本篇文章主要介紹GreenDao的代碼生成策略的實(shí)現(xiàn)方式,以及介紹Android中常用開(kāi)源框架的代碼生成策略,通過(guò)對(duì)GreenDao代碼生成方法的研究和學(xué)習(xí),提升自我編程能力,嘗試編寫(xiě)代碼生成框架的目的。
本文是介紹GreenDao系列文章的第二篇,前面一篇是對(duì)GreenDao框架的介紹,以及GreenDao的使用。后面還會(huì)有一篇是對(duì)GreenDao與數(shù)據(jù)庫(kù)打交道相關(guān)的講解。
目錄
- 1.GreenDao結(jié)構(gòu)
- 2.GreenDao頂級(jí)視圖
- 3.GreenDao代碼生成流程圖
- 4.Gradle 插件相關(guān)
- 5.Android注解相關(guān)
- 6.代碼生成框架FreeMarker
- 7.相關(guān)參考
1.GreenDao結(jié)構(gòu)

GreenDao框架中組件共有6個(gè),這其中不僅包含咱們引入的工程中的代碼也包含GreenDao使用gradle的插件執(zhí)行代碼,代碼對(duì)比工具、注解生成對(duì)象的相關(guān)。
Android中使用比較常見(jiàn)的注解處理器是APT,但是GreenDao使用的是JDT。
GreenDao官方提供的是代碼開(kāi)源,但是在GreenDao的GitHub只提供了greendao、greendao-api、greendao-generator這三個(gè)模塊,另外三個(gè)模塊在Gradle的cache文件夾中也是找不到源碼的,要想學(xué)習(xí)這部分源碼只能反編譯和分析來(lái)解決。
2.GreenDao頂級(jí)視圖

上圖對(duì)照著GreenDao的整體架構(gòu)進(jìn)行分析,繪制出來(lái)的GreenDao整體結(jié)構(gòu)圖。包含GreenDao的各個(gè)組件以及開(kāi)發(fā)者使用GreenDao中的注解編寫(xiě)代碼,注解生成的代碼和GreenDao的配合完成程序與數(shù)據(jù)庫(kù)打交道的工作。
先從左上角的模塊開(kāi)始,original-model是android開(kāi)發(fā)者使用GreenDao的注解編寫(xiě)代碼,編寫(xiě)出最原始的model類,添加上GreenDao的注解。這時(shí)候GreenDao的使用者就初步完成了工作。
再看左上角的greendao-api 注解即標(biāo)準(zhǔn),所謂的GreenDao注解就是在這里定義的,開(kāi)發(fā)者依據(jù)greendao-api中的注解添加到的model中,GreenDao代碼生成相關(guān)模塊也是依據(jù)greendao-api中的注解來(lái)生成對(duì)應(yīng)的dao代碼。到此GreenDao的代碼編寫(xiě)和生成代碼邏輯似乎有一些眉目了。
再來(lái)看結(jié)構(gòu)圖的右上這部分模塊,greendao-gradle-plugin模塊是Gradle的插件。就是android在編譯時(shí)使用的編譯工具Gradle,別和GreenDao弄混了。使用Gradle插件的目的是每次在編譯的時(shí)候,就會(huì)有相關(guān)執(zhí)行代碼的入口,GreenDao就可以在這個(gè)時(shí)機(jī)來(lái)生成代碼。提醒開(kāi)發(fā)者注意的是Gradle的插件是在編譯期執(zhí)行的,就意味著不會(huì)影響app代碼在用戶手機(jī)的運(yùn)行效率,但是會(huì)影響apk的編譯速度。在選擇使用GreenDao的時(shí)候也要考慮這方面的因素。
使用GreenDao除了官方樣例那樣全部引入以外,還有另外一種方案,就是用Demo工程去生成代碼,再將生成出來(lái)的代碼copy到主工程中使用,主工程只依賴greendao-core和greendao-api,GreenDao的Gradle插件在主工程并不使用,在Demo工程執(zhí)行插件生成代碼的工作。此方法提供給大家參考和選擇。
greendao-code-modifier是代碼自動(dòng)生成模塊的中間控制者,比對(duì)代碼中的注解是否需要重新生成,調(diào)用greenrobot-jdt收集代碼中的注解信息。
greendao-code-modifier模塊調(diào)用greendao-generator來(lái)生成對(duì)應(yīng)的代碼,greendao使用的代碼生成模板為freemarker開(kāi)源框架。
結(jié)構(gòu)圖的下半部分是與數(shù)據(jù)庫(kù)打交道的部分,也就是實(shí)際代碼運(yùn)行的部分,最上面的是生成的代碼DaoMaster、DaoSession、Dao,一般會(huì)生成這三個(gè)類,在一定條件下還會(huì)生成entity和content-provider、dao-unit-test相關(guān)的代碼。
下半部分的中間是greendao-core模塊,就是生成的代碼與greendao-core代碼配合實(shí)現(xiàn)與最底下的SQLlite通訊完成數(shù)據(jù)庫(kù)相關(guān)的操作。
3.GreenDao代碼生成流程圖

以上是GreenDao相關(guān)的代碼生成的實(shí)現(xiàn),下面是相關(guān)技術(shù)點(diǎn)的介紹,如果有對(duì)下面的技術(shù)點(diǎn)了解的可以跳過(guò)其中的章節(jié)。
4.Gradle 插件相關(guān)
如何開(kāi)發(fā)一個(gè)gradle plugin,網(wǎng)上例子很多,這里簡(jiǎn)單列舉自定義Gradle plugin插件的步驟
- 1.新建module,刪除module中大部分內(nèi)容。
- 2.新建MyPlugin.groovy,實(shí)現(xiàn)org.gradle.api.Plugin接口,apply入口方法。
- 3.建立resources目錄、創(chuàng)建.properties文件.
- 4.配置gradle文件、上傳maven庫(kù)。
- 5執(zhí)行插件。
注意:這里properties的名字及里邊的配置,以及Gradle文件中的配置只有實(shí)踐嘗試了之后才能搞明白都是做什么用的。在本篇文章的最后面有參考自定義Gradle的插件的鏈接,可以學(xué)習(xí)一下。
GreenDao的Gradle插件的代碼是
greendao-gradle-plugin-3.2.2.jar --> Greendao3GradlePlugin
5.Android注解相關(guān)
這部分是對(duì)注解和注解處理器做簡(jiǎn)單的介紹,有了這些基礎(chǔ)才能對(duì)GreenDao中注解相關(guān)知識(shí)分析明白,以及研究明白這些代碼是怎么串聯(lián)起來(lái)的和這些代碼是做什么用的。如果對(duì)注解和注解處理器已經(jīng)熟悉了可以直接跳過(guò)這部分介紹。
Annotation(注解)是JDK5.0及以后版本引入的。它可以用于創(chuàng)建文檔,跟蹤代碼中的依賴性,甚至執(zhí)行基本編譯時(shí)檢查。從某些方面看,annotation就像修飾符一樣被使用,并應(yīng)用于包、類 型、構(gòu)造方法、方法、成員變量、參數(shù)、本地變量的聲明中。這些信息被存儲(chǔ)在Annotation的“name=value”結(jié)構(gòu)對(duì)中。
功能作用:
1.編寫(xiě)文檔:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)生成文檔
2.代碼分析:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)對(duì)代碼進(jìn)行分析
3.編譯檢查:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)讓編譯器能實(shí)現(xiàn)基本的編譯檢查
根據(jù)注解使用的方法和用途分類:
1.JDK內(nèi)置系統(tǒng)注解
2.元注解
3.自定義注解
元注解
1.@Target 描述注解修飾的范圍, 類、接口、包、方法等類型。
2.@Retention 注解被保留的時(shí)間長(zhǎng)短
3.@Document javadoc
4.@Inhrited 注解類的繼承關(guān)系
(注:元注解的作用就是負(fù)責(zé)注解其他注解 java 5.0定義了4個(gè))
RetentionPoicy取值
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)
GreenDao中的注解是在greendao-api-3.2.2.jar 包中定義的、全部為source級(jí)別。
開(kāi)發(fā)中常見(jiàn)的注解處理器有反射、APT、JDT等。
反射在java開(kāi)發(fā)中是比較常見(jiàn)的、apt是android開(kāi)發(fā)經(jīng)常使用的方式、jdt是eclipse開(kāi)發(fā)工具使用的處理器。這個(gè)在國(guó)內(nèi)用的比較少。JDT的介紹是我從eclipse官網(wǎng)找到的,在文章最后有相關(guān)的鏈接。
JDT為Eclipse中的Java 5項(xiàng)目添加了注釋處理支持,它提供了以下功能:
支持為Sun的命令行apt工具編寫(xiě)的運(yùn)行注釋處理器。
增量構(gòu)建期間基于注釋的構(gòu)建構(gòu)件的貢獻(xiàn)。
基于注釋的問(wèn)題的問(wèn)題標(biāo)記的貢獻(xiàn)。
GreenDao使用的注解處理器是JDT。
6.代碼生成框架FreeMarker
FreeMarker不是什么新技術(shù),在java服務(wù)端的開(kāi)發(fā)中已經(jīng)使用好多年,基本原理就是寫(xiě)一個(gè)模板,然后在模板里加入判斷和變量,支持一些基本的聲明、變量、判斷、循環(huán)等語(yǔ)法。將實(shí)體類已對(duì)象的形式作為參數(shù)傳遞到模板中,最后將對(duì)象的值和模板進(jìn)行結(jié)合生成對(duì)應(yīng)的代碼。做android的同學(xué)可以用DataBinding、MVVM來(lái)做比較學(xué)習(xí),原理相似。FreeMarker還是比較容易學(xué)習(xí),在本篇文章的最后有FreeMarker的入門(mén)文章鏈接。
在GreenDao中代碼生成邏輯是以DaoGenerator.generateAll()作為入口。使用FreeMarker實(shí)現(xiàn)的生成代碼的引擎。
生成代碼的方式有很多種,最基礎(chǔ)的是拼接字符串的形式實(shí)現(xiàn),傳入變量去拼接,然后將字符串寫(xiě)到一個(gè)文件中。還有一種生成代碼的方式叫javapoet的,使用javapoet的語(yǔ)法定義文件、類、方法,然后將方法放入類中,類放入文件中,是個(gè)挺有意思的框架,有感興趣的可以了解一下。當(dāng)然還有FreeMarker類似的框架velocity,這些都是java模板引擎生成代碼的框架。
大家可以學(xué)習(xí)完GreenDao生成代碼之后自己去練習(xí)寫(xiě)一個(gè)生成代碼的框架,已到達(dá)復(fù)用的目的,這也是高級(jí)工程師、架構(gòu)設(shè)計(jì)師的基本技能手段。
7.相關(guān)參考
GreenDao github地址
https://github.com/greenrobot/greenDAO
Gradle插件開(kāi)發(fā)
http://www.itdecent.cn/p/d53399cd507b
JDT 介紹
http://www.eclipse.org/jdt/overview.php
注解處理器
https://blog.csdn.net/u013045971/article/details/53509237
自定義注解
https://blog.csdn.net/u013045971/article/details/53433874
FreeMarker 快速入門(mén)
https://segmentfault.com/a/1190000011768799