編譯時註解(轉)
原文http://fucknmb.com/2017/02/07/%E7%BC%96%E8%AF%91%E6%97%B6%E6%B3%A8%E8%A7%A35%E6%AD%A5%E8%B5%B0/
新建Java Module
http://fucknmb.com/2017/02/07/%E7%BC%96%E8%AF%91%E6%97%B6%E6%B3%A8%E8%A7%A35%E6%AD%A5%E8%B5%B0/new-module.png
引入auto-service(自動生成services下檔案)和javapoet(生成java檔案)
compile 'com.google.auto.service:auto-service:1.0-rc2'
compile 'com.squareup:javapoet:1.8.0'
編寫註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
@Inherited
public @interface Api {
String scope();
String name();
String version();
}
建立AbstractProcessor實現類
重寫getSupportedSourceVersion,getSupportedAnnotationTypes和process方法。注意在類上加入註解AutoService,便會自動生成META-INF下的services檔案
@AutoService(Processor.class)
public class AnnotationProcessor extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> supportedAnnotationTypes = new HashSet<>();
supportedAnnotationTypes.add(Api.class.getCanonicalName());
return supportedAnnotationTypes;
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false;
}
}
實現process方法,根據註解生成對應程式碼
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Api.class);
for (Element e : elements) {
//獲得對應的註解
Api api = e.getAnnotation(Api.class);
System.out.println("*");
//使用javapoet開始生成程式碼
TypeSpec clazz = TypeSpec.classBuilder(api.name().toUpperCase() + "Request")
.addJavadoc("Generated request for network\n")
.addSuperinterface(Serializable.class)
.build();
JavaFile javaFile = JavaFile.builder("com.funcknmb.api", clazz)
.build();
//生成的程式碼寫入檔案
try {
JavaFileObject fileObject = processingEnv.getFiler().createSourceFile("com.funcknmb.api." + api.name().toUpperCase() + "Request");
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + fileObject.toUri());
Writer writer = fileObject.openWriter();
javaFile.writeTo(writer);
writer.close();
} catch (IOException x) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, x.toString());
}
}
return false;
}
總結
編寫的註解以及process的實現只是做個模板,具體情況視情況而定。
相關文章
- 編譯時註解之APT編譯APT
- Android編譯時註解框架系列1-什麼是編譯時註解Android編譯框架
- 【Android】註解框架(三) 編譯時註解,手寫ButterKnifeAndroid框架編譯
- Android 編譯時註解-初認識Android編譯
- Android 如何編寫基於編譯時註解的專案Android編譯
- 重走JAVA之路(一):覆盤ButterKnife-編譯時註解Java編譯
- 【寫框架】基於編譯時註解打造ActivityBus,一鍵傳值框架編譯
- Android 打造編譯時註解解析框架 這只是一個開始Android編譯框架
- 在使用make編譯時,修改原始檔的註釋內容,是否會重新編譯?編譯
- MySQL5.5原始碼編譯新增編譯備註資訊~MySql原始碼編譯
- Android註解使用之註解編譯android-apt如何切換到annotationProcessorAndroid編譯APT
- [轉]:xmake編譯配置過程詳解編譯
- 手把手教你實現Android編譯期註解Android編譯
- NET編譯時都做了一些什麼 (轉)編譯
- 執行時框架,編譯時框架框架編譯
- nodejsless及時編譯NodeJS編譯
- koala 編譯scss不支援中文(包括中文註釋),解決方案如下編譯CSS
- [譯] 優化 Swift 的編譯時間優化Swift編譯
- PHP編譯安裝時常見錯誤解決辦法,php編譯常見錯誤PHP編譯
- lamp編譯詳解LAMP編譯
- oracle 儲存過程不能編譯-- (編譯的同時正在訪問所導致的) [轉載]Oracle儲存過程編譯
- 為什麼編譯的時候把mod_cookies編譯進去了,但是cookies還是不能(轉)編譯Cookie
- 【譯】8. Java反射——註解Java反射
- Flutter-一行註解直接編譯生成資源配置檔案Flutter編譯
- ffmpeg iOS平臺編譯 指令碼註釋iOS編譯指令碼
- Go 編譯時加入版本資訊Go編譯
- 為什麼編譯的時候把mod_cookies編譯進去了,但是cookies還是不能用(轉)編譯Cookie
- 提前編譯:AOT-Native Image 和執行時編譯 JIT編譯
- FreeBSD中的GNU C編譯器--編譯器GCC(轉)編譯GC
- 安卓反編譯詳解安卓編譯
- Linux作業系統核心編譯詳解(2)(轉)Linux作業系統編譯
- 【譯】Spring的@EnableCaching註解Spring
- 重編譯 invalid 物件(轉)編譯物件
- gcc最佳編譯引數(轉)GC編譯
- glade 編譯過程 (轉)編譯
- 關於預編譯頭 (轉)編譯
- 安裝 GCC 編譯器(轉)GC編譯
- 編譯器-Javac.exe(轉)編譯Java