springMVC的自定义annotation(@Retention@Target)详解

自定义注解:

  使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其余细节。在定义注解时,不能继承其余的注解或接口。@interface用来声明一个注解,其中的每个方法其实是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。能够经过default来声明参数的默认值。html

定义注解格式:   public @interface 注解名 {定义体}java

  注解参数的可支持数据类型:git

    1.全部基本数据类型(int,float,boolean,byte,double,char,long,short)     2.String类型     3.Class类型     4.enum类型     5.Annotation类型     6.以上全部类型的数组github

  Annotation类型里面的参数该怎么设定:   第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;      第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;     第三,若是只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。数组

  简单的自定义注解和使用注解实例:   bash

package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 水果名称注解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}
复制代码
package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 水果颜色注解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 颜色枚举
     * @author peida
     *
     */
    public enum Color{ BULE,RED,GREEN};
    
    /**
     * 颜色属性
     * @return
     */
    Color fruitColor() default Color.GREEN;

}
复制代码
package annotation;

import annotation.FruitColor.Color;

public class Apple {
    
    @FruitName("Apple")
    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;
    
    
    
    
    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
    public String getAppleColor() {
        return appleColor;
    }
    
    
    public void setAppleName(String appleName) {
        this.appleName = appleName;
    }
    public String getAppleName() {
        return appleName;
    }
    
    public void displayName(){
        System.out.println("水果的名字是:苹果");
    }
}
复制代码

元注解(meta-annotation):

元注解的做用就是负责注解其余注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型做说明。Java5.0定义的元注解:  1.@Target,用于描述注解的使用范围(方法、构造方法、成员变量、枚举值)    app

取值(ElementType)有:ide

1.CONSTRUCTOR:用于描述构造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部变量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述参数 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明函数

   2.@Retention,表示须要在什么级别保存该注释信息,用于描述注解的生命周期工具

取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在运行时有效(即运行时保留)(属性值是RUTIME,这样注解处理器能够经过反射,获取到该注解的属性值)

3.@Documented 用于描述其它类型的annotation应该被做为被标注的程序成员的公共API,所以能够被例如javadoc此类的工具文档化   4.@Inherited@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。若是一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

注解的使用:

第一步:新建一个annotation,名字为:MyAnnotation.java。

package com.dragon.test.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by gmq on 2015/9/10.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{

    String hello () default "hello";
    String world();
}
复制代码

第二步:创建一个MyTest.java 来使用上面的annotation。

package com.dragon.test.annotation;

/**
 * Created by gmq on 2015/9/10.
 */
public class MyTest
{

    @MyAnnotation(hello = "Hello,Beijing",world = "Hello,world")
    public void output() {
        System.out.println("method output is running ");
    }
}
复制代码

第三步:用反射机制来调用注解中的内容

package com.dragon.test.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 用反射机制来调用注解中的内容
 * Created by gmq on 2015/9/10.
 */
public class MyReflection
{
    public static void main(String[] args) throws Exception
    {
        // 得到要调用的类
        Class<MyTest> myTestClass = MyTest.class;
        // 得到要调用的方法,output是要调用的方法名字,new Class[]{}为所须要的参数。空则不是这种
        Method method = myTestClass.getMethod("output", new Class[]{});
        // 是否有类型为MyAnnotation的注解
        if (method.isAnnotationPresent(MyAnnotation.class))
        {
            // 得到注解
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            // 调用注解的内容
            System.out.println(annotation.hello());
            System.out.println(annotation.world());
        }
        System.out.println("----------------------------------");
        // 得到全部注解。必须是runtime类型的
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations)
        {
            // 遍历全部注解的名字
            System.out.println(annotation.annotationType().getName());
        }
    }
}
复制代码

输出:

Hello,Beijing Hello,world

参考:www.cnblogs.com/gmq-sh/p/47…


注解的概念

注解(Annotation),也叫元数据(Metadata),是Java5的新特性,JDK5引入了Metadata很容易的就可以调用Annotations。注解与类、接口、枚举在同一个层次,并能够应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中,用来对这些元素进行说明注释。

注解的语法与定义形式

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

