【译】spring注解编程模型

原文链接: https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model#stereotype-annotations

原文链接: https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model#stereotype-annotations

本文内容

  1. 概观
  2. 术语
  3. 例子
  4. 常问问题

一、概观

多年来,Spring Framework不断发展对注解的支持,比如元注解和组合注解的支持。本文档旨在帮助开发人员(Spring的最终用户,Spring Framework和Spring组合项目的开发人员)开发和使用Spring注解。

二、本文档的目标

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

  • 如何使用Spring注释。
  • 如何开发用于Spring的注释。
  • Spring如何找到注释(即Spring的注释搜索算法如何工作)。

三、本文档的非目标

本文档的目的不是说明Spring Framework中特定注释的语义或配置选项。需要查看相关关特定注释的详细信息,建议开发人员查阅相应的Javadoc或参考官网文档的相应部分。

四、术语

1.元注解

元注释是java基础注解来声明注解。因此,一个注解必然是被元注解而注解的。例如,任何注解被声明都是 @Documented从java.lang.annotation包中进行元注释的。

2.模式注解

模式注解是被用于声明在应用程序中个一个组件的角色。例如,@Repository 注解在Spring Framework中是任何满足存储库角色或构造型(也称为数据访问对象或DAO)的类的标记。

@Component是任何Spring管理组件的通用模式注解。任何被 @Component 标准的组件均为组件扫描的候选对象。类 似地,凡是被 @Component 元标注(meta-annotated)的注解,如 @Service,当任何组件标注它时,也被视作组件扫 描的候选对象。

核心Spring提供了一些模式注解开箱即用,包括但不限于:@Component,@Service,@Repository, @Controller,@RestController,和@Configuration。@Repository, @Service等等都是@Component的扩展化。

3.组合注释

组合注解是元注解与相结合的那些元注释相关联成一个单一的自定义注解的行为的意图的一个或多个注解。例如,一个名为@TransactionalService使用Spring里面的 @Transactional和@Service注释进行注解的注解是一个组合注释,它结合了@Transactional和@Service的语义。 @TransactionalService是在技??术上自定义的一个模式注解。

4.注释存在

一个注解无论是直接标注还是间接标注一个bean,这个注解在java8的java.lang.reflect.AnnotatedElement类注释中所约定的含义和特性都不会有任何改变。
在Spring框架里面,注释被认为是元存在,如果注释被声明为一些其他的注释的元注释这是一个元件上存在的元件上。例如,鉴于上述 @TransactionalService,我们可以说,@Transactional是元存在 于直接与注释的任何类@TransactionalService。

5.属性别名和覆盖

一个属性别名是从一个注释属性到另一个注释属性的别名。一组别名中的属性可以互换使用,并视为等效。属性别名可以分类如下。

显式别名:如果一个注释中的两个属性被声明为彼此的别名@AliasFor,则它们是显式别名。
隐式别名:如果一个注释中的两个或多个属性被声明为元注释中相同属性的显式覆盖@AliasFor,则它们是隐式别名。
传递隐式别名:在一个注释中给出两个或多个属性,这些属性被声明为元注释中属性的显式覆盖@AliasFor,如果属性有效地覆盖了遵循传递定律的元注释中的相同属性 ,则它们是传递隐式别名。

一个属性重写是一个重写(或阴影)在元注释的注释属性。属性覆盖可以分类如下。

隐式覆盖:给定的属性A中的注解@One和属性A的标注@Two,如果@One是元注解为@Two,然后在属性A中的注释@One是一个隐含的倍率为属性A的标注@Two只在命名约定为主(即,两个属性被命名A)。

显示覆盖:如果属性A被声明为属性的别名B在通过元注释@AliasFor,则A是一个明确的覆盖了B。

传递明确覆盖:如果注解@One中的成员A明确覆盖了注解@Two中的成员B,而且成员B实际覆盖了注解@Three中的成员C,那么因为覆盖的传递性,所以成员A实际覆盖了成员C。

五.例子

