你的位置:首页 > Java教程

[Java教程]java annotation+反射的应用记录


使用java 的annotation和反射的小例子,记录下来以供参考,

实现的功能是 配置页面可以动态选择一个实现检核接口的类,保存输入的参数,在真正检核时传入保存的参数

配置页面如下:第一行选择了检核1 有三个参数需要输入,第二行可以看到下拉选单,内容是根据annotation标注的class生成的

 

下拉选单是根据annotation标注的class生成的,目前是有3个测试class,选择了以后可以填入需要的参数进行保存,参数也是定义在class中,目前先讲一讲这部分配置的实现。

  自定义一个annotation

1 @Retention(RetentionPolicy.RUNTIME)2 @Target(ElementType.TYPE)3 public @interface AnnotBpbAssertionClass {4 5   public String descr() default "";6 }

其中一个检核class,实现的接口是为了实作assertData方法,检核调用的真正方法,

@AnnotBpbAssertionArg标注输入的参数,可以看到和上面页面上的匹配
 1 @AnnotBpbAssertionClass(descr="检核1") 2 public class TestAssert1 implements AssertionClassHandler{ 3  4   @AnnotBpbAssertionArg 5   private String arg1; 6   @AnnotBpbAssertionArg 7   private String arg2; 8   @AnnotBpbAssertionArg 9   private String arg3;10   public String getArg1() {11     return arg1;12   }13   public void setArg1(String arg1) {14     this.arg1 = arg1;15   }16   public String getArg2() {17     return arg2;18   }19   public void setArg2(String arg2) {20     this.arg2 = arg2;21   }22   public String getArg3() {23     return arg3;24   }25   public void setArg3(String arg3) {26     this.arg3 = arg3;27   }28   @Override29   public AssertionResult assertData() {30   31   }32 33   34 }

 

  为了效率比较高,标注有annotation的class是在spring加载bean的时候写入内存的,service需要实现InitializingBean,初始化方法中用到了类扫描

首先获得Reflections,PKG_NAME 为扫描其实包路径,如果觉得没有用也可以在调用时抓取一次

 

 1 private static Reflections getRef(String pkgName) { 2     String sPkgName = pkgName == null ? PKG_NAME : pkgName; 3  4     Set<URL> clzLoaderUrls = ClasspathHelper.forPackage(sPkgName); 5     Set<URL> webInfoLibUrls = Collections.emptySet(); 6     Set<URL> scanUrls = new LinkedHashSet<URL>(); 7  8     try { 9       ServletContext servletContext = WebContextInfo.getInstance().getParentServletContext();10       webInfoLibUrls = ClasspathHelper.forWebInfLib(servletContext);11       URL webInfoClassUrls = ClasspathHelper.forWebInfClasses(servletContext);12       if(webInfoClassUrls != null){13         scanUrls.add(webInfoClassUrls);14       } 15     } catch (Exception e) {16       LG.warn(ClassScanner.class.getSimpleName(),17           "get webinf lib/class failed., err: {0}", e.getMessage());18     }19 20     scanUrls.addAll(webInfoLibUrls);21     scanUrls.addAll(clzLoaderUrls);22 23     ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();24     cfgBuilder.filterInputsBy(new FilterBuilder.Include(FilterBuilder.prefix(sPkgName)));25     cfgBuilder.addScanners(26         new SubTypesScanner(), 27         new TypeAnnotationsScanner(), 28         new MethodAnnotationsScanner(), 29         new FieldAnnotationsScanner());30     cfgBuilder.setUrls(scanUrls);31 32     Reflections refs = new Reflections(cfgBuilder);33     return refs;34   }


获得所有标注annotation的class集合。

    Reflections ref = getRef();    Set<Class<?>> ret = ref.getTypesAnnotatedWith(annotation);  

将class和annotation的信息封装在 BpbAssertionClassMeta 这个类中,可以看到class和annotation的一些方法。

 

      if (CollectionUtils.isNotEmpty(clazzSet)) {        for (Class<?> clazz : clazzSet) {          BpbAssertionClassMeta meta = new BpbAssertionClassMeta();          List<ArgMeta> argMetas = new ArrayList<BpbAssertionClassMeta.ArgMeta>();          meta.setArgs(argMetas);          meta.setClassName(clazz.getCanonicalName());          AnnotBpbAssertionClass annotation = clazz.getAnnotation(AnnotBpbAssertionClass.class);//获取annotation          meta.setDesc(annotation.descr());          metas.add(meta);          Field[] declaredFields = clazz.getDeclaredFields();//获取类的所有字段          if (declaredFields != null) {            for (Field field : declaredFields) {              if (field.isAnnotationPresent(AnnotBpbAssertionArg.class)) {//是否标注的此annotation                if (String.class.isAssignableFrom(field.getType()) == false) {//是否string类型                  throw new IllegalArgumentException(                      String.format(                          "unsupported type!, expected %s but %s found. @field: %s, @class: %s",                          String.class.getSimpleName(), field.getType()                              .getSimpleName(), field.getName(), clazz                              .getName()));                }                ArgMeta argMeta = meta.new ArgMeta();                argMeta.setField(field);                argMeta.setDesc(field.getName());                argMetas.add(argMeta);              }            }          }        }      }

页面循环BpbAssertionClassMeta  就可以渲染此页面了。

 




几月去贵州旅游最好去贵州的旅游团价格去贵州旅游必去景点去贵州旅游要多少钱去贵州旅游最佳路线桂林到神龙水世界自驾游攻略?桂林到神龙水世界景区开车攻略? 南海影视城最新活动时间?佛山南海影视城4月有什么优惠? 桂林神龙水世界酒店住宿多少钱?神龙水世界景区有住的地方吗? 南海影视城五一有什么活动?佛山南海影视城好玩活动介绍? 香市动物园有动物表演吗?东莞香市动物园动物表演时间表? 3月松山湖桃花开了吗?2015松山湖桃花几月最好看? 2015马降龙碉楼旗袍节时间?开平碉楼穿旗袍免门票时间? 马降龙碉楼旗袍节有什么好玩的?开平碉楼旗袍节活动介绍? 深圳观澜版画村在哪里、怎么去? 云南大海草山怎么去? 秋日下江南 盘点江苏六大经典园林 广西龙脊美景 我在金秋遇见你 曼谷玉佛寺怎么去?曼谷玉佛寺怎么坐车? 2015年七夕去马尔代夫玩好不好? 去一次迪拜要带多少钱? 曼谷玉佛寺门票多少钱?曼谷玉佛寺有那些禁忌? IDT72V3650L10PF8 Datasheet IDT72V3650L10PF8 Datasheet IDT5V9910A-2SOG Datasheet IDT5V9910A-2SOG Datasheet IDT71V3558XS133PFGI8 Datasheet IDT71V3558XS133PFGI8 Datasheet 南京到香港旅游价格 南京到香港旅游价格 南京到香港旅游价格 大兴安岭到香港旅游价格 大兴安岭到香港旅游价格 大兴安岭到香港旅游价格 深圳到香港旅游价格 深圳到香港旅游价格 深圳到香港旅游价格