日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
聽說(shuō)你只會(huì)用注解,不會(huì)自己寫注解?那有點(diǎn)危險(xiǎn)了

Java猿的命根子!

創(chuàng)新互聯(lián)專注于海倫企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站建設(shè)。海倫網(wǎng)站建設(shè)公司,為海倫等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站建設(shè),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

自Java EE框架步入Spring Boot時(shí)代之后,注解簡(jiǎn)直是Java程序員的命根子啊,面向注解編程成了日常操作!

換句話的意思就是說(shuō):如果沒(méi)有注解,我們啥也干不了哇(滑稽)。

這豈不是很危險(xiǎn)!

所以本文來(lái)嘮一嘮關(guān)于注解的相關(guān)操作,并自己動(dòng)手來(lái)寫一個(gè)注解感受一下原理。原理性的東西掌握了,心里自然就不慌了。

注解的基本原理

首先必須要說(shuō)的是,注解它也不是什么高深的玩意兒,沒(méi)必要畏懼它!

意如其名,其本來(lái)的意思就是用來(lái)做標(biāo)注用:可以在類、字段變量、方法、接口等位置進(jìn)行一個(gè)特殊的標(biāo)記,為后續(xù)做一些諸如:代碼生成、數(shù)據(jù)校驗(yàn)、資源整合等工作做鋪墊。

對(duì)嘛,就做標(biāo)記用的嘛!

注解一旦對(duì)代碼標(biāo)注完成,后續(xù)我們就可以結(jié)合Java強(qiáng)大的反射機(jī)制,在運(yùn)行時(shí)動(dòng)態(tài)地獲取到注解的標(biāo)注信息,從而可以執(zhí)行很多其他邏輯,完成我們想要的自動(dòng)化工作。

所以,反射必須要學(xué)好!

來(lái)!動(dòng)手造一個(gè)注解

在我的前文《聽說(shuō)你還在手寫復(fù)雜的參數(shù)校驗(yàn)?》里曾經(jīng)講過(guò), Spring自身提供了非常多好用的注解可以用來(lái)方便地幫我們做數(shù)據(jù)校驗(yàn)的工作。

比如,在沒(méi)有注解加持時(shí),我們想要校驗(yàn) Student類:

 
 
 
 
  1. public class Student { 
  2.         private Long id;        // 學(xué)號(hào) 
  3.         private String name;    // 姓名 
  4.         private String mobile;  // 手機(jī)號(hào)碼(11位) 
  5.     }

我們只能通過(guò)手寫 if判斷來(lái)進(jìn)行校驗(yàn):

 
 
 
 
  1. @PostMapping("/add") 
  2.  public String addStudent( @RequestBody Student student ) { 
  3.      if( student == null ) 
  4.          return "傳入的Student對(duì)象為null,請(qǐng)傳值"; 
  5.      if( student.getName()==null || "".equals(student.getName()) ) 
  6.          return "傳入的學(xué)生姓名為空,請(qǐng)傳值"; 
  7.      if( student.getScore()==null ) 
  8.          return "傳入的學(xué)生成績(jī)?yōu)閚ull,請(qǐng)傳值"; 
  9.      if( (student.getScore()<0) || (student.getScore()>100) ) 
  10.          return "傳入的學(xué)生成績(jī)有誤,分?jǐn)?shù)應(yīng)該在0~100之間"; 
  11.      if( student.getMobile()==null || "".equals(student.getMobile()) ) 
  12.          return "傳入的學(xué)生電話號(hào)碼為空,請(qǐng)傳值"; 
  13.      if( student.getMobile().length()!=11 ) 
  14.          return "傳入的學(xué)生電話號(hào)碼長(zhǎng)度有誤,應(yīng)為11位"; 
  15.      studentService.addStudent( student ); // 將student對(duì)象存入MySQL數(shù)據(jù)庫(kù)
  16.      return "SUCCESS"; 
  17.  }

這樣非常繁瑣!

但是借助于 Spring提供的注解,數(shù)據(jù)校驗(yàn)工作可以變得非常優(yōu)雅,就像這樣:

 
 
 
 
  1. public class Student { 
  2.        @NotNull(message = "傳入的姓名為null,請(qǐng)傳值") 
  3.        @NotEmpty(message = "傳入的姓名為空字符串,請(qǐng)傳值") 
  4.        private String name;    // 姓名 
  5.        @NotNull(message = "傳入的分?jǐn)?shù)為null,請(qǐng)傳值") 
  6.        @Min(value = 0,message = "傳入的學(xué)生成績(jī)有誤,分?jǐn)?shù)應(yīng)該在0~100之間") 
  7.        @Max(value = 100,message = "傳入的學(xué)生成績(jī)有誤,分?jǐn)?shù)應(yīng)該在0~100之間") 
  8.        private Integer score;  // 分?jǐn)?shù) 
  9.        @NotNull(message = "傳入的電話為null,請(qǐng)傳值") 
  10.        @NotEmpty(message = "傳入的電話為空字符串,請(qǐng)傳值") 
  11.        @Length(min = 11, max = 11, message = "傳入的電話號(hào)碼長(zhǎng)度有誤,必須為11位") 
  12.        private String mobile;  // 電話號(hào)碼 
  13.    }

于是很多人就表示疑問(wèn),這些注解到底如何實(shí)現(xiàn)功能的呢?

