APT是一种java提供的注释处理工具,他能对annotation做额外的处理。
我们就用hibernate的annotation来做例子,eg:(代码如下,我就不多说了)
- @Documented
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.SOURCE)
- public @interface IdProperty
- {
- String column();
- String type();
- String generator();
- }
- @Documented
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.SOURCE)
- public @interface Persistent
- {
- String table();
- }
- @Documented
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.SOURCE)
- public @interface Property
- {
- String column();
- String type();
- }
以上是三个Annotation类型
- @Persistent(table="persons_table")
- public class Person
- {
- @IdProperty(column="person_id",type="integer",generator="identity")
- private int id;
- @Property(column="person_name",type="string")
- private String name;
- @Property(column="person_age",type="integer")
- private int age;
- public Person()
- {
- }
- public Person(int id , String name , int age)
- {
- this.id = id;
- this.name = name;
- this.age = age;
- }
- public void setId(int id)
- {
- this.id = id;
- }
- public int getId()
- {
- return this.id;
- }
- public void setName(String name)
- {
- this.name = name;
- }
- public String getName()
- {
- return this.name;
- }
- public void setAge(int age)
- {
- this.age = age;
- }
- public int getAge()
- {
- return this.age;
- }
- }
以上是要处理的类
- public class HibernateAnnotationProcessor implements AnnotationProcessor
- {
- //Annotation处理器环境,是该处理器与APT交互的重要途径
- private AnnotationProcessorEnvironment env;
- //构造HibernateAnnotationProcessor对象时,获得处理器环境
- public HibernateAnnotationProcessor(AnnotationProcessorEnvironment env)
- {
- this.env = env;
- }
- //循环处理每个对象
- public void process()
- {
- //遍历每个class文件
- for (TypeDeclaration t : env.getSpecifiedTypeDeclarations())
- {
- //定义一个文件输出流,用于生成额外的文件
- FileOutputStream fos = null;
- //获取正在处理的类名
- String clazzName = t.getSimpleName();
- //获取类定义前的Persistent Annotation
- Persistent per = t.getAnnotation(Persistent.class);
- //当per Annotation不为空时才继续处理
- if(per != null)
- {
- try
- {
- //创建文件输出流
- fos = new FileOutputStream(clazzName + ".hbm.xml");
- PrintStream ps = new PrintStream(fos);
- //执行输出
- ps.println("<?xml version=/"1.0/"?>");
- ps.println("<!DOCTYPE hibernate-mapping");
- ps.println(" PUBLIC /"-//Hibernate/Hibernate Mapping DTD 3.0//EN/"");
- ps.println(" /"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd/">");
- ps.println("<hibernate-mapping>");
- ps.print(" <class name=/"" + t);
- //输出per的table()的值
- ps.println("/" table=/"" + per.table() + "/">");
- for (FieldDeclaration f : t.getFields())
- {
- //获取指定FieldDeclaration前面的IdProperty Annotation
- IdProperty id = f.getAnnotation(IdProperty.class);
- //如果id Annotation不为空
- if (id != null)
- {
- //执行输出
- ps.println(" <id name=/""
- + f.getSimpleName()
- + "/" column=/"" + id.column()
- + "/" type=/"" + id.type()
- + "/">");
- ps.println(" <generator class=/""
- + id.generator() + "/"/>");
- ps.println(" </id>");
- }
- //获取指定FieldDeclaration前面的Property Annotation
- Property p = f.getAnnotation(Property.class);
- //如果p Annotation不为空
- if (p != null)
- {
- //执行输出
- ps.println(" <property name=/""
- + f.getSimpleName()
- + "/" column=/"" + p.column()
- + "/" type=/"" + p.type()
- + "/"/>");
- }
- }
- ps.println(" </class>");
- ps.println("</hibernate-mapping>");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- //关闭输出流
- try
- {
- if (fos != null)
- {
- fos.close();
- }
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- }
- }
- }
- }
- }
- public class HibernateAnnotationFactory implements AnnotationProcessorFactory
- {
- //所有支持的注释类型
- public Collection<String> supportedAnnotationTypes()
- {
- return Arrays.asList("Property" , "IdProperty" , "Persistent");
- }
- //返回所有支持的选项
- public Collection<String> supportedOptions()
- {
- return Arrays.asList(new String[0]);
- }
- //返回Annotation处理器
- public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds,
- AnnotationProcessorEnvironment env)
- {
- return new HibernateAnnotationProcessor(env);
- }
- }
处理机和工厂
最后用apt命令:apt -factory HibernateAnnotationFactory Person.java
这样就生成了hibernate的.hbm.xml文件
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping
- PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="Person" table="persons_table">
- <id name="id" column="person_id" type="integer">
- <generator class="identity"/>
- </id>
- <property name="name" column="person_name" type="string"/>
- <property name="age" column="person_age" type="integer"/>
- </class>
- </hibernate-mapping>