自定義注解(注解掃描)
自定義注解三步驟
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();
}
說明:
注解定義用@interface
關鍵字修飾
@Target
注解,是專門用來限定某個自定義注解能夠被應用在哪些Java元素上面的
@Retention
注解,翻譯為持久力、保持力。即用來修飾自定義注解的生命周期
@Documented
注解,是被用來指定自定義注解是否能隨着被定義的java文件生成到JavaDoc文檔當中
@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());
}
}
}
轉自: https://blog.csdn.net/java_faep/article/details/104004678