Java Annotation(注解)

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

自定义注释

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

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

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

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

    @H_301_22@
  5. RetentionPolicy.SOURCE

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

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

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

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

  10. @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() { /*方法/ }

  11. 示例

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

    @H_301_22@
  13. 核心方法

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

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

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

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

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

  19. Annotation[] getAnnotationsByTpye(Class annotationClass)

  20. 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的简单实现框架

    @H_301_22@
  3. 核心方法

    @H_301_22@
  4. Class Class.forName(clsName) 反射获取Class类

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

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

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

  8. 框架方案

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

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

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

  9. 简单示例

    //接口
    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();
  10. 利用注释进行依赖注入

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

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