Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Spring Annotation Programming Model

Sam Brannen edited this pageAug 31, 2023 ·22 revisions

Spring Annotation Programming Model

Table of Contents


Overview

Over the years, the Spring Framework has continually evolved its support forannotations,meta-annotations, andcomposed annotations. This document isintended to aid developers (both end users of Spring as well as developers ofthe Spring Framework and Spring portfolio projects) in the development and useof annotations with Spring.

See also:MergedAnnotation API internals

Goals of this Document

The primary goals of this document include explanations of the following:

  • How to use annotations with Spring.
  • How to develop annotations for use with Spring.
  • How Springfinds annotations (i.e., how Spring's annotation searchalgorithms work).

Non-goals of this Document

This document does not aim to explain the semantics or configuration optionsfor particular annotations in the Spring Framework. For details on a particularannotation, developers are encouraged to consult the corresponding Javadoc orapplicable sections of the reference manual.

Terminology

Meta-Annotations

Ameta-annotation is an annotation that is declared on anotherannotation. An annotation is thereforemeta-annotated if it is annotated withanother annotation. For example, any annotation that is declared to bedocumented is meta-annotated with@Documented from thejava.lang.annotation package.

Stereotype Annotations

Astereotype annotation is an annotation that is used to declare therole that a component plays within the application. For example, the@Repository annotation in the Spring Framework is a marker for any classthat fulfills the role orstereotype of a repository (also known asData Access Object or DAO).

@Component is a generic stereotype for any Spring-managed component.Any component annotated with@Component is a candidate forcomponent scanning. Similarly, any component annotated with an annotationthat is itself meta-annotated with@Component is also a candidate forcomponent scanning. For example,@Service is meta-annotated with@Component.

Core Spring provides several stereotype annotations out of the box,including but not limited to:@Component,@Service,@Repository,@Controller,@RestController, and@Configuration.@Repository,@Service, etc. are specializations of@Component.

Composed Annotations

Acomposed annotation is an annotation that ismeta-annotated with oneor more annotations with the intent of combining the behavior associated withthose meta-annotations into a single custom annotation. For example, anannotation named@TransactionalService that is meta-annotated with Spring's@Transactional and@Service annotations is a composed annotation thatcombines the semantics of@Transactional and@Service.@TransactionalService is technically also a customstereotype annotation.

Annotation Presence

The termsdirectly present,indirectly present, andpresenthave the same meanings as defined in the class-level Javadoc forjava.lang.reflect.AnnotatedElement in Java 8.

In Spring, an annotation is considered to bemeta-present on an elementif the annotation is declared as a meta-annotation on some other annotationwhich ispresent on the element. For example, given the aforementioned@TransactionalService, we would say that@Transactional ismeta-presenton any class that is directly annotated with@TransactionalService.

Attribute Aliases and Overrides

Anattribute alias is an alias from one annotation attribute to anotherannotation attribute. Attributes within a set of aliases can be usedinterchangeably and are treated as equivalent. Attribute aliases can becategorized as follows.

  1. Explicit Aliases: if two attributes in one annotation are declared asaliases for each other via@AliasFor, they areexplicit aliases.
  2. Implicit Aliases: if two or more attributes in one annotation aredeclared as explicit overrides for the same attribute in a meta-annotationvia@AliasFor, they areimplicit aliases.
  3. Transitive Implicit Aliases: given two or more attributes in oneannotation that are declared as explicit overrides for attributes inmeta-annotations via@AliasFor, if the attributeseffectively overridethe same attribute in a meta-annotation following thelaw of transitivity,they aretransitive implicit aliases.

Anattribute override is an annotation attribute thatoverrides (orshadows) an annotation attribute in a meta-annotation. Attribute overridescan be categorized as follows.

  1. Implicit Overrides: given attributeA in annotation@One andattributeA in annotation@Two, if@One is meta-annotated with@Two,then attributeA in annotation@One is animplicit override forattributeA in annotation@Two based solely on a naming convention (i.e.,both attributes are namedA).
  2. Explicit Overrides: if attributeA is declared as an alias forattributeB in a meta-annotation via@AliasFor, thenA is anexplicitoverride forB.
  3. Transitive Explicit Overrides: if attributeA in annotation@One isan explicit override for attributeB in annotation@Two andB is anexplicit override for attributeC in annotation@Three, thenA is atransitive explicit override forC following thelaw of transitivity.

Examples

Many of the annotations within the Spring Framework and Spring portfolioprojects make use of the@AliasFor annotation for declaringattributealiases andattribute overrides. Common examples include@RequestMapping,@GetMapping, and@PostMapping from Spring MVC as well as annotationssuch as@SpringBootApplication and@SpringBootTest from Spring Boot.

The following sections provide code snippets to demonstrate these features.

Declaring attribute aliases with @AliasFor

Spring Framework 4.2 introduced first-class support for declaring and lookingup aliases for annotation attributes. The@AliasFor annotation can be used todeclare a pair of aliased attributeswithin a single annotation or to declarean alias from one attribute in a custom composed annotation to an attribute ina meta-annotation.

For example,@ContextConfiguration from thespring-test module isdeclared as follows.

public @interfaceContextConfiguration {@AliasFor("locations")String[]value()default {};@AliasFor("value")String[]locations()default {};// ...}

Thelocations attribute is declared as an alias for thevalueattribute, and vice versa. Consequently, the following declarationsof@ContextConfiguration are equivalent.

@ContextConfiguration("/test-config.xml")publicclassMyTests {/* ... */ }
@ContextConfiguration(value ="/test-config.xml")publicclassMyTests {/* ... */ }
@ContextConfiguration(locations ="/test-config.xml")publicclassMyTests {/* ... */ }

Similarly,composed annotations that override attributes frommeta-annotations can use@AliasFor for fine-grained control over exactlywhich attributes are overridden within an annotation hierarchy. In fact, it iseven possible to declare an alias for thevalue attribute of ameta-annotation.

For example, one can develop a composed annotation with a custom attributeoverride as follows.

@ContextConfigurationpublic @interfaceMyTestConfig {@AliasFor(annotation =ContextConfiguration.class,attribute ="value")String[]xmlFiles();// ...}

The above example demonstrates how developers can implement their owncustomcomposed annotations; whereas, the following demonstrates thatSpring itself makes use of this feature in many core Spring annotations.

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documented@RequestMapping(method =RequestMethod.GET)public @interfaceGetMapping {/** * Alias for {@link RequestMapping#name}. */@AliasFor(annotation =RequestMapping.class)Stringname()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 {};// ...}

Spring Composed and Spring Polyglot

TheSpring Composed projectis a collection ofcomposed annotations for use with the Spring Framework4.2.1 and higher. There you will find annotations such as@Get,@Post,@Put, and@Delete that served as the inspiration for the@GetMapping,@PostMapping,@PutMapping, and@DeleteMapping annotations that arenow part of Spring MVC and Spring WebFlux.

Feel free to check outspring-composed for further examples and inspirationfor how you can implement your own customcomposed annotations, and for abit of geek humor and entertainment that further demonstrate the power of@AliasFor, take a look atSpring Polyglot.

FAQ

1) Can@AliasFor be used to alias thevalue attribute in@Qualifier?

No, thevalue attribute in@Qualifiercannot be influenced by@AliasFor. The reason is that the special handling of thevalue attribute for qualifiers was in place years before@AliasFor was invented, and that special handling is still in place.

2) Can@AliasFor be used to alias thevalue attribute for@Component and stereotype annotations?

The short answer is: No, not until Spring Framework 6.1

Prior to Spring Framework 6.1, thevalue attribute instereotype annotations (e.g.,@Component,@Repository,@Controller, and any custom stereotype annotations) could not be influenced by@AliasFor. The rationale is analogous to the explanation given for@Qualifier above. However, Spring Framework 6.1 introduces full support for aliasing thevalue attribute in@Component via@AliasFor. For example, see the source declaration of thename attribute in@ControllerAdvice.

Topics yet to be Covered

  • Document the general search algorithm(s) for annotations and meta-annotations on classes, interfaces, methods, fields, parameters, and annotations.
    • What happens if an annotation ispresent on an element both locally and as a meta-annotation?
    • How does the presence of@Inherited on an annotation (including custom composed annotations) affect the search algorithm?
  • Document support for annotation attribute aliases configured via@AliasFor.
    • What happens if an attributeand its alias are declared in an annotation instance (with the same value or with different values)?
      • Typically anAnnotationConfigurationException will be thrown.
  • Document support forcomposed annotations.
  • Document support for meta-annotation attribute overrides in composed annotations.
    • Document the algorithm used when looking up attributes, specifically explaining:
      • implicit mapping based on naming convention (i.e., composed annotation declares an attribute with the exact same name and type as declared in theoverridden meta-annotation)
      • explicit mapping using@AliasFor
    • What happens if an attributeand one of its aliases are declared somewhere within the annotationhierarchy? Which one takes precedence?
    • In general, how are conflicts involving annotation attributes resolved?
Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp