自定义注解三步骤
- 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.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> set = f.getTypesAnnotatedWith(UserRoleAnnotation.class);
for (Class> c : set) {
// 循环获取标记的注解
UserRoleAnnotation annotation = c.getAnnotation(UserRoleAnnotation.class);
// 打印注解中的内容
System.out.println(annotation.value());
}
}
}