iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0

Auto Service Setup

Auto Service 可以幫我們註冊 Annotation processor 到 java 的 service loader 裡面,我們的 processor 就可以在 build 的時候被呼叫。首先要在 processor module 裡面 (processor/src/main/resources/META-INF/services/) 加入一個名為 javax.annotation.processing.Processor 的 configuration 檔案。這個檔案要寫你的 processor 的完整路徑,包含 package name ,完整檔案可以參考這邊

tw.ktrssreader.processor.RssAnnotationProcessor

Processor 實作

設定好 auto service 之後,我們就可以來撰寫 processor 了!我們只要透過 @AutoService 來標注我們的 processor ,在 compile 的時候就會呼叫內部的 process 方法。除了要覆寫 process 方法外,我們還要覆寫 getSupportedAnnotationTypes 來指定要處理哪些 annotation ,在這邊我們要指定之前訂好的四個 annotation : RssTagRssRawDataRssAttributeRssValue

@AutoService(Processor::class)
class RssAnnotationProcessor : AbstractProcessor() {
    override fun getSupportedAnnotationTypes(): MutableSet<String> {
        return mutableSetOf(
            RssTag::class.java.canonicalName,
            RssRawData::class.java.canonicalName,
            RssAttribute::class.java.canonicalName,
            RssValue::class.java.canonicalName
        )
    }

    override fun process(typeElementSet: MutableSet<out TypeElement>?, roundEnvironment: RoundEnvironment?): Boolean {
        ...
    }
}

接下來我們來看 process 方法裡的 RoundEnvironment ,他指的是被 annotation 標注的程式碼資訊。我們可以從中獲得被標注的元素。在產生程式碼之前,我們需要做的就是先獲得標注的結構和資訊,所以我們可以先實作一個方法來拿到標註有 @RssTag 且它的名稱是 channel的類別,先判別第一層結構。

private inline fun generateParsers(roundEnv: RoundEnvironment?, crossinline action: (Boolean, Element) -> Unit) {
    roundEnv?.getElementsAnnotatedWith(RssTag::class.java)?.forEach{
		if (it?.kind == ElementKind.CLASS) {
		            val rssTag = it.getAnnotation(RssTag::class.java)
		            val isRoot = rssTag?.name == CHANNEL
								action(isRoot,it)
		        }
		}
}

可以用 getElementsAnnotatedWith 拿到有 @RssTag 的元素,然後判斷它是不是 class 層級和它的 tag 名稱,接著就可以執行 action ,這邊把 action 定義成一個 lambda ,讓使用這個 function 的人可以自己決定要做什麼動作。


上一篇
Annotation Processor Setup
下一篇
Code Generator 結構
系列文
如何使用 Kotlin Annotation Processor 做出自己的 Custom Data Parser Library30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言