注意以下类都没有定义package,在默认package下。

    1.0 定义注解, 要求 RetentionPolicy.SOURCE

    1. import java.lang.annotation.*;
    2. @Target(ElementType.FIELD)
    3. @Retention(RetentionPolicy.SOURCE)
    4. @Documented
    5. public @interface Id {
    6. String column();
    7. String type();
    8. String generator();
    9. }
    1. import java.lang.annotation.*;
    2. @Target(ElementType.TYPE)
    3. @Retention(RetentionPolicy.SOURCE)
    4. @Documented
    5. public @interface Persistent {
    6. String table();
    7. }
    1. import java.lang.annotation.*;
    2. @Target(ElementType.FIELD)
    3. @Retention(RetentionPolicy.SOURCE)
    4. @Documented
    5. public @interface Property {
    6. String column();
    7. String type();
    8. }

    2.0 注解处理器
    @SupportedAnnotationTypes({“Persistent”, “Id”, “Property”}) 指明注解处理器可以处理哪些注解

    1. import javax.annotation.processing.AbstractProcessor;
    2. import javax.annotation.processing.RoundEnvironment;
    3. import javax.annotation.processing.SupportedAnnotationTypes;
    4. import javax.annotation.processing.SupportedSourceVersion;
    5. import javax.lang.model.SourceVersion;
    6. import javax.lang.model.element.Element;
    7. import javax.lang.model.element.ElementKind;
    8. import javax.lang.model.element.Name;
    9. import javax.lang.model.element.TypeElement;
    10. import java.io.FileOutputStream;
    11. import java.io.PrintStream;
    12. import java.util.Set;
    13. @SupportedSourceVersion(SourceVersion.RELEASE_8)
    14. // 指定可处理 @Persistent、@Id、@Property 三个Annotation
    15. @SupportedAnnotationTypes({"Persistent", "Id", "Property"})
    16. public class HibernateAnnotationProcessor extends AbstractProcessor {
    17. // 循环处理每个需要处理的程序对象
    18. public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    19. // 定义一个文件输出流,用于生成额外的文件
    20. PrintStream ps = null;
    21. try {
    22. // 遍历每个被 @Persistent修饰的class文件
    23. for (Element t : roundEnv.getElementsAnnotatedWith(Persistent.class)) {
    24. // 获取正在处理的类名
    25. Name clazzName = t.getSimpleName();
    26. // 获取类定义前的 @Persistent Annotation
    27. Persistent per = t.getAnnotation(Persistent.class);
    28. // 创建文件输出流
    29. ps = new PrintStream(new FileOutputStream(clazzName + ".hbm.xml"));
    30. // 执行输出
    31. ps.println("<?xml version=\"1.0\"?>");
    32. ps.println("<!DOCTYPE hibernate-mapping PUBLIC");
    33. ps.println(" \"-//Hibernate/Hibernate "
    34. + "Mapping DTD 3.0//EN\"");
    35. ps.println(" \"http://www.hibernate.org/dtd/"
    36. + "hibernate-mapping-3.0.dtd\">");
    37. ps.println("<hibernate-mapping>");
    38. ps.print(" <class name=\"" + t);
    39. // 输出per的table()的值 注解使用相当于是注解的实例,注解的实例调用注解的方法,获取传入的值
    40. ps.println("\" table=\"" + per.table() + "\">");
    41. for (Element f : t.getEnclosedElements()) {
    42. // 只处理成员变量上的Annotation
    43. if (f.getKind() == ElementKind.FIELD) {
    44. // 获取成员变量定义前的@Id Annotation
    45. Id id = f.getAnnotation(Id.class);
    46. // 当@Id Annotation存在时输出<id.../>元素
    47. if (id != null) {
    48. ps.println(" <id name=\""
    49. + f.getSimpleName()
    50. + "\" column=\"" + id.column()
    51. + "\" type=\"" + id.type()
    52. + "\">");
    53. ps.println(" <generator class=\""
    54. + id.generator() + "\"/>");
    55. ps.println(" </id>");
    56. }
    57. // 获取成员变量定义前的@Property Annotation
    58. Property p = f.getAnnotation(Property.class);
    59. // 当@Property Annotation存在时输出<property.../>元素
    60. if (p != null) {
    61. ps.println(" <property name=\""
    62. + f.getSimpleName()
    63. + "\" column=\"" + p.column()
    64. + "\" type=\"" + p.type()
    65. + "\"/>");
    66. }
    67. }
    68. }
    69. ps.println(" </class>");
    70. ps.println("</hibernate-mapping>");
    71. }
    72. } catch (Exception ex) {
    73. ex.printStackTrace();
    74. } finally {
    75. if (ps != null) {
    76. try {
    77. ps.close();
    78. } catch (Exception ex) {
    79. ex.printStackTrace();
    80. }
    81. }
    82. }
    83. return true;
    84. }
    85. }

    3.0 使用注解

    1. @Persistent(table = "person_inf")
    2. public class Person {
    3. @Id(column = "person_id", type = "integer", generator = "identity")
    4. private int id;
    5. @Property(column = "person_name", type = "string")
    6. private String name;
    7. @Property(column = "person_age", type = "integer")
    8. private int age;
    9. //无参数的构造器
    10. public Person() {
    11. }
    12. //初始化全部成员变量的构造器
    13. public Person(int id, String name, int age) {
    14. this.id = id;
    15. this.name = name;
    16. this.age = age;
    17. }
    18. public void setId(int id) {
    19. this.id = id;
    20. }
    21. public int getId() {
    22. return this.id;
    23. }
    24. public void setName(String name) {
    25. this.name = name;
    26. }
    27. public String getName() {
    28. return this.name;
    29. }
    30. public void setAge(int age) {
    31. this.age = age;
    32. }
    33. public int getAge() {
    34. return this.age;
    35. }
    36. }

    4.0 让注解处理器生效

    image.png
    首先要编译 注解和注解处理器

    1. D:\ast>javac -encoding utf-8 *.java

    此时编译 注解处理器还没有起作用,Person的编译没有触发 注解处理器的执行。
    image.png
    其次, -processor 指定注解处理器,重新编译Person.java,
    说明: -processor [,,…] 要运行的注释处理程序的名称; 绕过默认的搜索进程,默认的搜索过程是SPI原理。

    1. D:\ast>javac -encoding utf-8 -processor HibernateAnnotationProcessor Person.java

    image.png

    1. <?xml version="1.0"?>
    2. <!DOCTYPE hibernate-mapping PUBLIC
    3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    5. <hibernate-mapping>
    6. <class name="Person" table="person_inf">
    7. <id name="id" column="person_id" type="integer">
    8. <generator class="identity"/>
    9. </id>
    10. <property name="name" column="person_name" type="string"/>
    11. <property name="age" column="person_age" type="integer"/>
    12. </class>
    13. </hibernate-mapping>