zoukankan      html  css  js  c++  java
  • Java注解拾遗

    注解简介:     

            注解Annotation是jdk1.5的新增功能,在现在的日常开发中,几乎离不开注解,写篇短文,来做个拾遗。

    注解作用:

            Annotation(注解)的作用是修饰包、类、构造方法、方法、成员变量等。

          注解语法及定义形式:

      @interface关键字定义
      注解包含成员,成员以无参数的方法的形式被声明。其方法名和返回值定义了该成员的名字和类型。
      成员赋值是通过@Annotation(name=value)的形式
      注解需要标明注解的生命周期,注解的修饰目标等信息,这些信息是通过元注解实现。

      举例:

           

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
        /**
         * Returns an array of the kinds of elements an annotation type
         * can be applied to.
         * @return an array of the kinds of elements an annotation type
         * can be applied to
         */
        ElementType[] value();
    }

           元注解@Retention,成员value的值为RetentionPolicy.RUNTIME、
           元注解@Target,成员value是个数组,用{}形式赋值,值为ElementType.ANNOTATION_TYPE
           成员名称为value,类型为ElementType[]

    注解分类:

    内置标准注解:

        @Override:用于修饰此方法覆盖了父类的方法
         @Deprecated:用于修饰已经过时的方法
         @SuppressWarnnings:用于通知java编译器禁止特定的编译警告

    元注解:

        @Target:说明Annotation所修饰的对象范围
        @Retention:说明Annotation的生命周期
        @Documented :Documented是一个标记注解,主要是用于javadoc
        @Inherited :Inherited也是一个标记注解,假如一个标记了Inherited的注解修饰一个类,那么继承于此类的子类,同样继承该注解
              这样虽然完成了继承,但是注解本身是不允许继承的。

    普通注解:

        自定义的完成特定任务的注解

    注解生命周期:

        注解的生命周期是由元注解Retention修饰的
        看下Retention的源码
        

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
    /**
    * Returns the retention policy.
    * @return the retention policy
    */
    RetentionPolicy value();
    }
    
    public enum RetentionPolicy {
    /**
    * Annotations are to be discarded by the compiler.
    */
    SOURCE,
    
    /**
    * Annotations are to be recorded in the class file by the compiler
    * but need not be retained by the VM at run time. This is the default
    * behavior.
    */
    CLASS,
    
    /**
    * Annotations are to be recorded in the class file by the compiler and
    * retained by the VM at run time, so they may be read reflectively.
    *
    * @see java.lang.reflect.AnnotatedElement
    */
    RUNTIME
    }

    SOURCE: 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃
    CLASS: 注解被保留到class文件,jvm加载class文件时候被遗弃。这是默认的生命周期
    RUNTIME: 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在,保存到class对象中,可以通过反射来获取

    注解的修饰目标:

      注解的修饰目标是由元注解Target修饰的

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
    /**
    * Returns an array of the kinds of elements an annotation type
    * can be applied to.
    * @return an array of the kinds of elements an annotation type
    * can be applied to
    */
    ElementType[] value();
    }
    
    public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,
    
    /** Field declaration (includes enum constants) */
    FIELD,
    
    /** Method declaration */
    METHOD,
    
    /** Formal parameter declaration */
    PARAMETER,
    
    /** Constructor declaration */
    CONSTRUCTOR,
    
    /** Local variable declaration */
    LOCAL_VARIABLE,
    
    /** Annotation type declaration */
    ANNOTATION_TYPE,
    
    /** Package declaration */
    PACKAGE,
    
    /**
    * Type parameter declaration
    *
    * @since 1.8
    */
    TYPE_PARAMETER,
    
    /**
    * Use of a type
    *
    * @since 1.8
    */
    TYPE_USE
    }

    TYPE:指的是在类,接口(包括注解)或者enum上使用的注解
    FIELD:指的在field属性,也包括enum常量使用的注解
    METHOD:指的是在方法声明上使用的注解
    PARAMETER:指的是在参数上使用的注解
    CONSTRUCTOR: 指的是在构造器使用的注解
    LOCAL_VARIABLE:指的是在局部变量上使用的注解
    ANNOTATION_TYPE:指的是在注解上使用的元注解
    PACKAGE:指的是在包上使用的注解

    自定义注解:

      自定义注解是利用注解方面很重要的一个方面,这次把项目里的一个自定义的注解分析下
    代码如下:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogMethod {
    }
    
    @Slf4j
    public class LogMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    String className = String.valueOf(methodInvocation.getMethod().getDeclaringClass());
    String methodName = methodInvocation.getMethod().getName();
    Object[] arguments = methodInvocation.getArguments();
    log.info("Before:" + className + "." + methodName + "()");
    log.info("Arguments:" + JsonTools.toJsonString(arguments));
    long start = System.currentTimeMillis();
    Object resultObj = methodInvocation.proceed();
    long end = System.currentTimeMillis();
    log.info("After:result is " + JsonTools.toJsonString(resultObj) + ",the execute time is " + (end - start) + " ms");
    
    return resultObj;
    }
    }

    具体配置:

    <bean id="logMethodInterceptor" class="com.*LogMethodInterceptor"/>
    <aop:config proxy-target-class="true">
    <aop:pointcut id="logMethodPointcut"
    expression="execution(* com*service.impl.*.*(..)) and @annotation(com.*annotation.LogMethod)"/>
    <aop:advisor advice-ref="logMethodInterceptor" pointcut-ref="logMethodPointcut"/>
    </aop:config>

    LogMethod 定义了一个 生命周期为RUNTIME 作用在METHOD上的注解
    LogMethodInterceptor 注解的处理器
    利用Spring的AOP完整在方法的出入口分别打印参数的相关日志

  • 相关阅读:
    Network in Network
    cord-in-a-box 2.0 安装指南
    L2 约束的最小二乘学习法
    点估计
    递归简介
    向量的L2范数求导
    优雅的线性代数系列三
    ansible批量部署nginx
    ansible批量部署mysql
    ansible批量部署tomcat
  • 原文地址:https://www.cnblogs.com/daily-note/p/7810604.html
Copyright © 2011-2022 走看看