Processor-強大的註解處理器功能


一 簡介

在上一篇文章中,google-auto之自動生成組件化文件 ,我是簡單的介紹了google的開源框架auto,其中官方的文章中,也有這麼一句話:
在這裏插入圖片描述
其實,auto的內部核心就是使用了註解處理器這個強大的jdk自帶的開源工具來實現對應類或者配置文件生成的。一番學習之後,本來自己想寫一些關於註解處理器的原理和基本的使用,但是看到網上有一篇寫的很不錯,特來記錄。

地址【Annotation】Processing-Tool詳解
(似乎這篇文章也是該作者轉載)

二 正文

1. 概念

在開始之前,我們需要聲明一件重要的事情是:我們不是在討論在運行時通過反射機制運行處理的註解,而是在討論在編譯時處理的註解。
註解處理器是 javac 自帶的一個工具,用來在編譯時期掃描處理註解信息。你可以爲某些註解註冊自己的註解處理器。註解處理器在Java 5 的時候就已經存在了,但直到 Java 6 (發佈於2006年十二月)的時候纔有可用的API。過了一段時間java的使用者們才意識到註解處理器的強大。所以最近幾年它纔開始流行。
一個特定註解的處理器以 java 源代碼(或者已編譯的字節碼)作爲輸入,然後生成一些文件(通常是.java文件)作爲輸出。那意味着什麼呢?你可以生成 java 代碼!這些 java 代碼在生成的.java文件中。因此你不能改變已經存在的java類,例如添加一個方法。這些生成的 java 文件跟其他手動編寫的 java 源代碼一樣,將會被 javac 編譯。

2.Processor

註解處理器的核心API就是Processor,但是我們在自己實現註解處理器的時候並不是實現Processor,而是實現它的抽象類AbstractProcessor 。Processor類是在rt.jar下,javax.annotation.processing包中

2.1 註解處理器的運行

註解處理器是運行在編譯中,當一個含有註解處理器的jar包被引入到另一個jar包時,進行編譯jar包的過程中,這個時候的註解處理器就進行執行。

2.2 註解處理器的定義

在這裏插入圖片描述
Processor的api文檔中,有這麼一句話,意思是Processor的發現是由一些工具來查找,並決定是否應該運行它們,對於JavaCompiler 編譯而言,你可以通過javax.tools.JavaCompiler.CompilationTask的setProcessos 方法來注入對應的註解處理器,同時你也可以使用ServiceLoad SPI 查找指定目錄下你聲明的註解處理器。如何聲明你的註解處理器呢?
首先,你必須提供一個jar文件,就像其他jar文件一樣,你將你已經編譯好的註解處理器打包到此文件中,並且,你的jar文件中,你必須打包一個特定的文件META-INF/services/javax.annotation.processing.Processor

util-processor.jar
	-com
	 -zcswl
		-processor
			-ExampleAbstractProcessor.class
	-META-INF
		-services
			-javax.annotation.processing.Processor

其中,javax.annotation.processing.Processor文件中就是你自己定義的註解處理器

com.zcswl.processor.ExampleAbstractProcessor
3.代碼

代碼演示之前,我們首先要去理解Processor中的幾個重要的接口,並理解對應接口的參數,參考對應的AbstractProcessor類
在這裏插入圖片描述

  • init(ProcessingEnvironment processingEnv):所有的註解處理器類都必須有一個無參的構造函數,然而,有一個特殊的方法init(),它會被註解處理器調用,ProcessingEnvironment提供了一些實用的工具類Elements,Types和Filer
  • process(Set<? extends TypeElement> annoations, RoundEnvironment env):這類似於每個處理器的main()方法。你可以在這個方法裏面編碼實現掃描,處理註解,生成 java 文件。使用RoundEnvironment 參數,你可以查詢被特定註解標註的元素(原文:you can query for elements annotated with a certain annotation )。
  • getSupportedAnnotationTypes():在這個方法裏面你必須指定哪些註解應該被註解處理器註冊。注意,它的返回值是一個String集合,包含了你的註解處理器想要處理的註解類型的全稱。換句話說,你在這裏定義你的註解處理器要處理哪些註解。
  • getSupportedSourceVersion():用來指定你使用的 java 版本。通常你應該返回SourceVersion.latestSupported() 。不過,如果你有足夠的理由堅持用 java 6 的話,你也可以返回SourceVersion.RELEASE_6。我建議使用SourceVersion.latestSupported()。在 Java 7 中,你也可以使用註解的方式來替代重寫getSupportedAnnotationTypes() 和 getSupportedSourceVersion()

關於註解處理器代碼的實現可以參考
google-auto:https://github.com/google/auto

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章