Skip to content

Commit e50a35c

Browse files
committed
完成APT 编译时注解的例子
1 parent cac662a commit e50a35c

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cn.byhieg.annotationstutorial;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Created by byhieg on 17/2/14.
10+
* Mail to byhieg@gmail.com
11+
*/
12+
13+
@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
14+
@Retention(RetentionPolicy.SOURCE)
15+
public @interface APTAnnotation {
16+
String author() default "byhieg";
17+
18+
String date();
19+
20+
String version() default "1";
21+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package cn.byhieg.annotationstutorial;
2+
3+
import javax.annotation.processing.AbstractProcessor;
4+
import javax.annotation.processing.Messager;
5+
import javax.annotation.processing.ProcessingEnvironment;
6+
import javax.annotation.processing.RoundEnvironment;
7+
import javax.lang.model.SourceVersion;
8+
import javax.lang.model.element.Element;
9+
import javax.lang.model.element.PackageElement;
10+
import javax.lang.model.element.TypeElement;
11+
import javax.tools.Diagnostic;
12+
import javax.tools.JavaFileObject;
13+
import java.io.IOException;
14+
import java.io.PrintWriter;
15+
import java.io.Writer;
16+
import java.util.Set;
17+
18+
/**
19+
* Created by byhieg on 17/2/14.
20+
* Mail to byhieg@gmail.com
21+
*/
22+
public class APTProcessor extends AbstractProcessor{
23+
24+
//类名的前缀、后缀
25+
public static final String SUFFIX = "AutoGenerate";
26+
public static final String PREFIX = "byhieg_";
27+
28+
@Override
29+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
30+
for (TypeElement typeElement : annotations) {
31+
for (Element e : roundEnv.getElementsAnnotatedWith(typeElement)) {
32+
//打印消息
33+
Messager messager = processingEnv.getMessager();
34+
messager.printMessage(Diagnostic.Kind.NOTE, "Printing:" + e.toString());
35+
messager.printMessage(Diagnostic.Kind.NOTE, "Printing:" + e.getSimpleName());
36+
messager.printMessage(Diagnostic.Kind.NOTE, "Printing:" + e.getEnclosedElements().toString());
37+
38+
//获取注解
39+
APTAnnotation aptAnnotation = e.getAnnotation(APTAnnotation.class);
40+
41+
//获取元素名并将其首字母大写
42+
String name = e.getSimpleName().toString();
43+
char c = Character.toUpperCase(name.charAt(0));
44+
name = String.valueOf(c + name.substring(1));
45+
46+
//包裹注解元素的元素, 也就是其父元素, 比如注解了成员变量或者成员函数, 其上层就是该类
47+
Element enclosingElement = e.getEnclosingElement();
48+
String enclosingQualifiedname;
49+
if (enclosingElement instanceof PackageElement) {
50+
enclosingQualifiedname = ((PackageElement) enclosingElement).getQualifiedName().toString();
51+
} else {
52+
enclosingQualifiedname = ((TypeElement) enclosingElement).getQualifiedName().toString();
53+
}
54+
try {
55+
//生成包名
56+
String generatePackageName = enclosingQualifiedname.substring(0, enclosingQualifiedname.lastIndexOf("."));
57+
58+
// 生成的类名
59+
String genarateClassName = PREFIX + enclosingElement.getSimpleName() + SUFFIX;
60+
61+
//创建Java 文件
62+
JavaFileObject f = processingEnv.getFiler().createSourceFile(genarateClassName);
63+
64+
// 在控制台输出文件路径
65+
messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + f.toUri());
66+
Writer w = f.openWriter();
67+
try {
68+
PrintWriter pw = new PrintWriter(w);
69+
pw.println("package " + generatePackageName + ";");
70+
pw.println("\npublic class " + genarateClassName + " { ");
71+
pw.println("\n /** 打印值 */");
72+
pw.println(" public static void print" + name + "() {");
73+
pw.println(" // 注解的父元素: " + enclosingElement.toString());
74+
pw.println(" System.out.println(\"代码生成的路径: " + f.toUri() + "\");");
75+
pw.println(" System.out.println(\"注解的元素: " + e.toString() + "\");");
76+
pw.println(" System.out.println(\"注解的版本: " + aptAnnotation.version() + "\");");
77+
pw.println(" System.out.println(\"注解的作者: " + aptAnnotation.author() + "\");");
78+
pw.println(" System.out.println(\"注解的日期: " + aptAnnotation.date() + "\");");
79+
80+
pw.println(" }");
81+
pw.println("}");
82+
pw.flush();
83+
} finally {
84+
w.close();
85+
}
86+
} catch (IOException e1) {
87+
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e1.toString());
88+
}
89+
}
90+
}
91+
return true;
92+
}
93+
94+
95+
@Override
96+
public Set<String> getSupportedAnnotationTypes() {
97+
return super.getSupportedAnnotationTypes();
98+
}
99+
100+
@Override
101+
public SourceVersion getSupportedSourceVersion() {
102+
return SourceVersion.latestSupported();
103+
}
104+
105+
@Override
106+
public synchronized void init(ProcessingEnvironment processingEnv) {
107+
super.init(processingEnv);
108+
}
109+
}

0 commit comments

Comments
 (0)