-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Spring Annotation Programming Model
This document is being introduced in conjunction with the release of Spring Framework 4.2; however, this document is still a work in progress. As such, you can expect to see multiple updates throughout the course of the 4.2.x timeline.
Over the years, the Spring Framework has continually evolved its support for annotations, meta-annotations, and composed annotations. This document is intended to aid developers (both end users of Spring as well as developers of the Spring Framework and Spring portfolio projects) in the development and use of annotations with Spring.
This document has the following primary goals.
- Explain how to use annotations with Spring.
- Explain how to develop annotations for use with Spring.
- Explain how Spring finds annotations (i.e., how Spring's annotation search algorithms work).
This document does not aim to explain the semantics or configuration options for particular annotations in the Spring Framework. For details on a particular annotation, developers are encouraged to consult the corresponding Javadoc or applicable sections of the reference manual.
A meta-annotation is an annotation that is declared on another
annotation. An annotation is therefore meta-annotated if it is
annotated with another annotation. For example, any annotation
that is declared to be documented is meta-annotated with
@Documented from the java.lang.annotation package.
A composed annotation is an annotation that is meta-annotated with
one or more annotations with the intent of combining the behavior
associated with those meta-annotations into a single custom annotation.
For example, an annotation named @TransactionalService that is
meta-annotated with Spring's @Transactional and @Service annotations
is a composed annotation that combines the semantics of @Transactional
and @Service.
The terms directly present, indirectly present, and present have
the same meanings as defined in the class-level Javadoc for
java.lang.reflect.AnnotatedElement in Java 8.
In Spring, an annotation is considered to be meta-present on an element
if the annotation is declared as a meta-annotation on some other annotation
which is present on the element. For example, given the aforementioned
@TransactionalService, we would say that @Transactional is
meta-present on any class that is directly annotated with
@TransactionalService.
Spring Framework 4.2 introduced first-class support for declaring and
looking up aliases for annotation attributes. The @AliasFor
annotation can be used to declare a pair of aliased attributes within
a single annotation or to declare an alias from one attribute in a
custom composed annotation to an attribute in a meta-annotation.
For example, @ContextConfiguration from the spring-test module
is now declared as follows:
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
// ...
}
Similarly, composed annotations that override attributes from
meta-annotations can use @AliasFor for fine-grained control
over exactly which attributes are overridden within an annotation
hierarchy. In fact, it is even possible to declare an alias for the
value attribute of a meta-annotation.
For example, one can develop a composed annotation with a custom attribute override as follows.
@ContextConfiguration
public @interface MyTestConfig {
@AliasFor(annotation = ContextConfiguration.class, attribute = "value")
String[] xmlFiles();
// ...
}
As of Spring Framework 4.2, the following annotations from core Spring
use @AliasFor to declare aliases for their value attributes.
org.springframework.cache.annotation.Cacheableorg.springframework.cache.annotation.CacheEvictorg.springframework.cache.annotation.CachePutorg.springframework.context.annotation.ComponentScan.Filterorg.springframework.context.annotation.ComponentScanorg.springframework.context.annotation.ImportResourceorg.springframework.context.annotation.Scopeorg.springframework.context.event.EventListenerorg.springframework.jmx.export.annotation.ManagedResourceorg.springframework.messaging.handler.annotation.Headerorg.springframework.messaging.handler.annotation.Payloadorg.springframework.messaging.simp.annotation.SendToUserorg.springframework.test.context.ActiveProfilesorg.springframework.test.context.ContextConfigurationorg.springframework.test.context.jdbc.Sqlorg.springframework.test.context.TestExecutionListenersorg.springframework.test.context.TestPropertySourceorg.springframework.transaction.annotation.Transactionalorg.springframework.transaction.event.TransactionalEventListenerorg.springframework.web.bind.annotation.ControllerAdviceorg.springframework.web.bind.annotation.CookieValueorg.springframework.web.bind.annotation.CrossOriginorg.springframework.web.bind.annotation.MatrixVariableorg.springframework.web.bind.annotation.RequestHeaderorg.springframework.web.bind.annotation.RequestMappingorg.springframework.web.bind.annotation.RequestParamorg.springframework.web.bind.annotation.RequestPartorg.springframework.web.bind.annotation.ResponseStatusorg.springframework.web.bind.annotation.SessionAttributesorg.springframework.web.portlet.bind.annotation.ActionMappingorg.springframework.web.portlet.bind.annotation.RenderMapping
- Document the general search algorithm(s) for annotations and meta-annotations on classes, interfaces, methods, fields, parameters, and annotations.
- What happens if an annotation is present on an element both locally and as a meta-annotation?
- How does the presence of
@Inheritedon an annotation (including custom composed annotations) affect the search algorithm?
- Document support for annotation attribute aliases configured via
@AliasFor.- What happens if an attribute and its alias are declared in an annotation instance (with the same value or with different values)?
- Typically an
AnnotationConfigurationExceptionwill be thrown.
- Typically an
- What happens if an attribute and its alias are declared in an annotation instance (with the same value or with different values)?
- Document support for composed 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 the overridden meta-annotation)
- explicit mapping using
@AliasFor
- What happens if an attribute and one of its aliases are declared somewhere within the annotation hierarchy? Which one takes precedence?
- In general, how are conflicts involving annotation attributes resolved?
- Document the algorithm used when looking up attributes, specifically explaining:
- Document the special handling of the
valueattribute for@Componentand@Qualifier.