以 java.lang.annotation 中定义的 Target 注解来讲明:

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.ANNOTATION_TYPE } )
public @interface Target {
    ElementType[] value();
}
复制代码

源码分析以下: 第一:元注解@Retention,成员value的值为RetentionPolicy.RUNTIME。 第二:元注解@Target,成员value是个数组,用{}形式赋值,值为ElementType.ANNOTATION_TYPE 第三:成员名称为value,类型为ElementType[] 另外,须要注意一下,若是成员名称是value,在赋值过程当中能够简写。若是成员类型为数组,可是只赋值一个元素,则也能够简写。如上面的简写形式为:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}
复制代码

注解的分类

注解的分类有两种分法:

第一种分法

一、基本内置注解,是指Java自带的几个Annotation,如@Override、Deprecated、@SuppressWarnings等;

二、元注解(meta-annotation),是指负责注解其余注解的注解,JDK 1.5及之后版本定义了4个标准的元注解类型,以下:

@Target @Retention @Documented @Inherited 三、自定义注解,根据须要能够自定义注解,自定义注解须要用到上面的meta-annotation

参考:blog.csdn.net/github_3518…


Java元注解@Retention规则

@Retention是java当中的一个元注解,该元注解一般都是用于对软件的测试

一、适用方式:
@Retention(RetentionPolicy.RUNTIME)
    @interface Task{.......}
复制代码

参数RetentionPolicy.RUNTIME就说明了,@Task注解在程序运行时是可见的 RetentionPolicy的枚举类型还有SOURCE、CLASS分别指定注解对于那个级别是可见的,可是,咱们通常都是用RUNTIME,由于这是在程序运行时能够对注解进行读取,从而易于软件的测试

二、接下来咱们要先介绍一下java程序的内省和反射机制,以后在讨论@Retention的具体用法实例

在java虚拟机JVM在运行时,就会将类进行加载,这时,每一个类都会生成一个Class数据类型的对象(Class类在java.lang.Class中),这个对象就是对应类的“运行时对象”,经过这个运行时对象,就可以获取对应类的许多信息,也就是说,运行时对象实际就是对应类的一个映射,这就java的内省反射机制

三、接下来咱们讨论一下,这个Class运行时对象的使用

① 获取对应类的Class数据类型的运行时对象的引用——getClass()

public class Point{.....} //声明一个类
     Point pt = new Point(); //建立对应类的实例对象
     Class cls = pt.getClass() ;    //则cls 就指向了Point类的运行时对象
复制代码

②运行时对象cls的成员函数

<1>public String  getName()
     返回对应类的类名
     
<2>public boolean isAnnotationPresent(注解名.class)
     断定指定的"注解"是否在运行时注解了 cls 的对应类
     
     <3>public boolean isAnnotation();
     断定cls 是否在运行时被任何注解 注解过
     
<4>public A getAnnotation(注解名.class)
     A 指的是一个注解的类型,具体用法以下:
     @Retention(RetentionPolicy.RUNTIME) //指定@Task运行时可见
     @interface Task{String descirption(); }
     
     @Task(descroption="NoFinished")   //为computer做注
     class Computer{.....} 
     则  Computer my = new Computer() ;
         Class cls = my.getClass() ;
         Task tk = (Task) cls.getAnnotation(Task.class);
         //这时 tk 就指向了标注Computer的注解@Task
         tk.description(); //调用@Task中的description(),输出"NoFinishing"
         
 <5> public Method[] getMethods()
        返回由对应类中的全部的方法造成的Method数组,每一个Method对象都惟一对应
        一个对应类中的方法,经过Method[i]就能够得到对应方法的信息
        (Method类在java.lang.reflect.Method中)
       
        这个Method类也有不少成员方法,用来获取对应的方法的信息

   		如也有:
       public boolean isAnnotationPresent(注解名.class)
       断定对应的方法是否被指定的注所注解
       public A getAnnotation(注解名.class)
       用法和上面的讲述的同样,之不过建立的注解型的引用变量指向的是 "标记对应方法的注解"
复制代码

上面将全部的成员方法只有在注解运行时可见的状况下才可以发挥做用,因此@Retention变得颇有用

参考:www.cnblogs.com/PengLee/p/3…

相关文章
相关标签/搜索