一、Annotation基本概念

Annotation是jdk5以后出现的新特性,在jdk中,其内置了许多自己的Annotation,例如@Override,@SuppresWarning,@Deprecated等等,其中一些Annotation是标志性的Annotation,例如@Override就是表示这个类要重写父类的方法。

我们首先要清楚的知道一点,其实Annotation和Class、Interface这些一样,都是类级别的,而且我们创建的每一个Annotation都默认的继承了java.lang.annotation.Annotation这个接口,注意:如果一个接口继承了这个Annotation接口,那么这个接口并不是一个Annotation。

我们接下来自己创建一个简单的Annotation:

public @interface MyAnnotation
{
    String value();
    String name() default "xiaoluo";
}

这样就定义了我们自己的一个Annotation了,它的标识符就是  @interface,同样,Annotation里面可以定义我们的属性,例如,上面的例子我就定义了两个String类型的属性,一个是value属性,一个是name属性,注意:在Annotation里定义属性,属性后面都要加上括号。同时我们还可以给Annotation的属性设置默认值,通过 default 这个关键字来设置默认值,接下来我们就可以使用我们自己定义的Annotation了:

@MyAnnotation(value="hello", name="world")
public class AnnotationTest
{
    @MyAnnotation("xiaoluo")
    public void hello()
    {
        System.out.println("This is my Annotation!");
    }
}
 

我们看到,这个时候我们就可以在类上面、方法上面使用我们的Annotation了,注意:在自己定义的Annotation中,如果为其设置了属性,则我们必须要给其属性赋值

在上面的例子中,我们看到 @MyAnnotation(value="hello", name="world") 这里就是给其 value属性和name 属性赋值,而在下面的那个Annotation中:

@MyAnnotation("xiaoluo"),我们没有指定其属性名,那么它是赋值给谁呢?在Annotation中,如果我们定义了一个 value 属性,那么我们在使用该Annotation,给其赋值时,可以不用写出属性的名字,即value。

怎么样,简单吧,这样我们就定义并使用了我们的Annotation了。

二、Retention和RetentionPolicy

在初步了解了Annotation之后,我们再来看看Retention和RetentionPolicy这两个概念,Retention的中文意思是,保留、持有,同样,Retention也是一个Annotation,通过这个注解,我们可以指定我们自己定义的Annotation的保留范围,其默认值是有三个,是枚举类型的值,RetentionPolicy.CLASS(这个是Retention的默认值,表示这个Annotation会被编译到class文件当中), RetentionPolicy.RESOURCE(这个表示Annotation仅仅在编译的时候有效,起到提示作用,并不会被编译到class文件当中去), RetentionPolicy.RUNTIME(这个表示Annotation不仅会被编译到class文件当中,而且会在JVM运行中也可以得到这个Annotation,这样我们就可以通过反射来得到Annotaion,并对其进行一些操作了),我们来看看jdk自带的一些Annotation,其Retention分别是什么:

 
@Retention(value=SOURCE)
public @interface Override

@Retention(value=SOURCE)
public @interface SuppressWarnings

@Retention(value=RUNTIME)
public @interface Deprecated
 

我们看到,Deprecated的RetentionPolicy是RUNTIME的,这样我们可以通过反射在运行时得到其Annotation,接下来我们自己来指定我们刚定义的MyAnnotation为RUNTIME:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
    String value();
    String name() default "xiaoluo";
}

这个时候,我们定义的Annotation就会被编译到class文件当中去,并且在运行时可以得到它,接下来我们来通过一个例子来看看如何使用反射机制得到我们的Annotation以及我们设置的属性值,java的API指定了访问得到Annotation的方法,我们的Class,Method,Constructor等等这些都默认实现了 AnnotatedElement 这个接口,这个接口定义了四个常用的方法:

 
<T extends Annotation> T  getAnnotation(Class<T> annotationClass)    // 根据Annotation.class得到这个Annotation

Annotation[] getAnnotations()    //  得到一个Annotation数组

Annotation[] getDeclaredAnnotations()  //  也是得到一个Annotation数组

boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)    //  判断是否为被当前的Annotation所标识
 
 
@MyAnnotation("hello")
public class AnnotationTest
{
    @MyAnnotation(value="xiaoluo", name="welcome")
    public void hello()
    {
        System.out.println("This is my Annotation!");
    }

    public static void main(String[] args) throws Exception
    {
        //    得到AnnotationTest这个类的 class 对象
        Class<AnnotationTest> clazz = AnnotationTest.class;

        //    得到AnnotationTest的一个实例对象
        AnnotationTest test = (AnnotationTest)clazz.newInstance();

        //    得到方法名为hello的Method对象
        Method method = clazz.getMethod("hello", new Class[]{});

        //    判断hello这个方法是否被MyAnnotation这个注解所标记
        if(method.isAnnotationPresent(MyAnnotation.class))
        {
            //    得到我们的MyAnnotation这个注解
            MyAnnotation myAnnotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

            System.out.println(myAnnotation.name() + ", " + myAnnotation.value());

            method.invoke(test, new Object[]{});
        }
    }
}
 

我们来看看,因为我们的@MyAnnotation设置了其RetentionPolicy为RUNTIME,所以我们可以在通过反射在运行时得到该Annotation对象,结果输出为:

welcome, xiaoluo
This is my Annotation!

