Spring 注解编程模型

2018-05-12  本文已影响81人  simoscode

(Spring注解编程模型这篇博文,转译自Spring注解编程模型.)

说明

本文档与Spring Framework 4.2的发布一起引入; 然而,这个文档是一直在完善的.因此,一段时间后你可以看到文档会更新.

目录

概述

多年来,Spring框架持续演变它对注解,元注解和组合注解的支持.这个文档旨在帮助开发者(包括Spring的终端开发者和Spring框架开发者和Spring其他项目开发者)开发和使用Spring注解.

本文档目的

本文档的主要目标包括以下内容的解释:

非本文档目的

这个文档目的不是解释Spring框架特定注解的语义或者配置选项.有关特定注释的详细信息,鼓励开发人员查阅相应的Javadoc或参考手册的适用部分。

术语

元注解

元注解是用来声明其他注解的注解.一个注解被元注解如果它被其他注解注解.比如,任何被声明为可以生成javac的注解都被java.lang.annotation包中的@Documented元注解.

原型注解

原型注解是用来声明组件在应用中角色的注解.比如,@Repository注解在Spring框架中用标识这个类的角色是实现repository(也称数据访问对象或DAO).
@Component是Spring管理组件的通用原型注解.任何被@Component注解的组件,都是组件扫描的候选者.同理,被@Component元注解注解的注解用于注解其他任何其他组件,这些组件也会是组件扫描的候选者.比如,@Service@Component元注解.
核心Spring提供几个开箱即用的原型注解,包括但不限于:@Component, @Service, @Repository, @Controller, @RestController, and @Configuration. @Repository, @Service等都是@Component的特例.

组合注解

组合注解是被一个或多个注解元注解的注解,目的是组合这些元注解的功能到一个单一的自定义注解当中.比如,一个名为@TransactionalService的注解被Spring的@Transactional@Service元注解是一个组合注解,组合了@Transactional@Service的语义.@TransactionalService技术上也是一个自定义的原型注解

注解存在

术语直接存在(directly present),间接存在(indirectly present),存在(present ) 具有与Java8的java.lang.reflect.AnnotatedElement类级别Javadoc一样的含义.
在Spring,一个注解被认为是元存在(meta-present )在一个元素上,如果这个注解被声明为元注解在其他注解上,然后被元注解的注解用于一个元素上.例如,前面提到过的@TransactionalService,我们可以说@Transactional元存在任何其他直接被@TransactionalService注解的类

属性别名和覆盖

一个属性别名是一个别名从一个注解属性到另一个注解属性.一组别名中的属性可以互换使用,并被视为等同。属性别名可以分类如下:
  1. 显式别名:如果两个属性在一个注解当中可以声明对方为别名使用@AliasFor,它们是显式别名.
  2. 隐式别名:如果两个或多个属性在一个注解中被声明显式覆盖元注解的相同属性通过@AliasFor,它们是隐式别名.
  3.传递隐式别名:给定两个或多个属性在一个注解中被声明显式覆盖元注解的相同属性通过@AliasFor.如果这些属性有效地覆盖了遵循传递性规则元注释中的相同属性 ,则它们是传递式隐式别名
属性覆盖就是一个注解的属性覆盖元注解的注解属性.属性覆盖可以分类如下:
 1.隐式覆盖:给定属性A在注解@one和属性A在注解@two,如果@one被@two元注解,然后注解@one的属性A隐式覆盖注解@two的属性A完全基于命名约定(比如两个的属性都命名为A).
2.显式覆盖: 如果属性A声明为元注解属性B的别名通过@AliasFor,然后A就隐式覆盖B.
3.传递式隐式覆盖: 如果注解@one的属性A显式覆盖注解@two的属性B,并且B又显式覆盖注解@three的属性C,那么A就就传递显式覆盖属性c.

例子

Spring Composed

Spring Composed项目是Spring框架4.2.1及以上组合注解使用的集合.这里你可以找到注解如@Get, @Post, @Put, 和 @Delete 使用在Spring MVC和@GetJson, @PostJson等注解使用在Spring MVC REST 应用.
务必检出spring-composed获取更多例子和灵感或贡献你自己自定义的组合注解.

定义属性别名使用@AliasFor

Spring框架4.2版本引入一流的支持对注解属性别名的定义和查找.@AliasFor注解可以用来定义一组别名属性在单个注解中或者自定义组合注解的属性给元注解的属性定义一个别名.
比如,spring-test 模块中@ContextConfiguration被定义如下所示:

public @interface ContextConfiguration {

@AliasFor("locations")
String[] value() default {};

@AliasFor("value")
String[] locations() default {};

// ...
}

同样,组合注解覆盖元注解的属性可以使用@AliasFor,`@AliasFor`以便精确控制注释层次结构中的哪些属性被重写.实际上,甚至可以为meta-annotation 的value属性声明一个别名.
比如,可以使用自定义属性覆盖开发一个组合注解,如下所示:

@ContextConfiguration
public @interface MyTestConfig {

@AliasFor(annotation = ContextConfiguration.class, attribute = "value")
String[] xmlFiles();

// ...
}

常见问题

1)@AliasFor可否用于 @Component 和 @Qualifier的属性?

简单回答:不行.
    value属性在@Qualifier和在原型注解(如@Component, @Repository, @Controller, 和其他任何自定义原型注解)不能被@AliasFor影响.原因是这些value特性的特殊处理在@AliasFor发明的数年前就已经存在.因此,为了向后兼容问题不可能使用@AliasFor 在value这些属性.

附录

使用@AliasFor的注释

从Spring Framework 4.2开始,来自核心Spring的以下注释将使用 @AliasFor声明其value属性的别名

主题尚未覆盖的

上一篇下一篇

猜你喜欢

热点阅读