qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

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

          前言:

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

            基本語(yǔ)法:

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

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

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

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

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

            四種元注解:

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

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

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

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

            RUNTIME,VM將在運(yùn)行期間也保留注解,可以使用反射機(jī)制讀取注解信息

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

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

            定義注解:

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

            如下所示:

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

            使用注解:

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

            注解是不能繼承的。

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

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

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

          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ù)庫(kù)約束信息嵌入其中
                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;
          }

           實(shí)體使用注解:這里是運(yùn)用了運(yùn)行時(shí)候處理注解,所以RetentionPolicy.RUNTIME

          package whut.annotationDB; 
          @DBTable(name="MEMBER") 
          public class Member { 
              //在使用注解過(guò)程中,如果有元素是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實(shí)現(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; 
                  } 
              } 
              //實(shí)現(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<?>必須用這個(gè)表明 
              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)沒(méi)有設(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)有注解的時(shí)候 
                          if (anns.length >= 1) { 
                              // 判斷注解的類型 
                              if (anns[0] instanceof SQLInteger) { 
                                  SQLInteger sInt = (SQLInteger) anns[0]; 
                                  // 當(dāng)沒(méi)有name時(shí)候,將字段大寫為列名 
                                  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)沒(méi)有name時(shí)候,將字段大寫為列名 
                                  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 + ","); 
                      // 移除最后一個(gè),號(hào) 
                      String tableSQL = createDB.substring(0, createDB.length() - 1) 
                              + ");"; 
                      // 輸出創(chuàng)建表的過(guò)程 
                      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) 評(píng)論(0)  編輯  收藏


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


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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 隆昌县| 丹巴县| 冕宁县| 绩溪县| 东乌| 兴安盟| 额尔古纳市| 龙胜| 南部县| 连南| 远安县| 新丰县| 五莲县| 江山市| 石泉县| 乌苏市| 突泉县| 南安市| 连平县| 湟中县| 天祝| 鄂伦春自治旗| 洛南县| 土默特右旗| 伊川县| 云梦县| 赣榆县| 府谷县| 武城县| 九龙城区| 玛曲县| 平湖市| 尉犁县| 淅川县| 溧阳市| 开封市| 建水县| 凤阳县| 高密市| 新龙县| 会宁县|