今天本文則以上文的 @Length注解為例,自己動(dòng)手實(shí)現(xiàn)一遍,這個(gè)學(xué)會(huì)了,其他注解實(shí)現(xiàn)原理也是類似。

總共分三大步實(shí)現(xiàn)。

第一步:首先定義注解:@Length

 
 
 
 
  1. @Target({ElementType.FIELD}) 
  2.   @Retention(RetentionPolicy.RUNTIME) 
  3.   public @interface Length { 
  4.       int min();          // 允許字符串長(zhǎng)度的最小值 
  5.       int max();          // 允許字符串長(zhǎng)度的最大值 
  6.       String errorMsg();  // 自定義的錯(cuò)誤提示信息 
  7.   }

下面做幾點(diǎn)說(shuō)明:

1、注解的定義有點(diǎn)像定義接口 interface,但唯一不同的是前面需要加一個(gè) @符號(hào)

2、注解的成員變量只能使用基本類型、 String或者 enum枚舉,比如 int可以,但 Integer這種包裝類型就不行,需注意

3、像上面 @Target、 @Retention這種加在注解定義上面的注解,我們稱為 “元注解”,元注解就是專門用于給注解添加注解的注解,哈哈,很拗口,簡(jiǎn)單理解,元注解就是天生就有的注解,可直接用于注解的定義上

4、 @Target(xxx) 用來(lái)說(shuō)明該自定義注解可以用在什么位置,比如:

  •  ElementType.FIELD:說(shuō)明自定義的注解可以用于類的變量
  •  ElementType.METHOD:說(shuō)明自定義的注解可以用于類的方法
  •  ElementType.TYPE:說(shuō)明自定義的注解可以用于類本身、接口或 enum類型
  •  等等... 還有很多,如果記不住,建議現(xiàn)用現(xiàn)查

5、 @Retention(xxx) 用來(lái)說(shuō)明你自定義注解的生命周期,比如:

  •  @Retention(RetentionPolicy.RUNTIME):表示注解可以一直保留到運(yùn)行時(shí),因此可以通過(guò)反射獲取注解信息
  •  @Retention(RetentionPolicy.CLASS):表示注解被編譯器編譯進(jìn) class文件,但運(yùn)行時(shí)會(huì)忽略
  •  @Retention(RetentionPolicy.SOURCE):表示注解僅在源文件中有效,編譯時(shí)就會(huì)被忽略

所以聲明周期從長(zhǎng)到短分別為:RUNTIME > CLASS > SOURCE ,一般來(lái)說(shuō),如果需要在運(yùn)行時(shí)去動(dòng)態(tài)獲取注解的信息,還是得用RUNTIME,就像本文所用。

第二步:獲取注解并對(duì)其進(jìn)行驗(yàn)證

在運(yùn)行時(shí)想獲取注解所代包含的信息,該怎么辦?那當(dāng)然得用 Java的反射相關(guān)知識(shí)!

下面寫了一個(gè)驗(yàn)證函數(shù) validate(),代碼中會(huì)逐行用注釋去解釋想要達(dá)到的目的,認(rèn)真看一下每一行的注釋:

 
 
 
 
  1. public static String validate( Object object ) throws IllegalAccessException { 
  2.       // 首先通過(guò)反射獲取object對(duì)象的類有哪些字段 
  3.      // 對(duì)本文來(lái)說(shuō)就可以獲取到Student類的id、name、mobile三個(gè)字段 
  4.      Field[] fields = object.getClass().getDeclaredFields(); 
  5.      // for循環(huán)逐個(gè)字段校驗(yàn),看哪個(gè)字段上標(biāo)了注解 
  6.      for( Field field : fields ) { 
  7.          // if判斷:檢查該字段上有沒(méi)有標(biāo)注了@Length注解 
  8.          if( field.isAnnotationPresent(Length.class) ) { 
  9.              // 通過(guò)反射獲取到該字段上標(biāo)注的@Length注解的詳細(xì)信息 
  10.              Length length = field.getAnnotation( Length.class ); 
  11.              field.setAccessible( true ); // 讓我們?cè)诜瓷鋾r(shí)能訪問(wèn)到私有變量 
  12.              // 用過(guò)反射獲取字段的實(shí)際值 
  13.              int value =( (String)field.get(object) ).length(); 
  14.              // 將字段的實(shí)際值和注解上做標(biāo)示的值進(jìn)行比對(duì) 
  15.              if( valuelength.max() ) { 
  16.                  return length.errorMsg(); 
  17.              } 
  18.          } 
  19.      } 
  20.      return null; 
  21.  }

可見(jiàn),學(xué)好Java的反射知識(shí)是多么的重要!

第三步:使用注解

這一步比較輕松,使用注解的過(guò)程往往都是很愉悅的

 
 
 
 
  1. public class Student { 
  2.        private Long id;        // 學(xué)號(hào) 
  3.        private String name;    // 姓名 
  4.        @Length(min = 11, max = 11, errorMsg = "電話號(hào)碼的長(zhǎng)度必須為11位") 
  5.        private String mobile;  // 手機(jī)號(hào)碼(11位) 
  6.    }

怎么樣,其實(shí)一點(diǎn)也不復(fù)雜吧,主要就是反射相關(guān)的知識(shí)!


新聞標(biāo)題:聽說(shuō)你只會(huì)用注解,不會(huì)自己寫注解?那有點(diǎn)危險(xiǎn)了
標(biāo)題網(wǎng)址:http://www.5511xx.com/article/djiipee.html