通过这个例子,我想大家应该知道了RecentPolicy的三个值的含义了吧,我们都可以设置其为RUNTIME,这样就可以在运行时对其进行判断来处理我们的业务逻辑了

三、Target和ElementType

最后我们来看看Target和ElementType这两个东东,Target这个也是一个注解,这个Annotation是用来指定我们的Annotation可以标志的范围,例如定义在类上,定义在方法上等等,其value就是通过ElementType来指定的,我们来看看ElementType有哪些值:

 
ANNOTATION_TYPE     // 可以定义在Annotation上
CONSTRUCTOR         // 可以定义在构造函数上
FIELD          // 可以定义属性上

LOCAL_VARIABLE    // 可以定义在方法的局部变量上

METHOD         // 可以定义在方法上

PACKAGE        // 可以定义在包上
  
PARAMETER       // 可以定义在方法的参数上

TYPE         // 可以定义在类上、接口上
 

我们也可以在刚才定义的MyAnnotation上设置我们的Target:

 
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
    String value();
    String name() default "xiaoluo";
}
 

表示MyAnnotation可以定义在类上还有方法上,如果在其他地方定义该注解,则会编译不通过

spring annotation简述的更多相关文章

  1. 【Spring】简述@Configuration配置类注册BeanDefinition到Spring容器的过程

    概述 本文以SpringBoot应用为基础,尝试分析基于注解@Configuration的配置类是如何向Spring容器注册BeanDefinition的过程 其中主要分析了 Configuratio ...

  2. Spring AOP简述

    使用面想对象(Object-Oriented Programming,OOP)包含一些弊端,当需要为多个不具有继承关系的对象引入公共行为时,例如日志,安全检测等.我们只有在每个对象中引入公共行为,这样 ...

  3. Spring Annotation Processing: How It Works--转

    找的好辛苦呀 原文地址:https://dzone.com/articles/spring-annotation-processing-how-it-works If you see an annot ...

  4. Spring(一)简述

    一.Spring简述 一段费话 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2 ...

  5. Java 第六天 Spring Annotation 和其它

    Annotation,是Java语言中的一种特殊的元数据语法,Spring支持使用annotation来进行对象实例化和装配 使用Annotation在Spring的配置xml中添加context命名 ...

  6. [转载]Spring Annotation Based Configuration

    Annotation injection is performed before XML injection, thus the latter configuration will override ...

  7. Spring(一)简述(转载)

    原文出自:http://www.cnblogs.com/liunanjava/p/4396794.html 一.Spring简述 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量 ...

  8. Spring Annotation注解进行aop的学习

    使用Maven管理项目,pom文件为: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...

  9. spring annotation功能备注

      @Autowired @Autowired 注释可以在 setter 方法中被用于自动连接 bean.以type方式进行匹配. 一个构造函数 @Autowired 说明当创建 bean 时,即使在 ...

随机推荐

  1. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  2. python signal信号

    作用:发送和接收异步系统信号 信号是一个操作系统特性,它提供了一个途径可以通知程序发生了一个事件并异步处理这个事件.信号可以由系统本身生成,也可以从一个进程发送到另一个进程. 由于信号会中断程序的正常 ...

  3. final static 深度解析

    function test(){ var a = b = 10; } test( ); alert(b); 由上一篇博客说起,最后输出的是10.引起歧义的原因是全局变量和局部变量的关系.顺着这个话题, ...

  4. HTML5+Activex+Singr+ABP+MongoDB

    最近在.net DDD开发领域有个炒的很火的框架叫ASP.NET Boilerplate看上去很牛逼的样子,为什么我会觉得很牛逼呢?  第一:我看不懂.  第二:关注的人多,我选框架就像进饭馆,哪家人 ...

  5. 【LoadRunner】OSGI性能测试实例

    其实我们就两点 Ø  确定测试登录最大并发用户数:Ø  事务平均响应时间 (两个查询) 得到这个任务 如何展开测试工作呢? 一.WindowsResources 设置(其实不监控 设不设都行 我感觉) ...

  6. .NET DLR 上的IronScheme 语言互操作&&IronScheme控制台输入中文的问题

    前言 一直以来对Lisp语言怀有很崇敬的心里,<黑客与画家>对Lisp更是推崇备至,虽然看了不少有关Lisp的介绍但都没有机会去写段程序试试,就像我对C++一样,多少有点敬畏.这个周末花了 ...

  7. asp.net mvc4 使用 System.Web.Optimization 对javascript和style的引入、代码合并和压缩的优化(ScriptBundle,StyleBundle,Bundling and Minification )

    Bundling and Minification两个单词对今天的内容有个比较好的总结. 问题所在 一. 在asp.net包括mvc项目中,引入js和css也许有人认为是个很容易和很简单操作的事情,v ...

  8. linux常用命令之压缩打包

    DF df – report file system disk space usage 查看文件系统的使用清空 用法 df [-hi] [path] 选项 -h human readable ,以人类 ...

  9. 在Java中如何实现“Pless presss any key to continue.”

    import java.util.*; class Continue{ public static void main(String[] args){ Scanner scanner=new Scan ...

  10. FancyBox - 经典的 jQuery Lightbox 插件

    FancyBox 是一款非常优秀的弹窗插件,能够为图片.HTML 内容和其它任务的多媒体内容提供优雅的弹出缩放效果.作为是最流行的 Lightbox 插件之一,可以通过 fitToView 实现自适应 ...