1. 程式人生 > 其它 >Java Annation自定義註解

Java Annation自定義註解

由於業務關係,新的專案對於欄位校驗及資料唯一性校驗較為嚴格,因此引用了hibernate-validator包進行校驗,由於業務不得不進行自定義校驗規則,這時候涉及到自定義註釋進行校驗接收的物件。對於java註解沒有過多深入細節瞭解,一直處於用時方去找的狀況。這次做一下筆記加深一下自己的印象,也希望有人看到給出更多建議,一切為了想進步。

Java 1.5 引入了註解,現在它在 Hibernate、Spring等 Java EE 框架中得到了大量使用。Java Annotation 是關於嵌入在程式本身中的程式的元資料。可以通過註解解析工具解析,也可以通過編譯器解析。我們還可以將註釋可用性指定為僅編譯時或直到執行時。在 Java 註釋之前,程式元資料可通過 Java 註釋或 Javadoc 獲得,但註釋提供的遠不止這些。註釋元資料也可以在執行時使用,註釋解析器可以使用它來確定流程。

Java自定義註解:

驗證java註解的一些要點是:

  1. 註解方法不能有引數。
  2. 註釋方法返回型別僅限於原始型別、字串、列舉、註釋或這些型別的陣列。
  3. Java Annotation 方法可以有預設值。
  4. 註釋可以附有元註釋。元註釋用於提供有關注釋的資訊。
@Documented
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {

    String message() 
default "該物件要求唯一"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }

Java中的元註解:

  1. @Documented- 指示使用此註釋的元素應由 javadoc 和類似工具記錄。此型別應用於註釋型別宣告,這些型別的註釋會影響其客戶端對帶註釋元素的使用。如果使用 Documented 對型別宣告進行註釋,則其註釋將成為帶註釋元素的公共 API 的一部分。
  2. @Target- 指示註釋型別適用的程式元素的種類。一些可能的值是型別、方法、建構函式、欄位等。如果目標元註釋不存在,則可以在任何程式元素上使用註釋。
  3. @Inherited– 表示自動繼承註解型別。如果使用者在類宣告上查詢註解型別,並且類宣告沒有針對該型別的註解,則將自動查詢該類的超類以獲取註解型別。將重複此過程,直到找到此型別的註釋,或到達類層次結構(物件)的頂部。
  4. @Retention- 指示帶有註釋型別的註釋將保留多長時間。它採用 RetentionPolicy 引數,其可能的值為 SOURCE、CLASS 和 RUNTIME
  5. @Repeatable- 用於指示其註釋的註釋型別是可重複的(瞭解即可)。

Java 中的內建註解:

  1. @Override– 當我們想要覆蓋 Superclass 的一個方法時,我們應該使用這個註解來通知編譯器我們正在覆蓋一個方法。因此,當移除或更改超類方法時,編譯器將顯示錯誤訊息。瞭解為什麼我們應該在覆蓋方法時始終使用java覆蓋註釋。
  2. @Deprecated– 當我們希望編譯器知道某個方法已被棄用時,我們應該使用這個註解。Java 建議在 javadoc 中,我們應該提供有關為什麼不推薦使用此方法以及可以使用的替代方法的資訊。
  3. @SuppressWarnings– 這只是告訴編譯器忽略它們產生的特定警告,例如在java genercis 中使用原始型別。它的保留策略是 SOURCE,它會被編譯器丟棄。
  4. @FunctionalInterface– 這個註解是在Java8中引入的,以表明該介面旨在成為一個功能介面。
  5. @SafeVarargs– 程式設計師斷言帶註釋的方法或建構函式的主體不會對其 varargs 引數執行潛在的不安全操作。

舉例:

@Documented
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {

    String message() default "該物件要求唯一";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

interface UniqueTest{

}

class Test{
    public static void main(String[] args) {
    }

    @Override
    @MethodInfo(message = "fail",groups = UniqueTest.class)
    public String toString(){
       return  "Override toString method";
    }

    @Deprecated
    @MethodInfo(message = "fail",groups = UniqueTest.class)
    public static void oldMethod(){
        System.out.println("oldMethod");
    }

    @SuppressWarnings({ "unchecked", "deprecation" })
    @MethodInfo(message = "fail",groups = UniqueTest.class)
    public static void genericsTest() throws FileNotFoundException {
        List l = new ArrayList();
        l.add("abc");
        oldMethod();
    }

}

有太多的hibernate校驗自定義註解,這裡就不具體實現了,這裡舉例一個實現自定義註解做操作日誌處理的方法:

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface AddOperationLog {
}

@Aspect
@Component
class AddOperationLogAspect {
@Pointcut(value = "@annotation(xxx.xxx.xxx.AddOperationLog)")
public void controllerAspect() {
}

@After("controllerAspect()")
public void doBefore() {}
}

到此只是花時間簡單梳理驗證一下,後續有更深入瞭解,繼續補充更新