最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java注解Annotation與自定義注解詳解

 更新時(shí)間:2018年03月21日 15:25:23   投稿:wdc  
本文全面講述了Java注解Annotation與Java自定義注解及相關(guān)內(nèi)容,大家可以認(rèn)真看看

一:Java注解簡(jiǎn)介

開(kāi)發(fā)中經(jīng)常使用到注解,在項(xiàng)目中也偶爾會(huì)見(jiàn)到過(guò)自定義注解,今天就來(lái)探討一下這個(gè)注解是什么鬼,以及注解的應(yīng)用場(chǎng)景和如何自定義注解。

下面列舉開(kāi)發(fā)中常見(jiàn)的注解

@Override:用于標(biāo)識(shí)該方法繼承自超類(lèi), 當(dāng)父類(lèi)的方法被刪除或修改了,編譯器會(huì)提示錯(cuò)誤信息(我們最經(jīng)常看到的toString()方法上總能看到這貨)

@Deprecated:表示該類(lèi)或者該方法已經(jīng)不推薦使用,已經(jīng)過(guò)期了,如果用戶(hù)還是要使用,會(huì)生成編譯的警告

@SuppressWarnings:用于忽略的編譯器警告信息

Junit測(cè)試:@Test

Spring的一些注解:@Controller、@RequestMapping、@RequestParam、@ResponseBody、@Service、@Component、@Repository、@Resource、@Autowire

Java驗(yàn)證的注解:@NotNull、@Email

下面看一下注解Override.java的廬山真面目

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {

}

二:Java注解基本知識(shí)

1. Java注解數(shù)據(jù)類(lèi)型

注解是寫(xiě)在.java文件中,使用@interface作為關(guān)鍵字, 所以注解也是Java的一種數(shù)據(jù)類(lèi)型,從廣泛的定義來(lái)說(shuō),Class、Interface、Enum、Annotation都屬于Class類(lèi)型。

2. Java元注解

在創(chuàng)建注解的時(shí)候,需要使用一些注解來(lái)描述自己創(chuàng)建的注解,就是寫(xiě)在@interface上面的那些注解,這些注解被稱(chēng)為元注解,如在Override中看到的@Target、@Retention等。下面列出一些元注解

@Documented: 用于標(biāo)記在生成javadoc時(shí)是否將注解包含進(jìn)去,可以看到這個(gè)注解和@Override一樣,注解中空空如也,什么東西都沒(méi)有

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {

}

@Target:用于定義注解可以在什么地方使用,默認(rèn)可以在任何地方使用,也可以指定使用的范圍,開(kāi)發(fā)中將注解用在類(lèi)上(如@Controller)、字段上(如@Autowire)、方法上(如@RequestMapping)、方法的參數(shù)上(如@RequestParam)等比較常見(jiàn)。

TYPE : 類(lèi)、接口或enum聲明
FIELD: 域(屬性)聲明
METHOD: 方法聲明
PARAMETER: 參數(shù)聲明
CONSTRUCTOR: 構(gòu)造方法聲明
LOCAL_VARIABLE:局部變量聲明
ANNOTATION_TYPE:注釋類(lèi)型聲明
PACKAGE: 包聲明

Target.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
  /**
   * Returns an array of the kinds of elements an annotation type
   * can be applied to.
   * @return an array of the kinds of elements an annotation type
   * can be applied to
   */
  ElementType[] value();
}
public enum ElementType {
  /** Class, interface (including annotation type), or enum declaration */
  TYPE,

  /** Field declaration (includes enum constants) */
  FIELD,

  /** Method declaration */
  METHOD,

  /** Formal parameter declaration */
  PARAMETER,

  /** Constructor declaration */
  CONSTRUCTOR,

  /** Local variable declaration */
  LOCAL_VARIABLE,

  /** Annotation type declaration */
  ANNOTATION_TYPE,

  /** Package declaration */
  PACKAGE,

  /** Type parameter declaration */
  TYPE_PARAMETER,

  /** Use of a type */
  TYPE_USE
}

@Inherited:允許子類(lèi)繼承父類(lèi)中的注解,可以通過(guò)反射獲取到父類(lèi)的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {

}

@Constraint:用于校驗(yàn)屬性值是否合法

@Documented
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraint {
  Class<? extends ConstraintValidator<?, ?>>[] validatedBy();
}

@Retention:注解的聲明周期,用于定義注解的存活階段,可以存活在源碼級(jí)別、編譯級(jí)別(字節(jié)碼級(jí)別)、運(yùn)行時(shí)級(jí)別

