Java Annotation(注解)

前端之家收集整理的这篇文章主要介绍了Java Annotation(注解)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

自定义注释

  1. 基本定义:
    属性通过 属性名()的方式声明,可以通过default 设置默认值,这样在使用注释时可以不给属性赋值,否则使用时声明的属性必需赋值

    public @interface myAnnot {
        int id() default -1;
        String desc();
    }
  2. 元注释:
    Meta Annotation,通俗的讲就是用来注释注释的注释。JDK定义了4个元注释:@Target,@Retention,@Documented,@Inherited

    • @Target
      标示自定义的Annotation可用来注释哪些元素,例如Class、Method
      示例
      @Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})

    • @Retention
      标示自定义的Annotation的生命周期,可选值为RetentionPolicy枚举值

      • RetentionPolicy.SOURCE

        标示自定义的Annotation仅存在于源代码中,编译时丢弃
      • RetentionPolicy.CLASS

        标示自定义的Annotation会编译到Class文件中,但在运行加载时被丢弃
      • RetentionPolicy.RUNTIME

        标示自定义的Annotation在运行加载时被一起加载,可以通过反射机制读取。
    • @Documented
      标示自定义的Annotation会包含在JavaDoc中,其实这个我不关心

    • @Inherited
      标示允许子类继承父类自定义的Annotation

    • @Repeatable
      JDK8新增的元注释,标示自定义的Annotation可以在一个目标上连续多次使用

      public @interface Schedules { Schedule[] value(); }
      

      @Repeatable(Schedules.class)
      public @interface Schedule {
      String dayOfMonth();
      String dayOfWeek();
      String hour();
      }

      @Schedule(dayOfMonth="last")
      @Schedule(dayOfWeek="Fri",hour="23")
      public void doPeriodicCleanup() { /*方法/ }

    • 示例

      @Retention(value = RetentionPolicy.RUNTIME)
      public @interface myAnnot {
          int id() default -1;
          String desc();
      }
  3. 反射读取Annotation

    • 核心方法

      • boolean isAnnotationPresent(Class annotationClass) 判断该程序元素上是否存在指定类型的注解

      • Annotation getAnnotation(Class annotationClass) 包含继承自父类的注释

      • Annotation[] getAnnotations()包含继承自父类的注释

      • Annotation getDeclaredAnnotation(Class annotationClass) 不包含继承自父类的注释

      • Annotation[] getDeclaredAnnotations()不包含继承自父类的注释

      • Annotation[] getAnnotationsByTpye(Class annotationClass)

      • Annotation[] getDeclaredAnnotationsByTpye(Class annotationClass)

        public static List read(Class  cls){
            List annot_lst = new ArrayList();
            for(Method m : cls.getDeclaredMethods()){
                myAnnot my_annot = m.getAnnotation(myAnnot.class);
                annot_lst.add(String.format("%s's myannot id is %s,desc is %s",m.getName(),my_annot.id(),my_annot.desc()));
            }
            return annot_lst;
        }

如何使用注释进行依赖注入(DI)

  1. 控制反转IoC(Inversion of Control)思想
    总的来说就是不通过New来创建对象,使用反射技术将对象创建权利转移给控制容器,IoC容器根据类加载器创建。

  2. IoC的简单实现框架

    • 核心方法

      • Class Class.forName(clsName) 反射获取Class类

      • Constructor Class.getConstructor(Class... parameterTypes) 反射获取指定参数形态的构造器(可以理解为构造函数对象)

      • T Class.newInstance() 无构造参数方式创建类实例对象。

      • T Constructor.newInstance(Object... args) 有构造参数方式创建类实例对象

    • 框架方案

      1. 搭建IoC容器,容器需要实现通过输入类的全名(包括命名空间)来创建类实例对象

      2. 功能的抽象接口。定义接入协议。

      3. 配置文件提供IoC容器需要的信息

    • 简单示例

      //接口
      com.sample.inf
      public interface IEntity {
          public void Start();
      }

      IoC容器

      com.sample.core
      

      import java.lang.reflect.Constructor;
      import java.lang.reflect.InvocationTargetException;

      //示例以IEntity作为唯一接入点
      public class Repo {
      @SuppressWarnings("unchecked")
      public static Class getClass(String className) throws ClassNotFoundException{
      Class<?> clsType = Class.forName(className);
      // 判断是否满足接口协议
      if (!IEntity.class.isAssignableFrom(clsType))
      {
      throw new ClassNotFoundException();
      }
      return (Class) clsType;
      }

      public static <W extends Object,T extends IEntity> T getEntity(String className,@SuppressWarnings("unchecked") W... args) throws InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,NoSuchMethodException,SecurityException,ClassNotFoundException{
          return getEntity(getClass(className),args);
      }
      
      public static <W extends Object,T extends IEntity> T getEntity(Class <T> clsType,SecurityException{
          T o = null;
          if(args.length > 0){
              Class<?>[] parameterTypes = new Class<?>[args.length];  
              int index =0;  
              for (W arg : args) {  
                  parameterTypes[index++] = arg.getClass();  
              }  
              Constructor<T> co = clsType.getConstructor(parameterTypes);
              o = co.newInstance(args);
          }
          else {
              o = clsType.newInstance();
          }
          return o;
      }

      }

      通过IoC容器创建实例对象

      IEntity entityObj = Repo.getEntity("com.sample.Entity.FirstEntity");
      entityObj.Start();
  3. 利用注释进行依赖注入

    • 通过约定的注释信息,提供给IoC容器创建实例对象的必要数据。

猜你在找的程序笔记相关文章