自定义注解
自定义注解三步骤
- 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);@Overridepublic void testLog() {System.out.println("进入BidService111的TestLog方法");}@Overridepublic 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());}}
}