您的位置:首页 > 编程语言 > Java开发

疯狂JAVA讲义---第十四章:APT处理annotation

2009-01-24 18:10 302 查看
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>


 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息