Spring Framework和Spring portfolio (https://github.com/sbrannen/spring-polyglot) 项目中的许多注释都使用@AliasFor注释来声明属性别名和属性覆盖。常见的例子包括@RequestMapping, @GetMapping和@PostMapping从Spring MVC的以及注释,比如@SpringBootApplication和@SpringBootTest从Springboot启动。

以下部分提供了演示这些功能的代码段。

1.使用@AliasFor声明属性别名

Spring Framework 4.2引入了一流的支持,用于声明和查找注释属性的别名。该@AliasFor注释可被用于声明一对混叠属性内的单个注释或从在自定义由注释一个属性声明的别名在元注释的属性。

例如,@ContextConfiguration从spring-test模块声明如下。

public  @interface  ContextConfiguration { @AliasFor(“ locations ”)
     String [] value()default {}; @AliasFor(“ value ”)
     String [] locations()default {}; // ...
}

该locations属性被声明为属性的别名value ,反之亦然。因此,以下声明@ContextConfiguration是等效的。

@ContextConfiguration(“/ test-config.xml ”)
 public  class  MyTests { / * ... * / }
@ContextConfiguration(value  =  “/ test-config.xml ”)
 public  class  MyTests { / * ... * / }
@ContextConfiguration(locations  =  “/ test-config.xml ”)
 public  class  MyTests { / * ... * / }
 

类似地,从元注释中覆盖属性的组合注释可@AliasFor用于精确控制在注释层次结构中覆盖哪些属性。实际上,甚至可以为value元注释的属性声明别名。

例如,可以使用自定义属性覆盖开发组合注释,如下所示。

@ContextConfiguration
public @interface MyTestConfig {

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

    // ...
}

上面的示例演示了开发人员如何实现自己的自定义组合注释 ; 然而,以下表明Spring本身在许多核心Spring注释中使用了这个特性。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {

    /**
     * Alias for {@link RequestMapping#name}.
     */
    @AliasFor(annotation = RequestMapping.class)
    String name() default "";

    /**
     * Alias for {@link RequestMapping#value}.
     */
    @AliasFor(annotation = RequestMapping.class)
    String[] value() default {};

    /**
     * Alias for {@link RequestMapping#path}.
     */
    @AliasFor(annotation = RequestMapping.class)
    String[] path() default {};

    // ...
}

2.Spring Composed和Spring Polyglot

Spring Composed项目是可以在在spring4.2.1和更高版本中使用的一系列组合注解。你可以在Spring MVC使用像@Get,@Post,@Put, 和@Delet这样的注解,也可以在Spring MVC REST应用中使用@GetJson,@PostJson等等注解。

如果你确信已经学习了足够深入的spring-composed例子,汲取了足够多的灵感,然后你可以为spring-Composed项目贡献出由你自定义的组合注解!

https://github.com/sbrannen/spring-composed
https://github.com/sbrannen/spring-polyglot

六、FAQ

1)可以@AliasFor与value属性一起使用@Component和@Qualifier?
最简洁的答案是:不可以。

将value在属性@Qualifier和模式注解(例如@Component,@Repository,@Controller,和任何自定义典型化注解)不能受其影响@AliasFor。原因是这些value属性的特殊处理是在@AliasFor发明之前的几年。因此,由于向后兼容性问题,根本不可能使用@AliasFor这些value属性。

七、待发掘主题

  • 记述 注解和标注了注解和元注解的类、接口、成员方法、成员变量、参数的通用搜索算法。

    1. 如果一个注解既是以注解又是以元注解的方式标注了一个元素会发生什么呢?
    2. 一个注解标注了@Inherited(包括自定义组合注解)后,是如何对搜索算法产生影响呢?
  • 记述 通过@AliasFor配置注解成员别名的技术原理。
    1. 如果一个成员和它的别名都声明在一个注解实例(成员和别名值相同或者不同时)中在技术上会发生什么?
    2. 较有代表性的一种情况是,一个AnnotationConfigurationException将会被抛出。
  • 记述_组合注解_的技术原理。
  • 记述 组合注解成员覆盖元注解成员的原理。
    1. 详细记述 查找成员的算法原理:

      • 基于命名约定的间接覆盖(换句话说,组合注解中有明确名字和类型的成员去覆盖元注解的成员)
      • 使用@AliasFor来直接覆盖
    2. 如果一个成员和它的众多别名中的一个在注解继承的某一层级中被重新声明了会发生什么?哪个会生效?
    3. 总之,成员变量声明时的冲突是怎么被解决的?


