大junjun的java小屋

          成長之路

          常用鏈接

          統(tǒng)計

          最新評論

          Java注解annotation用法和自定義注解處理器(轉(zhuǎn)載)

          轉(zhuǎn)自: http://computerdragon.blog.51cto.com/6235984/1210969

          前言:
          在J2EE中,注解使得開發(fā)更加便利,省去了生成XML文件的過程,在Hibernate實體聲明中,可以簡簡單單的用幾個注解就可以免去生成一個XML的文件操作。這里就主要論述一下annotation的用法和自定義注解處理器。當(dāng)在創(chuàng)建描述符性質(zhì)的類或接口時,有大量重復(fù)性的工作時候,就可以利用注解來實現(xiàn)。

          基本語法:

            Java目前包括三種標(biāo)準(zhǔn)注解和四種元注解。元注解主要負(fù)責(zé)注解其他注解的。

            三種標(biāo)準(zhǔn)注解:

          @Override,表示當(dāng)前的方法定義覆蓋了父類中的方法。必須要有相同的方法簽名即(方法名,參數(shù)類型,參數(shù)順序,參數(shù)個數(shù))都一樣。否則在編譯過程中發(fā)出錯誤提示。

          @Deprecated,對不應(yīng)該再使用的方法添加注解,當(dāng)使用這個方法的時候,會在編譯時候顯示提示信息。

          @SuppressWarnings,關(guān)閉不當(dāng)?shù)木幾g器報警信息

          四種元注解:

            @Target,表示該注解可以用什么地方。

          如CONSTRUCTOR,構(gòu)造器聲明;FIELD,域聲明;METHOD,方法聲明;TYPE,類,接口或enum聲明

            @Retention,表示需要在什么級別保存該注解信息。

             如SOURCE,注解將被編譯器丟棄;CLASS,注解在class文件可用,但會被VM丟棄

          RUNTIME,VM將在運行期間也保留注解,可以使用反射機制讀取注解信息

            @Documented,將此注解包含到Javadoc中。

            @Inherited,允許子類繼承父類的注解。

          定義注解:

          自定義注解是以@interface為標(biāo)志的。如同一個接口的定義,這里面定義的每個方法名,就是使用注解時候的元素名,方法的返回值就是元素的類型,可以利用default來聲明默認(rèn)值,不過對于非基本類型,不能設(shè)置為null為默認(rèn)值,一般對于字符串使用空字符串作為其默認(rèn)值。

          如下所示:


          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          package whut.annotation;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          //定義一個注解
          @Target(ElementType.METHOD)//定義該注解將應(yīng)用于什么地方,方法或者域
          @Retention(RetentionPolicy.RUNTIME)//定義該注解在哪一個級別可用
          public @interface UseCase {
              //注解元素,可以指定默認(rèn)值,在使用注解的時候,可以直接給元素賦值如id=5
              public int id();
              public String description() default "no description";
               //利用枚舉來設(shè)置參數(shù)類型
               public enum ParameterType { STRING, SHORT, INT, BOOL, LONG, OBJECT };
               // 默認(rèn)值,在使用注解的時候,只需要為元素賦值
               public ParameterType type() default ParameterType.STRING;
          }

          使用注解:

          在類中任意的域值前,或者方法前等直接@注解名,如@UseCase(id=5),使用注解的過程中,必須對于沒有設(shè)置默認(rèn)值的元素進(jìn)行賦值操作,對于每個元素進(jìn)行按照名-值對的方式賦值。如果在注解定義中有名為value的元素,并且它是唯一需要賦值的,可以直接在括號里給出value所需要的值。

              注解是不能繼承的。

          下面是一個基本的利用非apt實現(xiàn)的注解處理器模型。

          這個模型可以注解實體,進(jìn)行數(shù)據(jù)庫的映射建表操作。是最最基本的操作。

          注解定義:將四個注解名是在不同的文件中。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)
          @Retention(RetentionPolicy.RUNTIME)
          //定義字段的約束
          public @interface Constraints {
              boolean primaryKey() default false;
              boolean allowNull() default true;
              boolean unique() default false;
          }
          ////////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.TYPE)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          //定義表名的注解
          public @interface DBTable {
              public String name() default "";
          }
          ///////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          public @interface SQLInteger {
                String name() default "";
                //嵌套注解的功能,將column類型的數(shù)據(jù)庫約束信息嵌入其中
                Constraints constraints() default @Constraints;
          }
          ///////////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          public @interface SQLString {
              int value() default 0;
              String name() default "";
              //注解元素中引用別的注解,
              Constraints constraints() default @Constraints;
          }

          實體使用注解:這里是運用了運行時候處理注解,所以RetentionPolicy.RUNTIME

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          package whut.annotationDB;
          @DBTable(name="MEMBER")
          public class Member {
              //在使用注解過程中,如果有元素是value,并且只有value需要賦值,
              //則只需要在()中將值寫入
              @SQLString(30)
              private String firstName;
              @SQLString(50)
              private String lastName;
              @SQLInteger
              private Integer age;
              @SQLString(value=30,constraints=@Constraints(primaryKey=true))
              private String handle;
              public String getFirstName() {
                  return firstName;
              }
              public void setFirstName(String firstName) {
                  this.firstName = firstName;
              }
              public String getLastName() {
                  return lastName;
              }
              public void setLastName(String lastName) {
                  this.lastName = lastName;
              }
              public Integer getAge() {
                  return age;
              }
              public void setAge(Integer age) {
                  this.age = age;
              }
              public String getHandle() {
                  return handle;
              }
              public void setHandle(String handle) {
                  this.handle = handle;
              }
          }

          具體的非apt實現(xiàn)的注解處理器:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121
          122
          123
          124
          125
          126
          127
          128
          129
          package whut.annotationDB;
          import java.lang.annotation.Annotation;
          import java.lang.reflect.Field;
          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.util.ArrayList;
          import java.util.List;
          public class TableCreator {
              public Connection getConnection() {
                  String user = "root";
                  String password = "";
                  String serverUrl = "jdbc:mysql://localhost:3306/carrent?user=root&password=";
                  try {
                      Class.forName("com.mysql.jdbc.Driver");
                      Connection con = DriverManager.getConnection(serverUrl, user,
                              password);
                      return con;
                  } catch (Exception e) {
                      e.printStackTrace();
                      return null;
                  }
              }
              //實現(xiàn)創(chuàng)建表
              public static void main(String[] args) {
                  TableCreator tc = new TableCreator();
                  tc.executeCreateDB(Member.class);
              }
              public void executeCreateDB(Class<?> entity) {
                  String sqlStr = explainAnnotation(entity);
                  Connection con = getConnection();
                  PreparedStatement psql = null;
                  if (con != null && !sqlStr.equals("error")) {
                      try {
                          psql = con.prepareStatement(sqlStr);
                          psql.execute();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      } catch (Exception e) {
                          e.printStackTrace();
                      } finally {
                          try {
                              if (psql != null)
                                  psql.close();
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
                          try {
                              if (con != null)
                                  psql.close();
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
                      }
                  } else
                      System.out.println("failure to...");
              }
              // 真正的處理器,Class<?>必須用這個表明
              public String explainAnnotation(Class<?> entity) {
                  // 獲取指定類型的注解
                  DBTable dbtable = entity.getAnnotation(DBTable.class);
                  if (dbtable == null) {
                      System.out.println("No DBTable annotation in class"
                              + entity.getName());
                      return "error";
                  } else {
                      String tableName = dbtable.name();// 獲取注解name值,即表名稱
                      // 當(dāng)沒有設(shè)置name值,直接利用類的名作為表名
                      if (tableName.length() < 1)
                          tableName = entity.getName().toUpperCase();// 轉(zhuǎn)換大寫
                      // 準(zhǔn)備處理字段注解
                      List<String> columnsDefs = new ArrayList<String>();
                      // 獲取該類的所有字段
                      for (Field field : entity.getDeclaredFields()) {
                          String columnName = null;
                          // 獲取該字段所有的注解
                          Annotation[] anns = field.getDeclaredAnnotations();
                          // Annotation[] anns=field.getAnnotations();
                          // 當(dāng)有注解的時候
                          if (anns.length >= 1) {
                              // 判斷注解的類型
                              if (anns[0] instanceof SQLInteger) {
                                  SQLInteger sInt = (SQLInteger) anns[0];
                                  // 當(dāng)沒有name時候,將字段大寫為列名
                                  if (sInt.name().length() < 1)
                                      columnName = field.getName().toUpperCase();
                                  else
                                      columnName = sInt.name();
                                  columnsDefs.add(columnName + " INT"
                                          + getConstraints(sInt.constraints()));
                              }
                              if (anns[0] instanceof SQLString) {
                                  SQLString sString = (SQLString) anns[0];
                                  // 當(dāng)沒有name時候,將字段大寫為列名
                                  if (sString.name().length() < 1)
                                      columnName = field.getName().toUpperCase();
                                  else
                                      columnName = sString.name();
                                  columnsDefs.add(columnName + " VARCHAR("
                                          + sString.value() + ")"
                                          + getConstraints(sString.constraints()));
                              }
                          }
                      }
                      StringBuilder createDB = new StringBuilder("CREATE TABLE "
                              + tableName + "(");
                      for (String cols : columnsDefs)
                          createDB.append(" " + cols + ",");
                      // 移除最后一個,號
                      String tableSQL = createDB.substring(0, createDB.length() - 1)
                              + ");";
                      // 輸出創(chuàng)建表的過程
                      System.out.println("Table Creation SQL is:\n" + tableSQL);
                      return tableSQL;
                  }
              }
              // 返回指定的約束
              public String getConstraints(Constraints con) {
                  String constras = "";
                  if (!con.allowNull())
                      constras += " NOT NULL";
                  if (con.primaryKey())
                      constras += " PRIMARY KEY";
                  if (con.unique())
                      constras += " UNIQUE";
                  return constras;
              }
          }


          posted on 2013-08-21 11:12 李俊 閱讀(132) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 盐源县| 梁河县| 虎林市| 商洛市| 奉节县| 兴城市| 虞城县| 阜康市| 永昌县| 泽普县| 舟曲县| 高台县| 临沧市| 巴塘县| 沁阳市| 顺昌县| 松原市| 涞源县| 宜兰县| 昌都县| 遂宁市| 杭锦旗| 太原市| 弥勒县| 泰顺县| 德江县| 灵石县| 沾益县| 新昌县| 亚东县| 阳高县| 青州市| 泸州市| 安康市| 五寨县| 淮安市| 天台县| 枣阳市| 宣恩县| 从江县| 璧山县|