标签:
我们实现一个完整的一个例子,那么基本了解了其运行机制。
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