关注个人公众号:coder辰砂 ,目前正在慢慢的整理,前期还是基础技术部分整理

原文地址:https://www.cnblogs.com/tojian/p/10091054.html

时间: 2024-10-01 09:27:59

【译】spring注解编程模型的相关文章

Spring Security编程模型

1.采用spring进行权限控制 url权限控制 method权限控制 实现:aop或者拦截器(本质就是之前之后进行控制)--------------------proxy就是 2.权限模型: 本质理论: RABC权限模型(可以参看这方面的理论研究,有充分的数学理论作支撑) =========================== 用户---名称,密码,备注 角色---角色名称 操作(权限)---添加,浏览---------------------(url,按钮,页签) 资源---人力资源库, =

spring注解开发中常用注解以及简单配置

一.spring注解开发中常用注解以及简单配置 1.为什么要用注解开发:spring的核心是Ioc容器和Aop,对于传统的Ioc编程来说我们需要在spring的配置文件中邪大量的bean来向spring容器中注入bean对象, 然而,通过注解编程可以缩短我们开发的时间,简化程序员的代码编写. 2.如何开启注解开发:最常用的方法是使用<mvc:annotation-driven/>来开启注解编程(用一个标签配置了spring注解编程的映射器和适配器,同时配置了许多的参数) 3.如何将有注解的be

Spring Batch批处理以及编程模型

1.批处理: 类似于SQL里面的批处理提交 2.场景: 业务定时进行批处理操作,但是批处理的编程模型是怎么的呢? 3.开源框架 Spring Batch 4.编程模型: reader-processor-writer JobLauncher - Job - JobExecution -JobParametersValidator JobExecution result = launcher.run(job, new JobParameters()); //runJob机制 5.策略 a.批量提交

Spring Cloud Stream教程(五)编程模型

本节介绍Spring Cloud Stream的编程模型.Spring Cloud Stream提供了许多预定义的注释,用于声明绑定的输入和输出通道,以及如何收听频道. 声明和绑定频道 触发绑定@EnableBinding 您可以将Spring应用程序转换为Spring Cloud Stream应用程序,将@EnableBinding注释应用于应用程序的配置类之一.@EnableBinding注释本身使用@Configuration进行元注释,并触发Spring Cloud Stream基础架构

三种方式实现观察者模式 及 Spring中的事件编程模型

观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧,你可以自信的告诉他,Spring中的ApplicationListener就运用了观察者模式. 让我们一步一步来,首先我们要知道到底什么是观察者模式,用Java是如何实现的,在这里,我将会用三种方式来实现观察者模式. 什么是观察者模式 在现实生活中,观察者模式处处可见,比如 看新闻,只要新闻开始播放

Fiori编程模型规范里注解 - @ObjectModel.readOnly工作原理解析

今天是农历鼠年大年初五,本文是鼠年第5篇文章,也是汪子熙公众号第204篇原创文章. 最近大家真是谈蝙蝠色变呀! SAP官网的ABAP Programming Model for Fiori帮助文档里,定义了很多注解(Annotation): https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/1709%20000/en-US/896496ecfe4f4f8b857c6d93d4489841.html 对于这些注解,我们可以从其

揭开SAP Fiori编程模型规范里注解的神秘面纱 - @OData.publish

今天是2020年2月1日鼠年大年初八,这是Jerry鼠年的第8篇文章,也是汪子熙公众号总共第207篇原创文章. Jerry的前一篇文章 揭开SAP Fiori编程模型规范里注解的神秘面纱 - @ObjectModel.readOnly工作原理解析,给大家分享了@ObjectModel.readOnly这个注解对应的Fiori UI和ABAP后台的工作原理. 今天我们继续研究另一个注解@OData.publish. 在SAP官网的ABAP Programming Model for SAP Fio

Spring基于事件驱动模型的订阅发布模式代码实例详解

代码下载地址:http://www.zuidaima.com/share/1791499571923968.htm 原文:Spring基于事件驱动模型的订阅发布模式代码实例详解 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理解它的几个关键点: 首先是一种对象间的一对多的关系:最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方): 当目标发送改变(发布),观察者(订阅者)就可以接收到改变: 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的

Spring注解配置事务管理——问题

在上下文中配置: <!-- 配置注解驱动的Spring MVC控制器编程模型. --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /