近期项目需要做权限验证,高手们写了一个权限验证的框架,看了一遍代码,还是和高手有差距啊~
权限框架用到了一些注解反射啥的,所以回头看看以前写的文章《深入理解java 注解(Annotation)》,转过来,再做一些补充,做备忘使用。
一、什么是注解?
懒得去打了,搞一份wiki上的解释,自己看吧(以前可能会翻译一下,现在懒了)
Annotation的使用方式及自定义注解
首先扫下盲,元注解就是Annotation的元注解一共有4个,分别为:@Target、@Retention、@Documented、@Inherited
1、@Target用来表示声明的Annotation修饰的范围,其ElementType的枚举一共有以下几个
简单地翻译一下吧
ANNOTATION_TYPE 注解类型声明
CONSTRUCTOR 构造方法声明
FIELD 属性声明
LOCAL_VARIABLE 局部变量性声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注解类型)或枚举型声明
2、@Retention 表明了注解可以保留多长时间,或者说是在哪个阶段,默认的保存留方案是CLASS,其RetentionPolicy的枚举一共有以下几个
简单地翻译一下吧
CLASS 注解被记录在class文件中,但是在运行的时候不会在虚拟机中保留(即编译阶段有效)
RUNTIME 注解被记录在class文件中,在虚拟机运行时会被保留,因此可以被反射机制读取出来(即在运行阶段仍然有效)(一般我们使用的都是这个)
SOURCE 在编译的时候被编译器丢弃(即源码阶段有效),像java中的几个常见的在编写代码阶段用于编译器报错的注解都是使用这个值:@Override,@Deprecated,@SuppressWarnings
3、@Documented 标注了这个描述的annotation是否可以被文档化。(没什么好说的)
4、@Inherited 表明了注解的类型是自动被继承的。如果一个注解使用了@Inherited这个元注解,则它的子类也会自动添加这个注解(即这个注解是可以被继承的)。
5、jdk1.5后反射的实体都实现了AnnotatedElement的接口,使得读取注解更加地简单,为了节省时间,还是截jdk文档的图吧
二、注解有什么用
注解的字面上意思就是解释说明吧。
Java中的用途是对类、方法、属性进行添加注释说明,比如,这个方法/类的路由,权限等。
(以上都是自己YY的)
三、注解怎么用
注解的使用一般分类三步:定义注解、使用注解、解析注解。话不多说,上代码。
1、定义注解
@Inherited @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Controller { String value(); }
@Inherited @Documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Inject { String value(); }
@Inherited @Documented @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Permission { String value() default "root"; }
@Inherited @Documented @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Parameter { String value() default ""; }
@Inherited @Documented @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Required {}
2、使用注解
@Controller("testController") public class TestController { @Inject("injectStr") private String injectStr; @Permission("testPmission") public void test(@Parameter("param") @Required String param, @Required String param2) {} }
3、解析注解
public class Main { public static void main(String[] args) { Class clazz = TestController.class; if (clazz.isAnnotationPresent(Controller.class)) { Controller controllerAnnotaion = (Controller) clazz.getAnnotation(Controller.class); System.out.println("class annotations: " + controllerAnnotaion.value()); } Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Inject.class)) { System.out.println("field annotations: " + field.getAnnotation(Inject.class).value()); } } Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(Permission.class)) { System.out.println("method annotations: " + method.getAnnotation(Permission.class).value()); } Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (Annotation[] annotations : parameterAnnotations) { for (Annotation annotation : annotations) { System.out.println("parameter annotations: " + annotation.toString()); } } } } }
参考文章:
Oracle java api (这部分自己去选annotation包下的Class)