标签:
我们实现一个完整的一个例子,那么基本了解了其运行机制。
1 创建一个处理注解的项目

依次为一个注解,一个注解处理器,一个注解路径配置文件(供编译器识别)。
注解Seriable代码:
@Target({ ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.CLASS)
public @interface Seriable {
}
@Retention标明生命周期,
RetentionPolicy.CLASS //表示注解是在编译期处理
这个配置文件的内容是BeanProcessor.java的完整路径:com.zhy.annotationprocess.processor.BeanProcessor.
这个BeanProcessor.java的代码为:
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class BeanProcessor extends AbstractProcessor { // 元素操作的辅助类
Elements elementUtils;
ProcessingEnvironment processingEnv;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
// 元素操作的辅助类
elementUtils = processingEnv.getElementUtils();
this.processingEnv = processingEnv;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> typeSet = new LinkedHashSet<String>();
typeSet.add(Seriable.class.getCanonicalName());
return typeSet;
}
@SuppressWarnings("resource")
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
processingEnv.getMessager().printMessage(Kind.ERROR, "12346789");
// 获得被该注解声明的元素
Set<? extends Element> elememts = roundEnv
.getElementsAnnotatedWith(Seriable.class);
TypeElement classElement = null;// 声明类元素
List<VariableElement> fields = null;// 声明一个存放成员变量的列表
// 存放二者
Map<String, List<VariableElement>> maps = new HashMap<String, List<VariableElement>>();
try {
// 遍历
File file = new File("f:/test.txt");
FileWriter fWriter = null;
fWriter = new FileWriter(file,true);
FileOutputStream outputStream = new FileOutputStream(file,true);
outputStream.write((" ======elememts size : " +elememts.size()+ "\n").getBytes());
int i = 1;
for (Element ele : elememts) {
//processingEnv.getMessager().printMessage(Kind.ERROR, "12346789",ele);
outputStream.write((" ======start\n").getBytes());
outputStream.write((" element name:" + ele.getSimpleName() + " index:" + i + "\n").getBytes());
outputStream.write((" element enclose_name:"+ele.getEnclosingElement().getSimpleName()+"\n").getBytes());
outputStream.write(( "element kind:" + ele.getKind().name() + "\n").getBytes());
outputStream.write(( " element type:" + ele.asType().getKind().name() + "\n").getBytes());
outputStream.write(("========end\n").getBytes());
i++;
}
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
然后将其打成一个jar。
2 创建一个测试简单注解框架的项目

percent_1.jar就是刚才打的jar包
Article.java和User.java的代码分别为:
@Seriable
public class Article
{
private String title ;
private String content ;
}
public class User
{
@Seriable
int username123;
@Seriable
String password123;
private String three;
private String four;
}
对AnntotaionTest1项目配置,使编译器能识别jar中的注解处理器BeanProcessor。


配置完之后回头看BeanProcessor,编译器识别它之后,会调用它的process(...)入口,根据代码会在F盘创建一个test.txt文件,里面打印了被注解的元素的信息。现在我们来看一下这个文件的内容:
======elememts size : 3
======start
element name:username123 index:1
element enclose_name:User
element kind:FIELD
element type:INT
========end
======start
element name:Article index:2
element enclose_name:com
element kind:CLASS
element type:DECLARED
========end
======start
element name:password123 index:3
element enclose_name:User
element kind:FIELD
element type:DECLARED
========end
======elememts size : 0
果然打印出了3条注解元素的信息,这和我们在User和Article注解的元素一一对应。
这里解释一下:element name的值意思为注解元素的名称,element enclose_name:是封装这个元素的实体名称,element kind的值被注解元素的角色,字段或者类等其他,element type:的值表示被注解元素的类型,username123被定义成int,它的type就为INT,password123被定义成String,它的type就为DECLARED。至此简单的编译注解完成测试。在写注解处理器的时候有一点要注意,就是必须实现getSupportedAnnotationTypes()方法
标签:
原文地址:http://my.oschina.net/u/1463920/blog/512704