Spring 注解原理

一、背景

1、Annotation:

  提供了一种为程序元素设置元数据的方法,可用于修包、类、构造器、方法、成员变量、参数和局部变量(具体详见元注解 Target)的声明。

  注解可以被一些解析工具或者是编译工具进行解析。

  Annotation中的信息可以在编译、加载和运行时被读取(具体详见元注解 Retention),并执行相应的处理。

2、Metadata:

  中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。

  指从信息资源中抽取出来的用于说明其特征、内容的结构化的数据(如题名、版本、出版数据、相关说明、检索点等),用于组织、描述、检索、保存、管理信息和知识资源。

  任何文件系统中的数据都分为数据和元数据。数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息(inode…)等等。在集群文件系统中,分布信息包括文件在磁盘上的位置以及磁盘在集群中的位置。用户需要操作一个文件必须首先得到它的元数据,才能定位到文件的位置并且得到文件的内容或相关属性。

  HTML的head里有一个meta标签。meta的属性有两种(name、http-equiv),name属性用来描述网页的内容,http-equiv属性指示服务器在发送实际的文档之前先在要传送给浏览器的 MIME 文档头部包含名称/值对,比如用以说明主页制作所使用的文字以及语言。

3、XML:

  XML被广泛的应用于描述元数据。

4、XML vs Annotation:

xml的优点:
  • xml 作为可扩展标记语言最大的优势在于开发者能够为软件量身【定制】适用的标记,使代码更加通俗易懂。
  • 利用 xml 配置能使软件更具扩展性。例如 Spring 将 class 间的依赖配置在 xml 中,最大限度地提升应用的可扩展性。
  • 具有成熟的验证机制确保程序正确性。利用 Schema 或 DTD 可以对 xml 的正确性进行验证,避免了非法的配置导致应用程序出错。
  • 修改配置而无需变动现有程序。
xml的缺点:
  • 需要解析工具或类库的支持。
  • 解析 xml 势必会影响应用程序性能,占用系统资源。
  • 配置文件过多导致管理变得困难。
  • 编译期无法对其配置项的正确性进行验证,或要查错只能在运行期。
  • IDE 无法验证配置项的正确性。
  • 查错变得困难,往往配置的一个手误导致莫名其妙的错误。
  • 开发人员不得不同时维护代码和配置文件,开发效率变得低下。
  • 配置项与代码间存在潜规则。改变了任何一方都有可能影响另外一方。
Annotation 的优点:
  • 保存在 class 文件中,降低维护成本。
  • 无需工具支持,无需解析。
  • 编译期即可验证正确性,查错变得容易。
  • 提升开发效率。
Annotation的缺点:
  • 若要对配置项进行修改,不得不修改 Java 文件,重新编译打包应用。
  • 配置项编码在 Java 文件中,可扩展性差。

二、注解

1、@interface:定义一个Annotation类型的接口,可以包含成员变量。

 成员变量的一些规则
  • Annotation的成员变量以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和类型。
  • 使用带有属性的Annotation时,必须为其属性指定值,否则会报错。
  • 定义Annotation时可以使用【default】关键字为属性设置默认值。
  • 如果Annotation中具有名为【value】的属性,在使用时如果只使用value属性的话,可以不写属性名直接指定值。
  • Annotation的属性类型只能是基本类型、String、enum、Class及上述类型的一维数组类型。
  • 对于数组类型,当数组中只有一个元素时,可以省略大括号。

2、meta-annotation:

  四个原注解(@Target、@Retention、@Documented、@Inherited),注解其他注解。

  Java5.0定义了4个标准的 meta-annotation 类型,它们被用来提供对其它 annotation 类型作说明(只能作用在注解上,不能作用在其他程序元素上)。

  2.1、@Target:元素种类,指示注解类型所适用的程序元素的种类。由 ElementType 限定。

    • ElementType.TYPE:注解到接口、类、枚举、注解上
    • ElementType.FIELD:注解到属性字段、枚举的常量上
    • ElementType.METHOD:注解到方法上
    • ElementType.PARAMETER:注解到方法参数上
    • ElementType.CONSTRUCTOR:注解到构造方法上
    • ElementType.LOCAL_VARIABLE:注解到局部变量上
    • ElementType.ANNOTATION_TYPE:注解到注解类型元素的声明上(表明为原注解)
    • ElementType.PACKAGE:注解到包上
    • ElementType.TYPE_PARAMETER:注解到@since 1.8
    • ElementType.TYPE_USE:注解到@since 1.8

  2.2、@Retention:保留策略【重要】

    指示注解类型的注解要保留多久。如果注解类型声明中不存在 Retention 注解,则保留策略默认为 RetentionPolicy.CLASS

    • RetentionPolicy.SOURCE:注解保留在源代码中,但是编译的时候会被编译器所丢弃。
    • RetentionPolicy.CLASS:默认,注解会被保留在class文件中,但是在运行时期间就不会识别这个注解。
    • RetentionPolicy.RUNTIME:注解会被保留在class文件中,同时运行时期间也会被识别。所以可以使用反射机制获取注解信息。

  2.3、@Documented:文档化

    指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。

    一个类型的声明是用 @Documented 来注解的,则其注解将成为注解元素的公共 API 的一部分。

  2.4、@Inherited:自动继承

    说明子类可以继承父类中的该注解。

    指示注解类型被自动继承。如果在注解类型声明中存在 Inherited 元注解,并且用户在某一类声明中查询该注解类型,同时该类声明中没有此类型的注解,则将在该类的超类中自动查询该注解类型。此过程会重复进行,直到找到此类型的注解或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注解,则查询将指示当前类没有这样的注解。

  

 

 

    

    

 

sda

posted @ 2019-01-18 14:49  张界  阅读(2175)  评论(0编辑  收藏  举报