SOURCE:源碼級(jí)別,注解只存在源碼中,一般用于和編譯器交互,用于檢測(cè)代碼。如@Override, @SuppressWarings。

CLASS:字節(jié)碼級(jí)別,注解存在于源碼和字節(jié)碼文件中,主要用于編譯時(shí)生成額外的文件,如XML,Java文件等,但運(yùn)行時(shí)無(wú)法獲得。 如mybatis生成實(shí)體和映射文件,這個(gè)級(jí)別需要添加JVM加載時(shí)候的代理(javaagent),使用代理來(lái)動(dòng)態(tài)修改字節(jié)碼文件。

RUNTIME:運(yùn)行時(shí)級(jí)別,注解存在于源碼、字節(jié)碼、java虛擬機(jī)中,主要用于運(yùn)行時(shí),可以使用反射獲取相關(guān)的信息。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
  /**
   * Returns the retention policy.
   * @return the retention policy
   */
  RetentionPolicy value();
}

3. Java注解的內(nèi)容

在上面的注解源碼中可以看到有的注解中沒(méi)有任何內(nèi)容,有的注解的有內(nèi)容,看似像方法。

注解的內(nèi)容的語(yǔ)法格式: 數(shù)據(jù)類(lèi)型 屬性名() default 默認(rèn)值,數(shù)據(jù)類(lèi)型用于描述屬性的數(shù)據(jù)類(lèi)型,默認(rèn)值是說(shuō)當(dāng)沒(méi)有給屬性賦值時(shí)使用默認(rèn)值,一般String使用空字符串”“作為默認(rèn)值,數(shù)組一般使用空數(shù)組{ }作為默認(rèn)值.

下面看一下SpringMVC中的RequestMapping的注解的聲明

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
  String name() default "";

  @AliasFor("path")
  String[] value() default {};

  @AliasFor("value")
  String[] path() default {};

  RequestMethod[] method() default {};
  String[] params() default {};
  String[] headers() default {};
  String[] consumes() default {};
  String[] produces() default {};
}

使用SpringMVC中的RequestMapping注解

@RequestMapping(value = "/list", 
        method = RequestMethod.POST, 
        produces = {"application/json;charset=UTF-8;"})
public String list(){

}

4. 注解的使用場(chǎng)景

可以通過(guò)注解的聲明周期來(lái)分析注解的使用場(chǎng)景:

SOURCE源碼級(jí)別:給編譯器使用,如@Override、@Deprecated 等, 這部分開(kāi)發(fā)者應(yīng)該使用的場(chǎng)景不多

CLASS:字節(jié)碼級(jí)別,這部分也很少見(jiàn)到

RUNTIME:運(yùn)行時(shí)級(jí)別,這個(gè)是最多的,幾乎開(kāi)發(fā)者使用到的注解都是運(yùn)行時(shí)級(jí)別,運(yùn)行時(shí)注解常用的有以下幾種情況

注解中沒(méi)有任何屬性的,空的注解,這部分注解通常起到一個(gè)標(biāo)注的作用,如@Test、@Before、@After,通過(guò)獲取這些標(biāo)記注解在邏輯上做一些特殊的處理

可以使用約束注解@Constraint來(lái)對(duì)屬性值進(jìn)行校驗(yàn),如@Email, @NotNull等

可以通過(guò)在注解中使用屬性來(lái)配置一些參數(shù),然后可以使用反射獲取這些參數(shù),這些注解沒(méi)有其他特殊的功能,只是簡(jiǎn)單的代替xml配置的方式來(lái)配置一些參數(shù)。使用注解來(lái)配置參數(shù)這在Spring boot中得到了熱捧,如@Configuration

關(guān)于配置方式xml vs annotation, 一般使用xml配置一些和業(yè)務(wù)關(guān)系不太緊密的配置,使用注解配置一些和業(yè)務(wù)密切相關(guān)的參數(shù)。

三:Java注解和反射基本API

// 獲取某個(gè)類(lèi)型的注解
public <A extends Annotation> A getAnnotation(Class<A> annotationClass);
// 獲取所有注解(包括父類(lèi)中被Inherited修飾的注解)
public Annotation[] getAnnotations(); 
// 獲取聲明的注解(但是不包括父類(lèi)中被Inherited修飾的注解)
public Annotation[] getDeclaredAnnotations();
// 判斷某個(gè)對(duì)象上是否被某個(gè)注解進(jìn)行標(biāo)注
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

