zoukankan      html  css  js  c++  java
  • Java自定义注解的使用

    什么是注解?

    #======================================================================================================================
      Annotation(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。

     Annotation可以用于创建文档,跟踪代码中的依赖性,执行编译时的检查。Annotation就像修饰符一样被使用,可用于包,类型,构造方法,方法,成员变量,
     参数,本地变量的申明中。这些信息会被存储在Annotation的“name=value”结构对中
    #
    ======================================================================================================================

    什么是metadata元数据?

    #==========================================================================================================================
      元数据,即“描述数据的数据”的意思,元数据一词从“metadata”翻译过来。
     
     Annotation的行为非常类似于public,final这样的修饰符。

     Annotation类型定义了Annotation的名字,类型,成员默认值,一个Annotation可以说是一个特殊的Java接口,它的成员变量是受限制的,当我们通过Java反射
     API访问注解的时候,返回值将是一个实现了该Annotation类型接口的对象,通过这个对象我们能方便的访问到其他的Annotation成员。            
    #
    ============================================================================================================================

    注解的分类?

    #==========================================================================================================================
    
     JDK内置系统的注解:@Override,@Deprecated

     元注解:@Target,@Retention,@Document,@Inhrited,


     自定义注解:(元注解的作用就是负责注解其他注解) #
    ==========================================================================================================================

    注解是如何使用? 

    #==========================================================================================================================
    
     // 用于描述注解的使用范围  @Target(ElementType.Constructor)
     @Target(ElementType.Field)
     @Target(ElementType.Local_Variable)
     @Target(ElementType.Method)
     @Target(ElementType.Package)
     @Target(ElementType.Paramater)
     @Target(ElementType.Type)

    // 用于描述注解的生命周期
     @Rentention(RetentionPolicy.source)
     @Rentention(RetentionPolicy.class)
     @Rentention(RetentionPolicy.runtime)
     
     @Document 和 @Inhrited 不常用,暂时不做介绍;
    #
    ==========================================================================================================================

    自定义注解(注解与反射机制

    #==========================================================================================================================
    
     @Target(ElementType.Parameter)
     @Retention(RetentionPolicy.Runtime) 
     public @interface CacheKey{
        String value();
     }
     比如我们在代码中定义上述注解,直观的我们能看到注解使用在参数上,使用周期是运用在运行时使用,注解的参数名是value。阐述自定义注解:
     1. 使用@interface自定义注解的时候,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节
     2. 自定义注解,不能继承其他的注解或者接口。
     3. @interface用来申明一个注解,其中的每一个方法实际上是申明了一个配置参数,方法的名称就是参数的名称。
     4. 返回值类型仅仅包括:基本数据类型 + class + Enum + String
     5. 参数只能用public或default修饰,如果只有一个参数,最好把参数名称设置为value()。

     注解元素的默认值:注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。因此,
     使用空字符串或0作为默认值是一种常用的做法。这个约束使得处理器很难表现一个元素的存在或缺失的状态,因为每个注解的声明中,所有元素都存在,
     并且都具有相应的值,为了绕开这个约束,我们只能定义一些特殊的值,例如空字符串或者负数,一次表示某个元素不存在,在定义注解时,这已经成为一个习惯用法
    #==========================================================================================================================

    关于注解的一些其他说明

    #==========================================================================================================================
    
    public interface Annotation{

      boolean equals(Object obj);
      int hasCode();
      String toString();
      Class<? extends Annotation> annotationType();
    } Java中的注解是一种继承自接口的java.lang.annotation.Annotation的接口。
    #
    ==========================================================================================================================

    注解在程序运行时是如何作处理的

      java在java.lang.reflect下新增了AnnotatedElement接口,java处理注解的原理如下:

    @Getter
    @Setter
    public class Person{
    
        @Name("狂刀")
        private String name;
    
        @Gender(gender=Gender.GenderType)
        private String gender;
    
        @Profile(id=1001, height=180, nativePlace="CN")
        private String profile;            
    }
    
    public class CustomUtils{
        
        public static void getInfo(Class<?> clazz){
    
            Sring name; String gender; String profile;
            Field[] fields = clazz.getDeclaredFields();
            for(Field field : fields){
              if(field.isAnnotationPresent(Name.class)){
            Name arg0 = field.getAnnotation(Name.class);
              name = name + arg0.value();
         }   if(field.isAnnotationPresent(Gender.class)){
             Gender arg0 = field.getAnnotation(Gender.class);
             gender = gender + arg0.gender().toString();     
          }
           if(field.isAnnotationPresent(Profile.class)){
             Profile arg0 = field.getAnnotation(Profile.class);
             profile = profile + "id = " + arg0.id + ", height = " + arg0.height + ",nativePlace = " + arg0.nativePlace;
           } } } }

    自定义注解 && Spring AOP的使用

    #==========================================================================================================================
    
           通常使用场景:自定义注解 ==》Spring AOP中获取注解,并处理

    @Around("publicMethods() && @annotation(timedAnnotation)")
    public Object instrumentTimed(ProceedingJoinPoint pjp, TimingTimed timedAnnotation) throws Throwable {
      String name = name(pjp.getTarget().getClass(), StringUtils.hasLength(timedAnnotation.name())

                          ? timedAnnotation.name() : pjp.getSignature().getName(), "timingTimer");
      Metric metric = registry.getMetric(name);
      if (metric == null) {
        RedAlertMetric redAlertMetric = new RedAlertMetric(new TimingTimer(), name,
                      timedAnnotation.measurement(), timedAnnotation.interval());
        metric = registry.register(name, redAlertMetric);
      }
      if (metric != null && metric instanceof RedAlertMetric) {
          Metric timer = ((RedAlertMetric) metric).getMetric();
        if (timer != null && timer instanceof TimingTimer) {
          TimingTimer.Context tc = ((TimingTimer) timer).time();
          try {
            return pjp.proceed();
          } finally {
            tc.stop();
          }
        } else {
          return pjp.proceed();
        }
      } else {
      return pjp.proceed();
      }
    }

    
    
    #==========================================================================================================================

    附,参考文章:

    [1] http://blog.csdn.net/u013045971/article/details/53433874 

    [2] 自定义注解的使用Demo

  • 相关阅读:
    谈谈编译和运行
    全国车辆违章查询API文档及demo
    两款模拟键盘输入和鼠标点击的命令行工具
    利用AFNetworking框架去管理从聚合数据上面请求到的数据
    谈 API 的撰写
    谈 API 的撰写
    (四)Oracle条件查询,分页查询
    (三)Oracle字符串操作
    (二)Oracle数据库原理
    (一)Oracle安装详解
  • 原文地址:https://www.cnblogs.com/RunForLove/p/7079633.html
Copyright © 2011-2022 走看看