您好,欢迎访问一九零五行业门户网

获取指定包下所有自定义注解

reflections 通过扫描 classpath,索引元数据,允许在运行时查询这些元数据,也可以保存收集项目中多个模块的元数据信息。
使用reflections快速扫描指定包下自定义的controller和requestmapping两个注解,先去扫描加了@controller注解的类,接着获取这些类下面加了@requestmapping注解的方法,然后通过java的反射invoke方法去调用加了requestmapping注解的方法并输出注解上的信息。
maven 项目导入
<dependency>     <groupid>org.reflections</groupid>     <artifactid>reflections</artifactid>     <version>0.9.10</version> </dependency>
annotation包下面自定义了两个注解。
controller.java:
package annotationtest.annotation; import java.lang.annotation.documented; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @target(elementtype.type)// 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @retention(retentionpolicy.runtime)//定义注解的作用目标**作用范围字段、枚举的常量/方法 @documented//说明该注解将被包含在javadoc中 public @interface controller {     string value() default ; }
requestmapping.java
package annotationtest.annotation; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @target({elementtype.method, elementtype.type}) @retention(retentionpolicy.runtime) public @interface requestmapping {     string value() default ;     /**      * 是否为序列号      *      * @return      */     boolean id() default false;     /**      * 字段名称      *      * @return      */     string name() default ;     /**      * 字段描述      *      * @return      */     string description() default ; }
在model包下面定义了一个存放requestmapping注解方法的对象
executorbean.java
package annotationtest.model; import java.lang.reflect.method; public class executorbean {     private object object;     private method method;     public object getobject() {         return object;     }     public void setobject(object object) {         this.object = object;     }     public method getmethod() {         return method;     }     public void setmethod(method method) {         this.method = method;     } }
service包下面定义了几个类,其中有两个类使用了自定义的controller注解
sunservice.java
package annotationtest.service; import annotationtest.annotation.controller; import annotationtest.annotation.requestmapping; @controller public class sunservice {     @requestmapping(id = true, name = test1, description = sun测试1, value = /test1)     public void test1() {         system.out.println(sunservice->test1());     }     @requestmapping(id = true, name = test2, description = sun测试2, value = /test2)     public void test2() {         system.out.println(sunservice->test2());     } }
moonservice.java
package annotationtest.service; import annotationtest.annotation.controller; import annotationtest.annotation.requestmapping; @controller public class moonservice {     @requestmapping(id = true, name = moon测试3, description = /test3, value = /test3)     public void test3() {         system.out.println(moonservice->test3());     }     @requestmapping(id = true, name = moon测试4, description = /test4, value = /test4)     public void test4() {         system.out.println(moonservice->test4());     } }
stars.java
package annotationtest.service; import annotationtest.annotation.requestmapping; public class stars {     @requestmapping(id = true, name = test1, description = stars测试1, value = /test1)     public void test1() {         system.out.println(stars->test1());     } }
util包下面定义了一个工具类,来对包进行扫描获取自定义注解的类和方法
annomanageutil.java
package annotationtest.util; import java.lang.reflect.method; import java.util.hashmap; import java.util.map; import java.util.set; import annotationtest.annotation.controller; import annotationtest.annotation.requestmapping; import annotationtest.model.executorbean; import org.reflections.reflections; public final class annomanageutil {     /**      * 获取指定文件下面的requestmapping方法保存在mapp中      *      * @param packagename      * @return      */     public static map<string, executorbean> getrequestmappingmethod(string packagename) {         reflections reflections = new reflections(packagename);         set<class<?>> classeslist = reflections.gettypesannotatedwith(controller.class);         // 存放url和executorbean的对应关系         map<string, executorbean> mapp = new hashmap<string, executorbean>();         for (class classes : classeslist) {             //得到该类下面的所有方法             method[] methods = classes.getdeclaredmethods();             for (method method : methods) {                 //得到该类下面的requestmapping注解                 requestmapping requestmapping = method.getannotation(requestmapping.class);                 if (null != requestmapping) {                     executorbean executorbean = new executorbean();                     try {                         executorbean.setobject(classes.newinstance());                     } catch (instantiationexception e) {                         e.printstacktrace();                     } catch (illegalaccessexception e) {                         e.printstacktrace();                     }                     executorbean.setmethod(method);                     mapp.put(requestmapping.value(), executorbean);                 }             }         }         return mapp;     } }
test包下面是一个测试的类
package annotationtest.test; import java.lang.reflect.invocationtargetexception; import java.util.hashmap; import java.util.list; import java.util.map; import annotationtest.annotation.controller; import annotationtest.annotation.requestmapping; import annotationtest.model.executorbean; import annotationtest.util.annomanageutil; public class test {     public static void main(string[] args) {         list<class<?>> classeslist = null;         classeslist = annomanageutil.getpackagecontroller(annotationtest.service, controller.class);         map<string, executorbean> mmap = new hashmap<string, executorbean>();         annomanageutil.getrequestmappingmethod(classeslist, mmap);         executorbean bean = mmap.get(/test1);         try {             bean.getmethod().invoke(bean.getobject());             requestmapping annotation = bean.getmethod().getannotation(requestmapping.class);             system.out.println(注解名称: + annotation.name() + \t注解描述: + annotation.description());         } catch (illegalaccessexception e) {             e.printstacktrace();         } catch (invocationtargetexception e) {             e.printstacktrace();         }     } }
运行得到:
其他
使用 reflections 可以查询以下元数据信息:
reflections 依赖 google 的 guava 库和 javassist 库。
获得某个类型的所有子类型
获得标记了某个注解的所有类型/成员变量,支持注解参数匹配。
使用正则表达式获得所有匹配的资源文件
获得所有特定签名(包括参数,参数注解,返回值)的方法
使用注解修饰了类/方法/成员变量等之后,这些注解不会自己生效,必须由这些注解的开发者提供相应的工具来提取并处理注解信息(当然,只有当定义注解时使用了@retention(retentionpolicy.runtime)修饰,jvm才会在装载class文件时提取保存在class文件中的注解,该注解才会在运行时可见,这样我们才能够解析).
java使用annotation接口来代表程序元素前面的注解,该接口是所有注解的父接口。
java5在java.lang.reflect包下新增了 用annotatedelement接口代表程序中可以接受注解的程序元素.
annotatedelement接口的实现类有:class(类元素)、field(类的成员变量元素)、method(类的方法元素)、package(包元素),每一个实现类代表了一个可以接受注解的程序元素类型。
这样, 我们只需要获取到class、 method、 filed等这些实现了annotatedelement接口的类的实例,通过该实例对象调用该类中的方法(annotatedelement接口中抽象方法的重写) 就可以获取到我们想要的注解信息了。
获得class类的实例有三种方法:
利用对象调用getclass()方法获得class实例
利用class类的静态的forname()方法,使用类名获得class实例
运用.class的方式获得class实例,如:类名.class
annotatedelement接口提供的抽象方法(在该接口的实现类中重写了这些方法):
<t extends annotation> t getannotation(class< t> annotationclass)< t extends annotation>为泛型参数声明,表明a的类型只能是annotation类型或者是annotation的子类。
功能:返回该程序元素上存在的、指定类型的注解,如果该类型的注解不存在,则返回null
annotation[] getannotations()
功能:返回此元素上存在的所有注解,包括没有显示定义在该元素上的注解(继承得到的)。(如果此元素没有注释,则返回长度为零的数组。)
< t extends annotation> t getdeclaredannotation(class < t> annotationclass)
功能:这是java8新增的方法,该方法返回直接修饰该程序元素、指定类型的注解(忽略继承的注解)。如果该类型的注解不存在,返回null.
annotation[] getdeclaredannotations()
功能:返回直接存在于此元素上的所有注解,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)
boolean isannotationpresent(class<? extends annotation> annotationclass)
功能:判断该程序元素上是否存在指定类型的注解,如果存在则返回true,否则返回false。
<t extends annotation> t[] getannotationsbytpye(class<t> annotationclass)
功能: 因为java8增加了重复注解功能,因此需要使用该方法获得修饰该程序元素、指定类型的多个注解。
<t extends annotation> t[] getdeclaredannotationsbytpye(class<t>annotationclass)
功能: 因为java8增加了重复注解功能,因此需要使用该方法获得直接修饰该程序元素、指定类型的多个注解。
class提供了getmethod()、getfield()以及getconstructor()方法(还有其他方法),这些方法分别获取与方法、域变量以及构造函数相关的信息,这些方法返回method、field 以及constructor类型的对象。
以上就是获取指定包下所有自定义注解的详细内容。
其它类似信息

推荐信息