// 獲取某個(gè)類(lèi)聲明的所有字段
public Field[] getDeclaredFields() throws SecurityException;
// 獲取某個(gè)方法
public Method getMethod(String name, Class<?>... parameterTypes);

四:自定義注解

使用自定義注解+攔截器或者是AOP等可以進(jìn)行權(quán)限的控制。

下面通過(guò)定義一個(gè)注解用來(lái)限制當(dāng)用戶(hù)訪問(wèn)接口時(shí)必須要登錄的示例

步驟一:定義注解

RequiresLogin.java

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresLogin {

}

步驟二:使用注解

@Controller
@RequestMapping("/user")
public class UserController {
  @RequiresLogin
  @RequestMapping(value = "/list", produces = {"application/json;charset=UTF-8;"})
  public String getUserList(){

    System.out.println("--------------");
    return "[{'id': 1, 'username':'zhangsan'}]";
  }
}

步驟三:使用AOP進(jìn)行攔截,解析注解

public class LoginAdvices {
  public void before(JoinPoint joinPoint) throws Exception{

    Object target = joinPoint.getTarget();
    String methodName = joinPoint.getSignature().getName();

    System.out.println(target + "-------" + methodName);
    Method method = target.getClass().getMethod(methodName);
    boolean annotationPresent = method.isAnnotationPresent(RequiresLogin.class);
    if (annotationPresent) {
      // 用戶(hù)必須登錄
      boolean isLogin = false;
      if (!isLogin) {
        throw new Exception("訪問(wèn)該接口必須先登錄");
      } else {
        System.out.println("已登錄...");
      }
    }
  }
}

在applicationContext.xml中配置aop

<bean id="loginAdvices" class="com.mengdee.manager.aop.LoginAdvices"/>
  <!-- aop配置 -->
  <aop:config proxy-target-class="true">
    <!--切面 -->
    <aop:aspect ref="loginAdvices">
      <!-- 切點(diǎn) -->
      <aop:pointcut id="pointcut1" expression="execution(* com.mengdee.manager.controller.*.*(..))"/>
      <!--連接通知方法與切點(diǎn) -->
      <aop:before method="before" pointcut-ref="pointcut1"/>
    </aop:aspect>
  </aop:config>

自定義異常

為什么要自定義異常

Java雖然提供了豐富的異常處理類(lèi),但是在項(xiàng)目中還會(huì)經(jīng)常使用自定義異常,其主要原因是Java提供的異常類(lèi)在某些情況下還是不能滿(mǎn)足各種業(yè)務(wù)的需求。 例如系統(tǒng)中有些錯(cuò)誤是符合Java語(yǔ)法,但不符合業(yè)務(wù)邏輯。如當(dāng)用戶(hù)登錄時(shí)賬號(hào)不存在或者賬號(hào)已鎖定可以自定義一個(gè)賬號(hào)異常AccountException。

或者有些情況下Java的同一個(gè)異常可能會(huì)有多種原因引起,在排查問(wèn)題時(shí)不容易定位錯(cuò)誤,此時(shí)可以使用自定義一個(gè)更加明確的異常。

自定義異常的好處:自定義異??梢允巩惓8用鞔_,可以隱藏底層的異常,這樣更安全,異常信息更加直觀。

自定義異常的使用:自定義異常一般繼承自Exception或者RuntimeException,根據(jù)業(yè)務(wù)需要可以帶一些屬性作為構(gòu)造函數(shù)的參數(shù),自定義異常需要程序員手動(dòng)拋出異常,并處理異常。

下面是Apache Shiro中自定義異常的示例

public class ShiroException extends RuntimeException {
  public ShiroException() {
  }

  public ShiroException(String message) {
    super(message);
  }

  public ShiroException(Throwable cause) {
    super(cause);
  }

  public ShiroException(String message, Throwable cause) {
    super(message, cause);
  }
}

以上即是關(guān)于Java注解Annotation與自定義注解的詳細(xì)說(shuō)明

