qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          Java注解annotation用法和自定義注解處理器

          前言:

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

            基本語法:

            Java目前包括三種標準注解和四種元注解。元注解主要負責注解其他注解的。

            三種標準注解:

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

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

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

            四種元注解:

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

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

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

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

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

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

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

            定義注解:

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

            如下所示:

          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 {
              //注解元素,可以指定默認值,在使用注解的時候,可以直接給元素賦值如id=5
              public int id();
              public String description() default "no description";
               //利用枚舉來設(shè)置參數(shù)類型
               public enum ParameterType { STRING, SHORT, INT, BOOL, LONG, OBJECT };
               // 默認值,在使用注解的時候,只需要為元素賦值
               public ParameterType type() default ParameterType.STRING;
          }

            使用注解:

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

            注解是不能繼承的。

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

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

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

          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

          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)的注解處理器:

          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值,即表名稱 
                      // 當沒有設(shè)置name值,直接利用類的名作為表名 
                      if (tableName.length() < 1) 
                          tableName = entity.getName().toUpperCase();// 轉(zhuǎn)換大寫 
                      // 準備處理字段注解 
                      List<String> columnsDefs = new ArrayList<String>(); 
                      // 獲取該類的所有字段 
                      for (Field field : entity.getDeclaredFields()) { 
                          String columnName = null; 
                          // 獲取該字段所有的注解 
                          Annotation[] anns = field.getDeclaredAnnotations(); 
                          // Annotation[] anns=field.getAnnotations(); 
                          // 當有注解的時候 
                          if (anns.length >= 1) { 
                              // 判斷注解的類型 
                              if (anns[0] instanceof SQLInteger) { 
                                  SQLInteger sInt = (SQLInteger) anns[0]; 
                                  // 當沒有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]; 
                                  // 當沒有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-06-24 11:18 順其自然EVO 閱讀(272) 評論(0)  編輯  收藏


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


          網(wǎng)站導航:
           
          <2013年6月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          導航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 鄂州市| 南华县| 玉山县| 南丹县| 康定县| 昌邑市| 石泉县| 泸溪县| 东乡| 成都市| 玛沁县| 兴国县| 上栗县| 那坡县| 思茅市| 九龙坡区| 铜鼓县| 泉州市| 馆陶县| 宿松县| 宁城县| 灵石县| 武威市| 太原市| 乌什县| 镇巴县| 耒阳市| 偏关县| 元朗区| 冕宁县| 民丰县| 资兴市| 永吉县| 开封县| 清苑县| 鹰潭市| 兴宁市| 城固县| 冀州市| 通州区| 横峰县|