天天看點

Java自定義注解及個性化掃描注解自定義注解

自定義注解

自定義注解三步驟

  • 1、定義注解——相當于定義标記
  • 2、标記注解——把标記打到需要辨別的代碼中
  • 3、解析注解——在編譯期或運作期解析注解,并進行特殊操作

一、定義注解

1.1、代碼Demo

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface UserRoleAnnotation {

    /**
     * 允許通路的使用者角色
     */
    UserRole[] value();

}
           

說明:

  1. 注解定義用@interface關鍵字修飾
  2. @Target注解,是專門用來限定某個自定義注解能夠被應用在哪些Java元素上面的
  3. @Retention注解,翻譯為持久力、保持力。即用來修飾自定義注解的生命周期
  4. @Documented注解,是被用來指定自定義注解是否能随着被定義的java檔案生成到JavaDoc文檔當中
  5. @Inherited注解,是指定某個自定義注解如果寫在了父類的聲明部分,那麼子類的聲明部分也能自動擁有該注解

1.2、常用元注解說明

1.2.1、@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();
}
           

它是使用一個枚舉ElementType 來确定作用域:

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
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}
           

1.2.2、@Retention注解,翻譯為持久力、保持力。即用來修飾自定義注解的生命周期

注解的生命周期有三個階段:1、Java源檔案階段;2、編譯到class檔案階段;3、運作期階段。

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

同樣使用了RetentionPolicy枚舉類型定義了三個階段:

在預設的情況下,自定義注解是使用的RetentionPolicy.CLASS

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
           

1.2.3、@Documented注解,是被用來指定自定義注解是否能随着被定義的java檔案生成到JavaDoc文檔當中

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

1.2.4、@Inherited注解,是指定某個自定義注解如果寫在了父類的聲明部分,那麼子類的聲明部分也能自動擁有該注解。

@Inherited注解隻對那些@Target被定義為ElementType.TYPE的自定義注解起作用。

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

二、标記注解

@Component
@UserRoleAnnotation(UserRole.經濟标評委)
public class BidService implements IBidService {

    private Logger logger = Logger.getLogger(BidService.class);

    @Override
    public void testLog() {
        System.out.println("進入BidService111的TestLog方法");
    }

    @Override
    
    public void testLog2() {
        System.out.println("進入BidService111的TestLog222方法");
    }
}
           

三、解析注解

/**
 * 通過注解掃描菜單
 **/
public class MenuScanner {

    /**
     * 擷取自定義注解@ActionController掃描到的菜單集合
     */
    public static void getScanMenus() {
        // 要掃描的包
        String packageName = "com.epoint.smartbid";
        Reflections f = new Reflections(packageName);
        // 擷取掃描到的标記注解的集合
        Set<Class<?>> set = f.getTypesAnnotatedWith(UserRoleAnnotation.class);
        for (Class<?> c : set) {
            // 循環擷取标記的注解
            UserRoleAnnotation annotation = c.getAnnotation(UserRoleAnnotation.class);
            // 列印注解中的内容
            System.out.println(annotation.value());
        }
    }
}