相關(guān)文章

  • Java動(dòng)態(tài)腳本Groovy獲取Bean技巧

    Java動(dòng)態(tài)腳本Groovy獲取Bean技巧

    這篇文章主要給大家分享的是Java動(dòng)態(tài)腳本Groovy獲取Bean技巧,在Java代碼中當(dāng)我們需要一個(gè)Bean對(duì)象,通常會(huì)使用spring中@Autowired注解,用來(lái)自動(dòng)裝配對(duì)象。下面我們一起進(jìn)入文章學(xué)習(xí)個(gè)表格多 詳細(xì)內(nèi)容吧

    2021-12-12
  • 非常全面的IReport的使用教程

    非常全面的IReport的使用教程

    iReport 是為JasperReports Library和JasperReports Server設(shè)計(jì)的報(bào)表可視化設(shè)計(jì)器。本教程給大家詳細(xì)介紹IReport的使用解析,感興趣的朋友一起看看吧
    2021-10-10
  • Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射

    Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java使用Fastjson進(jìn)行JSON數(shù)據(jù)操作教程詳解

    Java使用Fastjson進(jìn)行JSON數(shù)據(jù)操作教程詳解

    Fastjson?是一個(gè)?Java?庫(kù),可以用來(lái)將?Java?對(duì)象轉(zhuǎn)換為它們的?JSON?表示,本文主要為大家詳細(xì)介紹了Java如何使用Fastjson進(jìn)行JSON數(shù)據(jù)操作,需要的可以參考下
    2023-12-12
  • Java經(jīng)典設(shè)計(jì)模式之觀察者模式原理與用法詳解

    Java經(jīng)典設(shè)計(jì)模式之觀察者模式原理與用法詳解

    這篇文章主要介紹了Java經(jīng)典設(shè)計(jì)模式之觀察者模式,簡(jiǎn)單分析了觀察者模式的概念、原理并結(jié)合實(shí)例形式給出了java觀察者模式的具體用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-08-08
  • java本機(jī)內(nèi)存分配N(xiāo)ative?memory?allocation?mmap失敗問(wèn)題解決

    java本機(jī)內(nèi)存分配N(xiāo)ative?memory?allocation?mmap失敗問(wèn)題解決

    這篇文章主要介紹了java本機(jī)內(nèi)存分配N(xiāo)ative?memory?allocation?mmap失敗問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Java并發(fā)框架中的AQS詳細(xì)解析

    Java并發(fā)框架中的AQS詳細(xì)解析

    這篇文章主要介紹了Java并發(fā)框架中的AQS詳細(xì)解析,之前說(shuō)鎖的升級(jí)的時(shí)候,說(shuō)到了自旋鎖會(huì)空轉(zhuǎn)幾次嘗試等待獲取資源,其實(shí)這一系列的動(dòng)作是有一個(gè)規(guī)范的這個(gè)規(guī)范叫做同步發(fā)生器AbstractQueuedSynchronizer ,簡(jiǎn)稱(chēng)AQS,需要的朋友可以參考下
    2024-01-01
  • java如何從linux服務(wù)器下載文件

    java如何從linux服務(wù)器下載文件

    這篇文章主要介紹了java如何從linux服務(wù)器下載文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Sprigmvc項(xiàng)目轉(zhuǎn)為springboot的方法

    Sprigmvc項(xiàng)目轉(zhuǎn)為springboot的方法

    本篇文章主要介紹了Sprigmvc項(xiàng)目轉(zhuǎn)為springboot的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • SpringBoot中利用@Valid和@Validated進(jìn)行參數(shù)校驗(yàn)

    SpringBoot中利用@Valid和@Validated進(jìn)行參數(shù)校驗(yàn)

    為了保證數(shù)據(jù)的正確性、完整性,前后端都需要進(jìn)行數(shù)據(jù)檢驗(yàn),作為一名后端開(kāi)發(fā)工程師,不能僅僅依靠前端來(lái)校驗(yàn)數(shù)據(jù),我們還需要對(duì)接口請(qǐng)求的參數(shù)進(jìn)行后端的校驗(yàn),所以本文給大家介紹了SpringBoot中利用@Valid和@Validated進(jìn)行參數(shù)校驗(yàn),需要的朋友可以參考下
    2024-09-09

最新評(píng)論

舒城县| 思南县| 堆龙德庆县| 惠水县| 许昌市| 维西| 磐安县| 临泽县| 谷城县| 湄潭县| 互助| 丹寨县| 同心县| 睢宁县| 聊城市| 寿宁县| 溆浦县| 民乐县| 科尔| SHOW| 黎川县| 兰溪市| 宿松县| 克什克腾旗| 天台县| 连云港市| 耒阳市| 炉霍县| 西安市| 大邑县| 罗山县| 淮北市| 门源| 长顺县| 乐清市| 宕昌县| 怀集县| 深州市| 利川市| 巴马| 桃源县|