Merge branch '7.0.x'

This commit is contained in:
Sam Brannen
2026-08-20 14:57:50 +02:00
78 changed files with 355 additions and 356 deletions
@@ -38,7 +38,7 @@ In common with most `FactoryBean` implementations provided with Spring, the
`ProxyFactoryBean` class is itself a JavaBean. Its properties are used to:
* Specify the target you want to proxy.
* Specify whether to use CGLIB (described later and see also xref:core/aop-api/pfb.adoc#aop-pfb-proxy-types[JDK- and CGLIB-based proxies]).
* Specify whether to use CGLIB (described later and see also <<aop-pfb-proxy-types,JDK- and CGLIB-based proxies>>).
Some key properties are inherited from `org.springframework.aop.framework.ProxyConfig`
(the superclass for all AOP proxy factories in Spring). These key properties include
@@ -46,7 +46,7 @@ the following:
* `proxyTargetClass`: `true` if the target class is to be proxied, rather than the
target class's interfaces. If this property value is set to `true`, then CGLIB proxies
are created (but see also xref:core/aop-api/pfb.adoc#aop-pfb-proxy-types[JDK- and CGLIB-based proxies]).
are created (but see also <<aop-pfb-proxy-types,JDK- and CGLIB-based proxies>>).
* `optimize`: Controls whether or not aggressive optimizations are applied to proxies
created through CGLIB. You should not blithely use this setting unless you fully
understand how the relevant AOP proxy handles optimization. This is currently used
@@ -64,7 +64,7 @@ the following:
Other properties specific to `ProxyFactoryBean` include the following:
* `proxyInterfaces`: An array of `String` interface names. If this is not supplied, a CGLIB
proxy for the target class is used (but see also xref:core/aop-api/pfb.adoc#aop-pfb-proxy-types[JDK- and CGLIB-based proxies]).
proxy for the target class is used (but see also <<aop-pfb-proxy-types,JDK- and CGLIB-based proxies>>).
* `interceptorNames`: A `String` array of `Advisor`, interceptor, or other advice names to
apply. Ordering is significant, on a first come-first served basis. That is to say
that the first interceptor in the list is the first to be able to intercept the
@@ -76,7 +76,7 @@ factories. You cannot mention bean references here, since doing so results in th
+
You can append an interceptor name with an asterisk (`*`). Doing so results in the
application of all advisor beans with names that start with the part before the asterisk
to be applied. You can find an example of using this feature in xref:core/aop-api/pfb.adoc#aop-global-advisors[Using "`Global`" Advisors].
to be applied. You can find an example of using this feature in <<aop-global-advisors,Using "`Global`" Advisors>>.
* singleton: Whether or not the factory should return a single object, no matter how
often the `getObject()` method is called. Several `FactoryBean` implementations offer
@@ -394,7 +394,7 @@ execution-only semantics. You only need to be aware of this difference if you co
`@AspectJ` aspects written for Spring and use `proceed` with arguments with the AspectJ
compiler and weaver. There is a way to write such aspects that is 100% compatible across
both Spring AOP and AspectJ, and this is discussed in the
xref:core/aop/ataspectj/advice.adoc#aop-ataspectj-advice-proceeding-with-the-call[following section on advice parameters].
<<aop-ataspectj-advice-proceeding-with-the-call,following section on advice parameters>>.
====
The value returned by the around advice is the return value seen by the caller of the
@@ -722,7 +722,7 @@ of determining parameter names, an exception will be thrown.
`AspectJAnnotationParameterNameDiscoverer` :: Uses parameter names that have been explicitly
specified by the user via the `argNames` attribute in the corresponding advice or
pointcut annotation. See xref:core/aop/ataspectj/advice.adoc#aop-ataspectj-advice-params-names-explicit[Explicit Argument Names] for details.
pointcut annotation. See <<aop-ataspectj-advice-params-names-explicit,Explicit Argument Names>> for details.
`KotlinReflectionParameterNameDiscoverer` :: Uses Kotlin reflection APIs to determine
parameter names. This discoverer is only used if such APIs are present on the classpath.
`StandardReflectionParameterNameDiscoverer` :: Uses the standard `java.lang.reflect.Parameter`
@@ -204,7 +204,7 @@ Before advice runs before a matched method execution. It is declared inside an
----
In the example above, `dataAccessOperation` is the `id` of a _named pointcut_ defined at
the top (`<aop:config>`) level (see xref:core/aop/schema.adoc#aop-schema-pointcuts[Declaring a Pointcut]).
the top (`<aop:config>`) level (see <<aop-schema-pointcuts,Declaring a Pointcut>>).
NOTE: As we noted in the discussion of the @AspectJ style, using _named pointcuts_ can
significantly improve the readability of your code. See xref:core/aop/ataspectj/pointcuts.adoc#aop-common-pointcuts[Sharing Named Pointcut Definitions] for
@@ -9,12 +9,12 @@ alone.
Spring ships with a small AspectJ aspect library, which is available stand-alone in your
distribution as `spring-aspects.jar`. You need to add this to your classpath in order
to use the aspects in it.
xref:core/aop/using-aspectj.adoc#aop-atconfigurable[Using AspectJ to Dependency Inject Domain Objects with Spring]
and xref:core/aop/using-aspectj.adoc#aop-ajlib-other[Other Spring aspects for AspectJ]
<<aop-atconfigurable,Using AspectJ to Dependency Inject Domain Objects with Spring>>
and <<aop-ajlib-other,Other Spring aspects for AspectJ>>
discuss the content of this library and how you can use it.
xref:core/aop/using-aspectj.adoc#aop-aj-configure[Configuring AspectJ Aspects by Using Spring IoC]
<<aop-aj-configure,Configuring AspectJ Aspects by Using Spring IoC>>
discusses how to dependency inject AspectJ aspects that are woven using the AspectJ compiler. Finally,
xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]
<<aop-aj-ltw,Load-time Weaving with AspectJ in the Spring Framework>>
provides an introduction to load-time weaving for Spring applications that use AspectJ.
@@ -177,7 +177,7 @@ types in AspectJ
For this to work, the annotated types must be woven with the AspectJ weaver. You can
either use a build-time Ant or Maven task to do this (see, for example, the
{aspectj-docs-devguide}/antTasks.html[AspectJ Development
Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The
Environment Guide]) or load-time weaving (see <<aop-aj-ltw,Load-time Weaving with AspectJ in the Spring Framework>>). The
`AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain
a reference to the bean factory that is to be used to configure new objects). You can define
the related configuration as follows:
@@ -376,7 +376,7 @@ per-`ClassLoader` basis, which is more fine-grained and which can make more
sense in a 'single-JVM-multiple-application' environment (such as is found in a typical
application server environment).
Further, xref:core/aop/using-aspectj.adoc#aop-aj-ltw-environments[in certain environments], this support enables
Further, <<aop-aj-ltw-environments,in certain environments>>, this support enables
load-time weaving without making any modifications to the application server's launch
script that is needed to add `-javaagent:path/to/aspectjweaver.jar` or (as we describe
later in this section) `-javaagent:path/to/spring-instrument.jar`. Developers configure
@@ -400,7 +400,7 @@ tool to that specific area immediately afterwards.
NOTE: The example presented here uses XML configuration. You can also configure and
use @AspectJ with xref:core/beans/java.adoc[Java configuration]. Specifically, you can use the
`@EnableLoadTimeWeaving` annotation as an alternative to `<context:load-time-weaver/>`
(see xref:core/aop/using-aspectj.adoc#aop-aj-ltw-spring[below] for details).
(see <<aop-aj-ltw-spring,below>> for details).
The following example shows the profiling aspect, which is not fancy.
It is a time-based profiler that uses the @AspectJ-style of aspect declaration:
@@ -719,7 +719,7 @@ for AspectJ LTW:
* `spring-aop.jar`
* `aspectjweaver.jar`
If you use the xref:core/aop/using-aspectj.adoc#aop-aj-ltw-environments-generic[Spring-provided agent to enable instrumentation]
If you use the <<aop-aj-ltw-environments-generic,Spring-provided agent to enable instrumentation>>
, you also need:
* `spring-instrument.jar`
@@ -836,7 +836,7 @@ containers.
Tomcat and JBoss/WildFly provide a general app `ClassLoader` that is capable of local
instrumentation. Spring's native LTW may leverage those ClassLoader implementations
to provide AspectJ weaving.
You can simply enable load-time weaving, as xref:core/aop/using-aspectj.adoc[described earlier].
You can simply enable load-time weaving, as <<aop-using-aspectj,described earlier>>.
Specifically, you do not need to modify the JVM launch script to add
`-javaagent:path/to/spring-instrument.jar`.
@@ -24,7 +24,7 @@ Applying such optimizations early implies the following restrictions:
* As we cannot rely on the instance, make sure that the bean type is as precise as
possible.
TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.
TIP: See also the <<aot.bestpractices>> section.
When these restrictions are in place, it becomes possible to perform ahead-of-time processing at build time and generate additional assets.
A Spring AOT processed application typically generates:
@@ -14,11 +14,11 @@ Spring distribution, you should first read the previous section on xref:core/app
To create new XML configuration extensions:
. xref:core/appendix/xml-custom.adoc#xsd-custom-schema[Author] an XML schema to describe your custom element(s).
. xref:core/appendix/xml-custom.adoc#xsd-custom-namespacehandler[Code] a custom `NamespaceHandler` implementation.
. xref:core/appendix/xml-custom.adoc#xsd-custom-parser[Code] one or more `BeanDefinitionParser` implementations
. <<xsd-custom-schema,Author>> an XML schema to describe your custom element(s).
. <<xsd-custom-namespacehandler,Code>> a custom `NamespaceHandler` implementation.
. <<xsd-custom-parser,Code>> one or more `BeanDefinitionParser` implementations
(this is where the real work is done).
. xref:core/appendix/xml-custom.adoc#xsd-custom-registration[Register] your new artifacts with Spring.
. <<xsd-custom-registration,Register>> your new artifacts with Spring.
For a unified example, we create an
XML extension (a custom XML element) that lets us configure objects of the type
@@ -553,7 +553,7 @@ Kotlin::
This works nicely, but it exposes a lot of Spring plumbing to the end user. What we are
going to do is write a custom extension that hides away all of this Spring plumbing.
If we stick to xref:core/appendix/xml-custom.adoc#xsd-custom-introduction[the steps described previously], we start off
If we stick to <<xsd-custom-introduction,the steps described previously>>, we start off
by creating the XSD schema to define the structure of our custom tag, as the following
listing shows:
@@ -580,7 +580,7 @@ listing shows:
</xsd:schema>
----
Again following xref:core/appendix/xml-custom.adoc#xsd-custom-introduction[the process described earlier],
Again following <<xsd-custom-introduction,the process described earlier>>,
we then create a custom `NamespaceHandler`:
[tabs]
@@ -43,7 +43,7 @@ An `@Autowired` annotation on such a constructor is not necessary if the target
defines only one constructor. However, if several constructors are available and there is
no primary or default constructor, at least one of the constructors must be annotated
with `@Autowired` in order to instruct the container which one to use. See the discussion
on xref:core/beans/annotation-config/autowired.adoc#beans-autowired-annotation-constructor-resolution[constructor resolution]
on <<beans-autowired-annotation-constructor-resolution,constructor resolution>>
for details.
====
@@ -193,7 +193,7 @@ XML configuration file represents a logical layer or module in your architecture
You can use the `ClassPathXmlApplicationContext` constructor to load bean definitions from
XML fragments. This constructor takes multiple `Resource` locations, as was shown in the
xref:core/beans/basics.adoc#beans-factory-xml[previous section]. Alternatively,
<<beans-factory-xml,previous section>>. Alternatively,
use one or more occurrences of the `<import/>` element to load bean definitions from
another file or files. The following example shows how to do so:
@@ -52,7 +52,7 @@ supported as a marker for automatic exception translation in your persistence la
Many of the annotations provided by Spring can be used as meta-annotations in your
own code. A meta-annotation is an annotation that can be applied to another annotation.
For example, the `@Service` annotation mentioned xref:core/beans/classpath-scanning.adoc#beans-stereotype-annotations[earlier]
For example, the `@Service` annotation mentioned <<beans-stereotype-annotations,earlier>>
is meta-annotated with `@Component`, as the following example shows:
[tabs]
@@ -483,7 +483,7 @@ When a component is autodetected as part of the scanning process, its bean name
generated by the `BeanNameGenerator` strategy known to that scanner.
By default, the `AnnotationBeanNameGenerator` is used. For Spring
xref:core/beans/classpath-scanning.adoc#beans-stereotype-annotations[stereotype annotations],
<<beans-stereotype-annotations,stereotype annotations>>,
if you supply a name via the annotation's `value` attribute that name will be used as
the name in the corresponding bean definition. This convention also applies when the
`@jakarta.inject.Named` annotation is used instead of Spring stereotype annotations.
@@ -282,7 +282,7 @@ class and the `ApplicationListener` interface. If a bean that implements the
Essentially, this is the standard Observer design pattern.
TIP: As of Spring 4.2, the event infrastructure has been significantly improved and offers
an xref:core/beans/context-introduction.adoc#context-functionality-events-annotation[annotation-based model] as well as the
an <<context-functionality-events-annotation,annotation-based model>> as well as the
ability to publish any arbitrary event (that is, an object that does not necessarily
extend from `ApplicationEvent`). When such an object is published, we wrap it in an
event for you.
@@ -698,7 +698,7 @@ Kotlin::
======
NOTE: This feature is not supported for
xref:core/beans/context-introduction.adoc#context-functionality-events-async[asynchronous listeners].
<<context-functionality-events-async,asynchronous listeners>>.
The `handleBlockedListEvent()` method publishes a new `ListUpdateEvent` for every
`BlockedListEvent` that it handles. If you need to publish several events, you can return
@@ -27,10 +27,10 @@ The following table describes these properties:
| Property| Explained in...
| Class
| xref:core/beans/definition.adoc#beans-factory-class[Instantiating Beans]
| <<beans-factory-class,Instantiating Beans>>
| Name
| xref:core/beans/definition.adoc#beans-beanname[Naming Beans]
| <<beans-beanname,Naming Beans>>
| Scope
| xref:core/beans/factory-scopes.adoc[Bean Scopes]
@@ -205,7 +205,7 @@ If you use XML-based configuration metadata, you specify the type (or class) of
that is to be instantiated in the `class` attribute of the `<bean/>` element. This
`class` attribute (which, internally, is a `Class` property on a `BeanDefinition`
instance) is usually mandatory. (For exceptions, see
xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[Instantiation by Using an Instance Factory Method]
<<beans-factory-class-instance-factory-method,Instantiation by Using an Instance Factory Method>>
and xref:core/beans/child-bean-definitions.adoc[Bean Definition Inheritance].)
You can use the `Class` property in one of two ways:
@@ -344,7 +344,7 @@ overloads of the `mock` method. Choose the most specific variant of `mock` possi
[[beans-factory-class-instance-factory-method]]
=== Instantiation by Using an Instance Factory Method
Similar to instantiation through a xref:core/beans/definition.adoc#beans-factory-class-static-factory-method[static factory method]
Similar to instantiation through a <<beans-factory-class-static-factory-method,static factory method>>
, instantiation with an instance factory method invokes a non-static
method of an existing bean from the container to create a new bean. To use this
mechanism, leave the `class` attribute empty and, in the `factory-bean` attribute,
@@ -467,8 +467,8 @@ See xref:core/beans/dependencies/factory-properties-detailed.adoc[Dependencies a
NOTE: In Spring documentation, "factory bean" refers to a bean that is configured in the
Spring container and that creates objects through an
xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[instance] or
xref:core/beans/definition.adoc#beans-factory-class-static-factory-method[static] factory method. By contrast,
<<beans-factory-class-instance-factory-method,instance>> or
<<beans-factory-class-static-factory-method,static>> factory method. By contrast,
`FactoryBean` (notice the capitalization) refers to a Spring-specific
xref:core/beans/factory-extension.adoc#beans-factory-extension-factorybean[`FactoryBean`] implementation class.
@@ -91,7 +91,7 @@ In the latter scenario, you have several options:
* Abandon autowiring in favor of explicit wiring.
* Avoid autowiring for a bean definition by setting its `autowire-candidate` attributes
to `false`, as described in the
xref:core/beans/dependencies/factory-autowire.adoc#beans-factory-autowire-candidate[next section].
<<beans-factory-autowire-candidate,next section>>.
* Designate a single bean definition as the primary candidate by setting the
`primary` attribute of its `<bean/>` element to `true`.
* Implement the more fine-grained control available with annotation-based configuration,
@@ -17,8 +17,8 @@ to test, particularly when the dependencies are on interfaces or abstract base c
which allow for stub or mock implementations to be used in unit tests.
DI exists in two major variants:
xref:core/beans/dependencies/factory-collaborators.adoc#beans-constructor-injection[Constructor-based dependency injection]
and xref:core/beans/dependencies/factory-collaborators.adoc#beans-setter-injection[Setter-based dependency injection].
<<beans-constructor-injection,Constructor-based dependency injection>>
and <<beans-setter-injection,Setter-based dependency injection>>.
[[beans-constructor-injection]]
@@ -110,7 +110,7 @@ You can read more about the motivation for Method Injection in
Lookup method injection is the ability of the container to override methods on
container-managed beans and return the lookup result for another named bean in the
container. The lookup typically involves a prototype bean, as in the scenario described
in xref:core/beans/dependencies/factory-method-injection.adoc[the preceding section]. The Spring Framework
in <<beans-factory-method-injection,the preceding section>>. The Spring Framework
implements this method injection by using bytecode generation from the CGLIB library to
dynamically generate a subclass that overrides the method.
@@ -27,7 +27,7 @@ The following example shows various values being set:
</bean>
----
The following example uses the xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[p-namespace] for even more succinct
The following example uses the <<beans-p-namespace,p-namespace>> for even more succinct
XML configuration:
[source,xml,indent=0,subs="verbatim,quotes"]
@@ -539,7 +539,7 @@ three approaches at the same time.
== XML Shortcut with the c-namespace
Similar to the
xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[XML Shortcut with the p-namespace],
<<beans-p-namespace,XML Shortcut with the p-namespace>>,
the c-namespace, introduced in Spring 3.1, allows inlined attributes for configuring
the constructor arguments rather then nested `constructor-arg` elements.
@@ -3,8 +3,8 @@
The {spring-framework-api}/core/env/Environment.html[`Environment`] interface
is an abstraction integrated in the container that models two key
aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]
and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].
aspects of the application environment: <<beans-definition-profiles,profiles>>
and <<beans-property-source-abstraction,properties>>.
A profile is a named, logical group of bean definitions to be registered with the
container only if the given profile is active. Beans may be assigned to a profile
@@ -473,7 +473,7 @@ Kotlin::
In addition, you can also declaratively activate profiles through the
`spring.profiles.active` property, which may be specified through system environment
variables, JVM system properties, servlet context parameters in `web.xml`, or even as an
entry in JNDI (see xref:core/beans/environment.adoc#beans-property-source-abstraction[`PropertySource` Abstraction]). In integration tests, active
entry in JNDI (see <<beans-property-source-abstraction,`PropertySource` Abstraction>>). In integration tests, active
profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test`
module (see xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[context configuration with environment profiles]
).
@@ -553,7 +553,7 @@ Kotlin::
----
======
If xref:#beans-definition-profiles-enable[no profile is active], the `dataSource` is
If <<beans-definition-profiles-enable,no profile is active>>, the `dataSource` is
created. You can see this as a way to provide a default definition for one or more
beans. If any profile is enabled, the default profile does not apply.
@@ -23,7 +23,7 @@ interface. If you write your own `BeanPostProcessor`, you should consider implem
the `Ordered` interface, too. For further details, see the javadoc of the
{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]
and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on
xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].
<<beans-factory-programmatically-registering-beanpostprocessors,programmatic registration of `BeanPostProcessor` instances>>.
[NOTE]
====
@@ -39,7 +39,7 @@ another container, even if both containers are part of the same hierarchy.
To change the actual bean definition (that is, the blueprint that defines the bean),
you instead need to use a `BeanFactoryPostProcessor`, as described in
xref:core/beans/factory-extension.adoc#beans-factory-extension-factory-postprocessors[Customizing Configuration Metadata with a `BeanFactoryPostProcessor`].
<<beans-factory-extension-factory-postprocessors,Customizing Configuration Metadata with a `BeanFactoryPostProcessor`>>.
====
The `org.springframework.beans.factory.config.BeanPostProcessor` interface consists of
@@ -329,7 +329,7 @@ and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more deta
If you want to change the actual bean instances (that is, the objects that are created
from the configuration metadata), then you instead need to use a `BeanPostProcessor`
(described earlier in
xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp[Customizing Beans by Using a `BeanPostProcessor`]).
<<beans-factory-extension-bpp,Customizing Beans by Using a `BeanPostProcessor`>>).
While it is technically possible to work with bean instances within a `BeanFactoryPostProcessor`
(for example, by using `BeanFactory.getBean()`), doing so causes premature bean instantiation,
violating the standard container lifecycle. This may cause negative side effects, such as
@@ -4,9 +4,9 @@
The Spring Framework provides a number of interfaces you can use to customize the nature
of a bean. This section groups them as follows:
* xref:core/beans/factory-nature.adoc#beans-factory-lifecycle[Lifecycle Callbacks]
* xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
* xref:core/beans/factory-nature.adoc#aware-list[Other `Aware` Interfaces]
* <<beans-factory-lifecycle,Lifecycle Callbacks>>
* <<beans-factory-aware,`ApplicationContextAware` and `BeanNameAware`>>
* <<aware-list,Other `Aware` Interfaces>>
[[beans-factory-lifecycle]]
@@ -252,7 +252,7 @@ of a `<bean>` element a special `(inferred)` value, which instructs Spring to au
detect a public `close` or `shutdown` method on the bean class for a specific bean definition.
You can also set this special `(inferred)` value on the `default-destroy-method` attribute
of a `<beans>` element to apply this behavior to an entire set of bean definitions (see
xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-default-init-destroy-methods[Default Initialization and Destroy Methods]).
<<beans-factory-lifecycle-default-init-destroy-methods,Default Initialization and Destroy Methods>>).
[NOTE]
====
@@ -276,7 +276,7 @@ callback method names on every bean. This means that you, as an application deve
can write your application classes and use an initialization callback called `init()`,
without having to configure an `init-method="init"` attribute with each bean definition.
The Spring IoC container calls that method when the bean is created (and in accordance
with the standard lifecycle callback contract xref:core/beans/factory-nature.adoc#beans-factory-lifecycle[described previously]).
with the standard lifecycle callback contract <<beans-factory-lifecycle,described previously>>).
This feature also enforces a consistent naming convention for initialization and
destroy method callbacks.
@@ -367,8 +367,8 @@ interacts directly with the raw target bean.
As of Spring 2.5, you have three options for controlling bean lifecycle behavior:
* The xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-initializingbean[`InitializingBean`] and
xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-disposablebean[`DisposableBean`] callback interfaces
* The <<beans-factory-lifecycle-initializingbean,`InitializingBean`>> and
<<beans-factory-lifecycle-disposablebean,`DisposableBean`>> callback interfaces
* Custom `init()` and `destroy()` methods
* The xref:core/beans/annotation-config/postconstruct-and-predestroy-annotations.adoc[`@PostConstruct` and `@PreDestroy` annotations]
. You can combine these mechanisms to control a given bean.
@@ -378,7 +378,7 @@ configured with a different method name, then each configured method is run in t
order listed after this note. However, if the same method name is configured -- for example,
`init()` for an initialization method -- for more than one of these lifecycle mechanisms,
that method is run once, as explained in the
xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-default-init-destroy-methods[preceding section].
<<beans-factory-lifecycle-default-init-destroy-methods,preceding section>>.
Multiple lifecycle mechanisms configured for the same bean, with different
initialization methods, are called as follows:
@@ -669,7 +669,7 @@ init-method.
[[aware-list]]
== Other `Aware` Interfaces
Besides `ApplicationContextAware` and `BeanNameAware` (discussed xref:core/beans/factory-nature.adoc#beans-factory-aware[earlier]),
Besides `ApplicationContextAware` and `BeanNameAware` (discussed <<beans-factory-aware,earlier>>),
Spring offers a wide range of `Aware` callback interfaces that let beans indicate to the container
that they require a certain infrastructure dependency. As a general rule, the name indicates the
dependency type. The following table summarizes the most important `Aware` interfaces:
@@ -681,7 +681,7 @@ dependency type. The following table summarizes the most important `Aware` inter
| `ApplicationContextAware`
| Declaring `ApplicationContext`.
| xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
| <<beans-factory-aware,`ApplicationContextAware` and `BeanNameAware`>>
| `ApplicationEventPublisherAware`
| Event publisher of the enclosing `ApplicationContext`.
@@ -697,7 +697,7 @@ dependency type. The following table summarizes the most important `Aware` inter
| `BeanNameAware`
| Name of the declaring bean.
| xref:core/beans/factory-nature.adoc#beans-factory-aware[`ApplicationContextAware` and `BeanNameAware`]
| <<beans-factory-aware,`ApplicationContextAware` and `BeanNameAware`>>
| `LoadTimeWeaverAware`
| Defined weaver for processing class definition at load time.
@@ -14,7 +14,7 @@ through configuration instead of having to bake in the scope of an object at the
class level. Beans can be defined to be deployed in one of a number of scopes.
The Spring Framework supports six scopes, four of which are available only if
you use a web-aware `ApplicationContext`. You can also create
xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom[a custom scope.]
<<beans-factory-scopes-custom,a custom scope.>>
The following table describes the supported scopes:
@@ -24,23 +24,23 @@ The following table describes the supported scopes:
|===
| Scope| Description
| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton]
| <<beans-factory-scopes-singleton,singleton>>
| (Default) Scopes a single bean definition to a single object instance for each Spring IoC
container.
| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-prototype[prototype]
| <<beans-factory-scopes-prototype,prototype>>
| Scopes a single bean definition to any number of object instances.
| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-request[request]
| <<beans-factory-scopes-request,request>>
| Scopes a single bean definition to the lifecycle of a single HTTP request. That is,
each HTTP request has its own instance of a bean created off the back of a single bean
definition. Only valid in the context of a web-aware Spring `ApplicationContext`.
| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-session[session]
| <<beans-factory-scopes-session,session>>
| Scopes a single bean definition to the lifecycle of an HTTP `Session`. Only valid in
the context of a web-aware Spring `ApplicationContext`.
| xref:core/beans/factory-scopes.adoc#beans-factory-scopes-application[application]
| <<beans-factory-scopes-application,application>>
| Scopes a single bean definition to the lifecycle of a `ServletContext`. Only valid in
the context of a web-aware Spring `ApplicationContext`.
@@ -53,7 +53,7 @@ NOTE: A thread scope is available but is not registered by default. For more inf
see the documentation for
{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].
For instructions on how to register this or any other custom scope, see
xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].
<<beans-factory-scopes-custom-using,Using a Custom Scope>>.
[[beans-factory-scopes-singleton]]
@@ -432,7 +432,7 @@ understand the "`why`" as well as the "`how`" behind it:
To create such a proxy, you insert a child `<aop:scoped-proxy/>` element into a
scoped bean definition (see
xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection-proxies[Choosing the Type of Proxy to Create]
<<beans-factory-scopes-other-injection-proxies,Choosing the Type of Proxy to Create>>
and xref:core/appendix/xsd-schemas.adoc[XML Schema-based configuration]).
Why do definitions of beans scoped at the `request`, `session` and custom-scope
@@ -19,7 +19,7 @@ You can use the `@Bean` annotation in a `@Configuration`-annotated or in a
To declare a bean, you can annotate a method with the `@Bean` annotation. You use this
method to register a bean definition within an `ApplicationContext` of the type specified
by the method's return type. By default, the bean name is the same as the method name
(unless a different xref:#beans-java-customizing-bean-naming[bean name generator] is
(unless a different <<beans-java-customizing-bean-naming,bean name generator>> is
configured). The following example shows a `@Bean` method declaration:
[tabs]
@@ -8,10 +8,10 @@ Jetty uses pooled byte buffers with a callback to be released, and so on.
The `spring-core` module provides a set of abstractions to work with various byte buffer
APIs as follows:
* xref:core/databuffer-codec.adoc#databuffers-factory[`DataBufferFactory`] abstracts the creation of a data buffer.
* xref:core/databuffer-codec.adoc#databuffers-buffer[`DataBuffer`] represents a byte buffer, which may be
xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[pooled].
* xref:core/databuffer-codec.adoc#databuffers-utils[`DataBufferUtils`] offers utility methods for data buffers.
* <<databuffers-factory,`DataBufferFactory`>> abstracts the creation of a data buffer.
* <<databuffers-buffer,`DataBuffer`>> represents a byte buffer, which may be
<<databuffers-buffer-pooled,pooled>>.
* <<databuffers-utils,`DataBufferUtils`>> offers utility methods for data buffers.
* <<Codecs>> decode or encode data buffer streams into higher level objects.
@@ -41,7 +41,7 @@ Below is a partial list of benefits:
* Read and write with independent positions, i.e. not requiring a call to `flip()` to
alternate between read and write.
* Capacity expanded on demand as with `java.lang.StringBuilder`.
* Pooled buffers and reference counting via xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[`PooledDataBuffer`].
* Pooled buffers and reference counting via <<databuffers-buffer-pooled,`PooledDataBuffer`>>.
* View a buffer as `java.nio.ByteBuffer`, `InputStream`, or `OutputStream`.
* Determine the index, or the last index, for a given byte.
@@ -101,7 +101,7 @@ xref:web/webflux/reactive-spring.adoc#webflux-codecs[Codecs] in the WebFlux sect
== Using `DataBuffer`
When working with data buffers, special care must be taken to ensure buffers are released
since they may be xref:core/databuffer-codec.adoc#databuffers-buffer-pooled[pooled]. We'll use codecs to illustrate
since they may be <<databuffers-buffer-pooled,pooled>>. We'll use codecs to illustrate
how that works but the concepts apply more generally. Let's see what codecs must do
internally to manage data buffers.
@@ -612,9 +612,9 @@ only 3ms using the compiled version of the expression.
The compiler is not turned on by default, but you can turn it on in either of two
different ways. You can turn it on by using the parser configuration process
(xref:core/expressions/evaluation.adoc#expressions-parser-configuration[discussed
earlier]) or by using a Spring property when SpEL usage is embedded inside another
component. This section discusses both of these options.
(<<expressions-parser-configuration,discussed earlier>>) or by using a Spring property
when SpEL usage is embedded inside another component. This section discusses both of
these options.
The compiler can operate in one of three modes, which are captured in the
`org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows.
@@ -3,12 +3,12 @@
The Spring Expression Language supports the following kinds of operators:
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-relational[Relational Operators]
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-logical[Logical Operators]
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-string[String Operators]
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-mathematical[Mathematical Operators]
* xref:core/expressions/language-ref/operators.adoc#expressions-assignment[The Assignment Operator]
* xref:core/expressions/language-ref/operators.adoc#expressions-operators-overloaded[Overloaded Operators]
* <<expressions-operators-relational,Relational Operators>>
* <<expressions-operators-logical,Logical Operators>>
* <<expressions-operators-string,String Operators>>
* <<expressions-operators-mathematical,Mathematical Operators>>
* <<expressions-assignment,The Assignment Operator>>
* <<expressions-operators-overloaded,Overloaded Operators>>
@@ -4,14 +4,14 @@
This chapter covers how Spring handles resources and how you can work with resources in
Spring. It includes the following topics:
* xref:core/resources.adoc#resources-introduction[Introduction]
* xref:core/resources.adoc#resources-resource[The `Resource` Interface]
* xref:core/resources.adoc#resources-implementations[Built-in `Resource` Implementations]
* xref:core/resources.adoc#resources-resourceloader[The `ResourceLoader` Interface]
* xref:core/resources.adoc#resources-resourcepatternresolver[The `ResourcePatternResolver` Interface]
* xref:core/resources.adoc#resources-resourceloaderaware[The `ResourceLoaderAware` Interface]
* xref:core/resources.adoc#resources-as-dependencies[Resources as Dependencies]
* xref:core/resources.adoc#resources-app-ctx[Application Contexts and Resource Paths]
* <<resources-introduction,Introduction>>
* <<resources-resource,The `Resource` Interface>>
* <<resources-implementations,Built-in `Resource` Implementations>>
* <<resources-resourceloader,The `ResourceLoader` Interface>>
* <<resources-resourcepatternresolver,The `ResourcePatternResolver` Interface>>
* <<resources-resourceloaderaware,The `ResourceLoaderAware` Interface>>
* <<resources-as-dependencies,Resources as Dependencies>>
* <<resources-app-ctx,Application Contexts and Resource Paths>>
[[resources-introduction]]
@@ -126,13 +126,13 @@ For example, a `UrlResource` wraps a URL and uses the wrapped `URL` to do its wo
Spring includes several built-in `Resource` implementations:
* xref:core/resources.adoc#resources-implementations-urlresource[`UrlResource`]
* xref:core/resources.adoc#resources-implementations-classpathresource[`ClassPathResource`]
* xref:core/resources.adoc#resources-implementations-filesystemresource[`FileSystemResource`]
* xref:core/resources.adoc#resources-implementations-pathresource[`PathResource`]
* xref:core/resources.adoc#resources-implementations-servletcontextresource[`ServletContextResource`]
* xref:core/resources.adoc#resources-implementations-inputstreamresource[`InputStreamResource`]
* xref:core/resources.adoc#resources-implementations-bytearrayresource[`ByteArrayResource`]
* <<resources-implementations-urlresource,`UrlResource`>>
* <<resources-implementations-classpathresource,`ClassPathResource`>>
* <<resources-implementations-filesystemresource,`FileSystemResource`>>
* <<resources-implementations-pathresource,`PathResource`>>
* <<resources-implementations-servletcontextresource,`ServletContextResource`>>
* <<resources-implementations-inputstreamresource,`InputStreamResource`>>
* <<resources-implementations-bytearrayresource,`ByteArrayResource`>>
For a complete list of `Resource` implementations available in Spring, consult the
"All Known Implementing Classes" section of the
@@ -350,7 +350,7 @@ objects:
| file:
| `\file:///data/config.xml`
| Loaded as a `URL` from the filesystem. See also xref:core/resources.adoc#resources-filesystemresource-caveats[`FileSystemResource` Caveats].
| Loaded as a `URL` from the filesystem. See also <<resources-filesystemresource-caveats,`FileSystemResource` Caveats>>.
| https:
| `\https://myserver/logo.png`
@@ -384,11 +384,11 @@ for all matching resources from the class path. Note that the resource location
expected to be a path without placeholders in this case -- for example,
`classpath*:/config/beans.xml`. JAR files or different directories in the class path can
contain multiple files with the same path and the same name. See
xref:core/resources.adoc#resources-app-ctx-wildcards-in-resource-paths[Wildcards in Application Context Constructor Resource Paths] and its subsections for further details
<<resources-app-ctx-wildcards-in-resource-paths,Wildcards in Application Context Constructor Resource Paths>> and its subsections for further details
on wildcard support with the `classpath*:` resource prefix.
A passed-in `ResourceLoader` (for example, one supplied via
xref:core/resources.adoc#resources-resourceloaderaware[`ResourceLoaderAware`] semantics) can be checked whether
<<resources-resourceloaderaware,`ResourceLoaderAware`>> semantics) can be checked whether
it implements this extended interface too.
`PathMatchingResourcePatternResolver` is a standalone implementation that is usable
@@ -452,7 +452,7 @@ For more information, see xref:core/beans/annotation-config/autowired.adoc[Using
NOTE: To load one or more `Resource` objects for a resource path that contains wildcards
or makes use of the special `classpath*:` resource prefix, consider having an instance of
xref:core/resources.adoc#resources-resourcepatternresolver[`ResourcePatternResolver`] autowired into your
<<resources-resourcepatternresolver,`ResourcePatternResolver`>> autowired into your
application components instead of `ResourceLoader`.
@@ -2,13 +2,13 @@
= Data Binding
Data binding is useful for binding user input to a target object where user input is a map
with property paths as keys, following xref:data-binding-conventions[JavaBeans conventions].
with property paths as keys, following <<data-binding-conventions,JavaBeans conventions>>.
`DataBinder` is the main class that supports this, and it provides two ways to bind user
input:
- xref:data-binding-constructor-binding[Constructor binding] - bind user input to a
- <<data-binding-constructor-binding,Constructor binding>> - bind user input to a
public data constructor, looking up constructor argument values in the user input.
- xref:data-binding-property-binding[Property binding] - bind user input to setters,
- <<data-binding-property-binding,Property binding>> - bind user input to setters,
matching keys from the user input to properties of the target object structure.
You can apply both constructor and property binding or only one.
@@ -32,7 +32,7 @@ WebFlux support a custom name mapping through the `@BindParam` annotation on con
parameters or fields if present. If necessary, you can also configure a `NameResolver` on
`DataBinder` to customize the argument name to use.
xref:data-binding-conventions[Type conversion] is applied as needed to convert user input.
<<data-binding-conventions,Type conversion>> is applied as needed to convert user input.
If the constructor parameter is an object, it is constructed recursively in the same
manner, but through a nested property path. That means constructor binding creates both
the target object and any objects it contains.
@@ -103,7 +103,7 @@ details. The below table shows some examples of these conventions:
(This next section is not vitally important to you if you do not plan to work with
the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory`
and their default implementations, you should skip ahead to the
xref:core/validation/data-binding.adoc#data-binding-conversion[section on `PropertyEditors`].)
<<data-binding-conversion,section on `PropertyEditors`>>.)
The following two example classes use the `BeanWrapper` to get and set
properties:
@@ -447,7 +447,7 @@ where it can be automatically detected and applied.
Note that all bean factories and application contexts automatically use a number of
built-in property editors, through their use of a `BeanWrapper` to
handle property conversions. The standard property editors that the `BeanWrapper`
registers are listed in the xref:core/validation/data-binding.adoc#data-binding-conversion[previous section].
registers are listed in the <<data-binding-conversion,previous section>>.
Additionally, ``ApplicationContext``s also override or add additional editors to handle
resource lookups in a manner appropriate to the specific application context type.
@@ -576,7 +576,7 @@ You can write a corresponding registrar and reuse it in each case.
`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper`
(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient
when used in conjunction with `CustomEditorConfigurer` (described
xref:core/validation/data-binding.adoc#data-binding-conversion-customeditor-registration[here]), which exposes a property
<<data-binding-conversion-customeditor-registration,here>>), which exposes a property
called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added
to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and
Spring MVC controllers. Furthermore, it avoids the need for synchronization on custom
@@ -7,8 +7,8 @@
This part of the appendix lists XML schemas for data access, including the following:
* xref:data-access/appendix.adoc#xsd-schemas-tx[The `tx` Schema]
* xref:data-access/appendix.adoc#xsd-schemas-jdbc[The `jdbc` Schema]
* <<xsd-schemas-tx,The `tx` Schema>>
* <<xsd-schemas-jdbc,The `jdbc` Schema>>
[[xsd-schemas-tx]]
=== The `tx` Schema
@@ -3,14 +3,14 @@
This section covers:
* xref:data-access/jdbc/connections.adoc#jdbc-datasource[Using `DataSource`]
* xref:data-access/jdbc/connections.adoc#jdbc-DataSourceUtils[Using `DataSourceUtils`]
* xref:data-access/jdbc/connections.adoc#jdbc-SmartDataSource[Implementing `SmartDataSource`]
* xref:data-access/jdbc/connections.adoc#jdbc-AbstractDataSource[Extending `AbstractDataSource`]
* xref:data-access/jdbc/connections.adoc#jdbc-SingleConnectionDataSource[Using `SingleConnectionDataSource`]
* xref:data-access/jdbc/connections.adoc#jdbc-DriverManagerDataSource[Using `DriverManagerDataSource`]
* xref:data-access/jdbc/connections.adoc#jdbc-TransactionAwareDataSourceProxy[Using `TransactionAwareDataSourceProxy`]
* xref:data-access/jdbc/connections.adoc#jdbc-DataSourceTransactionManager[Using `DataSourceTransactionManager` / `JdbcTransactionManager`]
* <<jdbc-datasource,Using `DataSource`>>
* <<jdbc-DataSourceUtils,Using `DataSourceUtils`>>
* <<jdbc-SmartDataSource,Implementing `SmartDataSource`>>
* <<jdbc-AbstractDataSource,Extending `AbstractDataSource`>>
* <<jdbc-SingleConnectionDataSource,Using `SingleConnectionDataSource`>>
* <<jdbc-DriverManagerDataSource,Using `DriverManagerDataSource`>>
* <<jdbc-TransactionAwareDataSourceProxy,Using `TransactionAwareDataSourceProxy`>>
* <<jdbc-DataSourceTransactionManager,Using `DataSourceTransactionManager` / `JdbcTransactionManager`>>
[[jdbc-datasource]]
@@ -4,14 +4,14 @@
This section covers how to use the JDBC core classes to control basic JDBC processing,
including error handling. It includes the following topics:
* xref:data-access/jdbc/core.adoc#jdbc-JdbcTemplate[Using `JdbcTemplate`]
* xref:data-access/jdbc/core.adoc#jdbc-NamedParameterJdbcTemplate[Using `NamedParameterJdbcTemplate`]
* xref:data-access/jdbc/core.adoc#jdbc-JdbcClient[Unified JDBC Query/Update Operations: `JdbcClient`]
* xref:data-access/jdbc/core.adoc#jdbc-SQLExceptionTranslator[Using `SQLExceptionTranslator`]
* xref:data-access/jdbc/core.adoc#jdbc-statements-executing[Running Statements]
* xref:data-access/jdbc/core.adoc#jdbc-statements-querying[Running Queries]
* xref:data-access/jdbc/core.adoc#jdbc-updates[Updating the Database]
* xref:data-access/jdbc/core.adoc#jdbc-auto-generated-keys[Retrieving Auto-generated Keys]
* <<jdbc-JdbcTemplate,Using `JdbcTemplate`>>
* <<jdbc-NamedParameterJdbcTemplate,Using `NamedParameterJdbcTemplate`>>
* <<jdbc-JdbcClient,Unified JDBC Query/Update Operations: `JdbcClient`>>
* <<jdbc-SQLExceptionTranslator,Using `SQLExceptionTranslator`>>
* <<jdbc-statements-executing,Running Statements>>
* <<jdbc-statements-querying,Running Queries>>
* <<jdbc-updates,Updating the Database>>
* <<jdbc-auto-generated-keys,Retrieving Auto-generated Keys>>
[[jdbc-JdbcTemplate]]
@@ -349,7 +349,7 @@ The `JdbcTemplate` is stateful, in that it maintains a reference to a `DataSourc
this state is not conversational state.
A common practice when using the `JdbcTemplate` class (and the associated
xref:data-access/jdbc/core.adoc#jdbc-NamedParameterJdbcTemplate[`NamedParameterJdbcTemplate`] class) is to
<<jdbc-NamedParameterJdbcTemplate,`NamedParameterJdbcTemplate`>> class) is to
configure a `DataSource` in your Spring configuration file and then dependency-inject
that shared `DataSource` bean into your DAO classes. The `JdbcTemplate` is created in
the setter for the `DataSource` or in the constructor. This leads to DAOs that resemble the following:
@@ -574,7 +574,7 @@ functionality that is present only in the `JdbcTemplate` class, you can use the
`getJdbcOperations()` method to access the wrapped `JdbcTemplate` through the
`JdbcOperations` interface.
See also xref:data-access/jdbc/core.adoc#jdbc-jdbctemplate-idioms[`JdbcTemplate` Best Practices]
See also <<jdbc-jdbctemplate-idioms,`JdbcTemplate` Best Practices>>
for guidelines on using the `NamedParameterJdbcTemplate` class in the context of an application.
@@ -39,9 +39,9 @@ for further details on all supported options.
This section covers how to select one of the three embedded databases that Spring
supports. It includes the following topics:
* xref:data-access/jdbc/embedded-database-support.adoc#jdbc-embedded-database-using-HSQL[Using HSQL]
* xref:data-access/jdbc/embedded-database-support.adoc#jdbc-embedded-database-using-H2[Using H2]
* xref:data-access/jdbc/embedded-database-support.adoc#jdbc-embedded-database-using-Derby[Using Derby]
* <<jdbc-embedded-database-using-HSQL,Using HSQL>>
* <<jdbc-embedded-database-using-H2,Using H2>>
* <<jdbc-embedded-database-using-Derby,Using Derby>>
[[jdbc-embedded-database-using-HSQL]]
=== Using HSQL
@@ -143,7 +143,7 @@ can be useful for one-offs when the embedded database does not need to be reused
classes. However, if you wish to create an embedded database that is shared within a test suite,
consider using the xref:testing/testcontext-framework.adoc[Spring TestContext Framework] and
configuring the embedded database as a bean in the Spring `ApplicationContext` as described
in xref:data-access/jdbc/embedded-database-support.adoc#jdbc-embedded-database[Creating an Embedded Database].
in <<jdbc-embedded-database,Creating an Embedded Database>>.
The following listing shows the test template:
[tabs]
@@ -10,7 +10,7 @@ procedures and run update, delete, and insert statements.
[NOTE]
====
Many Spring developers believe that the various RDBMS operation classes described below
(with the exception of the xref:data-access/jdbc/object.adoc#jdbc-StoredProcedure[`StoredProcedure`] class) can often
(with the exception of the <<jdbc-StoredProcedure,`StoredProcedure`>> class) can often
be replaced with straight `JdbcTemplate` calls. Often, it is simpler to write a DAO
method that calls a method on a `JdbcTemplate` directly (as opposed to
encapsulating a query as a full-blown class).
@@ -266,7 +266,7 @@ The SQL type is specified using the `java.sql.Types` constants.
The first line (with the `SqlParameter`) declares an IN parameter. You can use IN parameters
both for stored procedure calls and for queries using the `SqlQuery` and its
subclasses (covered in xref:data-access/jdbc/object.adoc#jdbc-SqlQuery[Understanding `SqlQuery`]).
subclasses (covered in <<jdbc-SqlQuery,Understanding `SqlQuery`>>).
The second line (with the `SqlOutParameter`) declares an `out` parameter to be used in the
stored procedure call. There is also an `SqlInOutParameter` for `InOut` parameters
@@ -479,7 +479,7 @@ returned `out` parameters.
Earlier in this chapter, we described how parameters are deduced from metadata, but you can declare them
explicitly if you wish. You can do so by creating and configuring `SimpleJdbcCall` with
the `declareParameters` method, which takes a variable number of `SqlParameter` objects
as input. See the xref:data-access/jdbc/simple.adoc#jdbc-params[next section] for details on how to define an `SqlParameter`.
as input. See the <<jdbc-params,next section>> for details on how to define an `SqlParameter`.
NOTE: Explicit declarations are necessary if the database you use is not a Spring-supported
database. Currently, Spring supports metadata lookup of stored procedure calls for the
@@ -35,7 +35,7 @@ JDBC, the `JdbcTemplate` class mentioned in a xref:data-access/jdbc/core.adoc#jd
provides connection handling and proper conversion of `SQLException` to the
`DataAccessException` hierarchy, including translation of database-specific SQL error
codes to meaningful exception classes. For ORM technologies, see the
xref:data-access/orm/general.adoc#orm-exception-translation[next section] for how to get the same exception
<<orm-exception-translation,next section>> for how to get the same exception
translation benefits.
When it comes to transaction management, the `JdbcTemplate` class hooks in to the Spring
@@ -26,7 +26,7 @@ To avoid tying application objects to hard-coded resource lookups, you can defin
resources (such as a JDBC `DataSource` or a Hibernate `SessionFactory`) as beans in the
Spring container. Application objects that need to access resources receive references
to such predefined instances through bean references, as illustrated in the DAO
definition in the xref:data-access/orm/hibernate.adoc#orm-hibernate-straight[next section].
definition in the <<orm-hibernate-straight,next section>>.
The following excerpt from an XML application context definition shows how to set up a
JDBC `DataSource` and a Hibernate `SessionFactory` on top of it:
@@ -14,9 +14,9 @@ the underlying implementation in order to provide additional features.
The Spring JPA support offers three ways of setting up the JPA `EntityManagerFactory`
that is used by the application to obtain an entity manager.
* xref:data-access/orm/jpa.adoc#orm-jpa-setup-lemfb[Using `LocalEntityManagerFactoryBean`]
* xref:data-access/orm/jpa.adoc#orm-jpa-setup-jndi[Obtaining an EntityManagerFactory from JNDI]
* xref:data-access/orm/jpa.adoc#orm-jpa-setup-lcemfb[Using `LocalContainerEntityManagerFactoryBean`]
* <<orm-jpa-setup-lemfb,Using `LocalEntityManagerFactoryBean`>>
* <<orm-jpa-setup-jndi,Obtaining an EntityManagerFactory from JNDI>>
* <<orm-jpa-setup-lcemfb,Using `LocalContainerEntityManagerFactoryBean`>>
[[orm-jpa-setup-lemfb]]
=== Using `LocalEntityManagerFactoryBean`
@@ -519,7 +519,7 @@ Spring JPA also lets a configured `JpaTransactionManager` expose a JPA transacti
to JDBC access code that accesses the same `DataSource`, provided that the registered
`JpaDialect` supports retrieval of the underlying JDBC `Connection`. Spring provides
dialects for the EclipseLink and Hibernate JPA implementations. See the
xref:data-access/orm/jpa.adoc#orm-jpa-dialect[next section] for details on `JpaDialect`.
<<orm-jpa-dialect,next section>> for details on `JpaDialect`.
For JTA-style lazy retrieval of actual resource connections, Spring provides a
corresponding `DataSource` proxy class for the target connection pool: see
@@ -621,7 +621,7 @@ seamlessly integrating with `@Bean` style configuration (no `FactoryBean` involv
====
`LocalSessionFactoryBean` and `LocalSessionFactoryBuilder` support background
bootstrapping, just as the JPA `LocalContainerEntityManagerFactoryBean` does.
See xref:data-access/orm/jpa.adoc#orm-jpa-setup-background[Background Bootstrapping] for an introduction.
See <<orm-jpa-setup-background,Background Bootstrapping>> for an introduction.
On `LocalSessionFactoryBean`, this is available through the `bootstrapExecutor`
property. On the programmatic `LocalSessionFactoryBuilder`, an overloaded
@@ -17,9 +17,9 @@ stream, or a SAX handler.
Some of the benefits of using Spring for your O/X mapping needs are:
* xref:data-access/oxm.adoc#oxm-ease-of-configuration[Ease of configuration]
* xref:data-access/oxm.adoc#oxm-consistent-interfaces[Consistent Interfaces]
* xref:data-access/oxm.adoc#oxm-consistent-exception-hierarchy[Consistent Exception Hierarchy]
* <<oxm-ease-of-configuration,Ease of configuration>>
* <<oxm-consistent-interfaces,Consistent Interfaces>>
* <<oxm-consistent-exception-hierarchy,Consistent Exception Hierarchy>>
[[oxm-ease-of-configuration]]
=== Ease of configuration
@@ -52,7 +52,7 @@ These runtime exceptions wrap the original exception so that no information is l
[[oxm-marshaller-unmarshaller]]
== `Marshaller` and `Unmarshaller`
As stated in the xref:data-access/oxm.adoc#oxm-introduction[introduction], a marshaller serializes an object
As stated in the <<oxm-introduction,introduction>>, a marshaller serializes an object
to XML, and an unmarshaller deserializes XML stream to an object. This section describes
the two Spring interfaces used for this purpose.
@@ -334,8 +334,8 @@ preamble of the XML configuration file. The following example shows how to do so
The schema makes the following elements available:
* xref:data-access/oxm.adoc#oxm-jaxb2-xsd[`jaxb2-marshaller`]
* xref:data-access/oxm.adoc#oxm-jibx-xsd[`jibx-marshaller`]
* <<oxm-jaxb2-xsd,`jaxb2-marshaller`>>
* <<oxm-jibx-xsd,`jibx-marshaller`>>
Each tag is explained in its respective marshaller's section. As an example, though,
the configuration of a JAXB2 marshaller might resemble the following:
@@ -354,7 +354,7 @@ The JAXB binding compiler translates a W3C XML Schema into one or more Java clas
generate a schema from annotated Java classes.
Spring supports the JAXB 2.0 API as XML marshalling strategies, following the
`Marshaller` and `Unmarshaller` interfaces described in xref:data-access/oxm.adoc#oxm-marshaller-unmarshaller[`Marshaller` and `Unmarshaller`].
`Marshaller` and `Unmarshaller` interfaces described in <<oxm-marshaller-unmarshaller,`Marshaller` and `Unmarshaller`>>.
The corresponding integration classes reside in the `org.springframework.oxm.jaxb`
package.
@@ -12,12 +12,12 @@ The Spring Framework's R2DBC abstraction framework consists of two different pac
* `core`: The `org.springframework.r2dbc.core` package contains the `DatabaseClient`
class plus a variety of related classes. See
xref:data-access/r2dbc.adoc#r2dbc-core[Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling].
<<r2dbc-core,Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling>>.
* `connection`: The `org.springframework.r2dbc.connection` package contains a utility class
for easy `ConnectionFactory` access and various simple `ConnectionFactory` implementations
that you can use for testing and running unmodified R2DBC. See
xref:data-access/r2dbc.adoc#r2dbc-connections[Controlling Database Connections].
<<r2dbc-connections,Controlling Database Connections>>.
[[r2dbc-core]]
@@ -26,12 +26,12 @@ xref:data-access/r2dbc.adoc#r2dbc-connections[Controlling Database Connections].
This section covers how to use the R2DBC core classes to control basic R2DBC processing,
including error handling. It includes the following topics:
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient[Using `DatabaseClient`]
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient-examples-statement[Executing Statements]
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient-examples-query[Querying (`SELECT`)]
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient-examples-update[Updating (`INSERT`, `UPDATE`, and `DELETE`) with `DatabaseClient`]
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient-filter[Statement Filters]
* xref:data-access/r2dbc.adoc#r2dbc-auto-generated-keys[Retrieving Auto-generated Keys]
* <<r2dbc-DatabaseClient,Using `DatabaseClient`>>
* <<r2dbc-DatabaseClient-examples-statement,Executing Statements>>
* <<r2dbc-DatabaseClient-examples-query,Querying (`SELECT`)>>
* <<r2dbc-DatabaseClient-examples-update,Updating (`INSERT`, `UPDATE`, and `DELETE`) with `DatabaseClient`>>
* <<r2dbc-DatabaseClient-filter,Statement Filters>>
* <<r2dbc-auto-generated-keys,Retrieving Auto-generated Keys>>
[[r2dbc-DatabaseClient]]
=== Using `DatabaseClient`
@@ -680,11 +680,11 @@ Kotlin::
This section covers:
* xref:data-access/r2dbc.adoc#r2dbc-ConnectionFactory[Using `ConnectionFactory`]
* xref:data-access/r2dbc.adoc#r2dbc-ConnectionFactoryUtils[Using `ConnectionFactoryUtils`]
* xref:data-access/r2dbc.adoc#r2dbc-SingleConnectionFactory[Using `SingleConnectionFactory`]
* xref:data-access/r2dbc.adoc#r2dbc-TransactionAwareConnectionFactoryProxy[Using `TransactionAwareConnectionFactoryProxy`]
* xref:data-access/r2dbc.adoc#r2dbc-R2dbcTransactionManager[Using `R2dbcTransactionManager`]
* <<r2dbc-ConnectionFactory,Using `ConnectionFactory`>>
* <<r2dbc-ConnectionFactoryUtils,Using `ConnectionFactoryUtils`>>
* <<r2dbc-SingleConnectionFactory,Using `SingleConnectionFactory`>>
* <<r2dbc-TransactionAwareConnectionFactoryProxy,Using `TransactionAwareConnectionFactoryProxy`>>
* <<r2dbc-R2dbcTransactionManager,Using `R2dbcTransactionManager`>>
[[r2dbc-ConnectionFactory]]
=== Using `ConnectionFactory`
@@ -77,7 +77,7 @@ Kotlin::
Used at the class level as above, the annotation indicates a default for all methods
of the declaring class (as well as its subclasses). Alternatively, each method can be
annotated individually. See
xref:data-access/transaction/declarative/annotations.adoc#transaction-declarative-annotations-method-visibility[method visibility]
<<transaction-declarative-annotations-method-visibility,method visibility>>
for further details on which methods Spring considers transactional. Note that a class-level
annotation does not apply to ancestor classes up the class hierarchy; in such a scenario,
inherited methods need to be locally redeclared in order to participate in a
@@ -360,7 +360,7 @@ properties of the `@Transactional` annotation:
|===
| Property| Type| Description
| xref:data-access/transaction/declarative/annotations.adoc#tx-multiple-tx-mgrs-with-attransactional[value]
| <<tx-multiple-tx-mgrs-with-attransactional,value>>
| `String`
| Optional qualifier that specifies the transaction manager to be used.
@@ -98,7 +98,7 @@ through its `key` attribute. You can use xref:core/expressions.adoc[SpEL] to pic
arguments of interest (or their nested properties), perform operations, or even
invoke arbitrary methods without having to write any code or implement any interface.
This is the recommended approach over the
xref:integration/cache/annotations.adoc#cache-annotations-cacheable-default-key[default generator],
<<cache-annotations-cacheable-default-key,default generator>>,
since methods tend to be quite different in signatures as the code base grows. While the
default strategy might work for some methods, it rarely works for all methods.
@@ -160,7 +160,7 @@ For applications that work with several cache managers, you can set the
<1> Specifying `anotherCacheManager`.
You can also replace the `CacheResolver` entirely in a fashion similar to that of
replacing xref:integration/cache/annotations.adoc#cache-annotations-cacheable-key[key generation].
replacing <<cache-annotations-cacheable-key,key generation>>.
The resolution is requested for every cache operation, letting the implementation
actually resolve the caches to use based on runtime arguments. The following example
shows how to specify a `CacheResolver`:
@@ -684,5 +684,5 @@ preceding code:
Even though `@SlowService` is not a Spring annotation, the container automatically picks
up its declaration at runtime and understands its meaning. Note that, as mentioned
xref:integration/cache/annotations.adoc#cache-annotation-enable[earlier],
<<cache-annotation-enable,earlier>>,
annotation-driven behavior needs to be enabled.
@@ -29,7 +29,7 @@ or eviction contracts.
== Ehcache-based Cache
Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. See
xref:integration/cache/store-configuration.adoc#cache-store-configuration-jsr107[JSR-107 Cache] for details.
<<cache-store-configuration-jsr107,JSR-107 Cache>> for details.
[[cache-store-configuration-caffeine]]
@@ -25,7 +25,7 @@ See xref:integration/jms/annotated.adoc#jms-annotated-support[Enable Listener En
In a fashion similar to a Message-Driven Bean (MDB) in the EJB world, the Message-Driven
POJO (MDP) acts as a receiver for JMS messages. The one restriction (but see
xref:integration/jms/receiving.adoc#jms-receiving-async-message-listener-adapter[Using `MessageListenerAdapter`])
<<jms-receiving-async-message-listener-adapter,Using `MessageListenerAdapter`>>)
on an MDP is that it must implement the `jakarta.jms.MessageListener` interface.
Note that, if your POJO receives messages on multiple threads, it is important to
ensure that your implementation is thread-safe.
@@ -206,8 +206,8 @@ boilerplate JMS infrastructure concerns to the framework.
There are two standard JMS message listener containers packaged with Spring, each with
its specialized feature set.
* xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]
* xref:integration/jms/using.adoc#jms-mdp-default[`DefaultMessageListenerContainer`]
* <<jms-mdp-simple,`SimpleMessageListenerContainer`>>
* <<jms-mdp-default,`DefaultMessageListenerContainer`>>
[[jms-mdp-simple]]
=== Using `SimpleMessageListenerContainer`
@@ -258,7 +258,7 @@ a simple `BackOff` implementation retries every five seconds. You can specify
a custom `BackOff` implementation for more fine-grained recovery options. See
{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.
NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),
NOTE: Like its sibling (<<jms-mdp-simple,`SimpleMessageListenerContainer`>>),
`DefaultMessageListenerContainer` supports native JMS transactions and allows for
customizing the acknowledgment mode. If feasible for your scenario, This is strongly
recommended over externally managed transactions -- that is, if you can live with
@@ -33,7 +33,7 @@ the export happens or disable automatic registration by setting the `autoStartup
[[jmx-exporting-mbeanserver]]
== Creating an MBeanServer
The configuration shown in the xref:integration/jmx/exporting.adoc[preceding section] assumes that the
The configuration shown in the <<jmx-exporting,preceding section>> assumes that the
application is running in an environment that has one (and only one) `MBeanServer`
already running. In this case, Spring tries to locate the running `MBeanServer` and
register your beans with that server (if any). This behavior is useful when your
@@ -108,7 +108,7 @@ In the preceding example, you can see that the `AnnotationTestBean` class is ann
with `@ManagedResource` and that this `@ManagedResource` annotation is configured
with a set of attributes. These attributes can be used to configure various aspects
of the MBean that is generated by the `MBeanExporter` and are explained in greater
detail later in xref:integration/jmx/interface.adoc#jmx-interface-metadata-types[Spring JMX Annotations].
detail later in <<jmx-interface-metadata-types,Spring JMX Annotations>>.
Both the `age` and `name` properties are annotated with `@ManagedAttribute`,
but, in the case of the `age` property, only the getter method is annotated.
@@ -305,7 +305,7 @@ it. The only downside with this approach is that the name of the `AnnotationTest
has business meaning. You can address this issue by configuring an `ObjectNamingStrategy`
as explained in xref:integration/jmx/naming.adoc[Controlling `ObjectName` Instances for
Your Beans]. You can also see an example which uses the `MetadataNamingStrategy` in
xref:integration/jmx/interface.adoc#jmx-interface-metadata[Using Source-level Metadata: Java Annotations].
<<jmx-interface-metadata,Using Source-level Metadata: Java Annotations>>.
@@ -131,7 +131,7 @@ If necessary, you can provide a reference to a particular MBean `server`, and th
`defaultDomain` attribute (a property of `AnnotationMBeanExporter`) accepts an alternate
value for the generated MBean `ObjectName` domains. This is used in place of the
fully qualified package name as described in the previous section on
xref:integration/jmx/naming.adoc#jmx-naming-metadata[MetadataNamingStrategy], as the following example shows:
<<jmx-naming-metadata,MetadataNamingStrategy>>, as the following example shows:
include-code::./CustomJmxConfiguration[tag=snippet,indent=0]
@@ -19,26 +19,26 @@ You can learn more about {spring-boot-docs-ref}/actuator/observability.html[conf
== List of produced Observations
Spring Framework instruments various features for observability.
As outlined xref:integration/observability.adoc[at the beginning of this section], observations can generate timer Metrics and/or Traces depending on the configuration.
As outlined <<observability,at the beginning of this section>>, observations can generate timer Metrics and/or Traces depending on the configuration.
.Observations produced by Spring Framework
[%autowidth]
|===
|Observation name |Description
|xref:integration/observability.adoc#observability.http-client[`"http.client.requests"`]
|<<observability.http-client,`"http.client.requests"`>>
|Time spent for HTTP client exchanges
|xref:integration/observability.adoc#observability.http-server[`"http.server.requests"`]
|<<observability.http-server,`"http.server.requests"`>>
|Processing time for HTTP server exchanges at the Framework level
|xref:integration/observability.adoc#observability.jms.publish[`"jms.message.publish"`]
|<<observability.jms.publish,`"jms.message.publish"`>>
|Time spent sending a JMS message to a destination by a message producer.
|xref:integration/observability.adoc#observability.jms.process[`"jms.message.process"`]
|<<observability.jms.process,`"jms.message.process"`>>
|Processing time for a JMS message that was previously received by a message consumer.
|xref:integration/observability.adoc#observability.tasks-scheduled[`"tasks.scheduled.execution"`]
|<<observability.tasks-scheduled,`"tasks.scheduled.execution"`>>
|Processing time for an execution of a `@Scheduled` task
|===
@@ -3,10 +3,10 @@
The Spring Framework provides the following choices for making calls to REST endpoints:
* xref:integration/rest-clients.adoc#rest-restclient[`RestClient`] -- synchronous client with a fluent API
* xref:integration/rest-clients.adoc#rest-webclient[`WebClient`] -- non-blocking, reactive client with fluent API
* xref:integration/rest-clients.adoc#rest-resttemplate[`RestTemplate`] -- synchronous client with template method API, now deprecated in favor of `RestClient`
* xref:integration/rest-clients.adoc#rest-http-service-client[HTTP Service Clients] -- annotated interface backed by generated proxy
* <<rest-restclient,`RestClient`>> -- synchronous client with a fluent API
* <<rest-webclient,`WebClient`>> -- non-blocking, reactive client with fluent API
* <<rest-resttemplate,`RestTemplate`>> -- synchronous client with template method API, now deprecated in favor of `RestClient`
* <<rest-http-service-client,HTTP Service Clients>> -- annotated interface backed by generated proxy
[[rest-restclient]]
@@ -435,7 +435,7 @@ The `RestTemplate` provides a high-level API over HTTP client libraries in the f
It exposes the following groups of overloaded methods:
WARNING: As of Spring Framework 7.0, `RestTemplate` is deprecated in favor of `RestClient` and will be removed in a future version,
please use the xref:integration/rest-clients.adoc#migrating-to-restclient["Migrating to RestClient"] guide.
please use the <<migrating-to-restclient,"Migrating to RestClient">> guide.
For asynchronous and streaming scenarios, consider the reactive xref:web/webflux-webclient.adoc[WebClient].
[[rest-overview-of-resttemplate-methods-tbl]]
@@ -515,7 +515,7 @@ You can consider the following steps:
2. Once all client requests go through `RestClient` instances, you can now work on replicating your existing
`RestTemplate` instance creations by using `RestClient.Builder`. Because `RestTemplate` and `RestClient`
share the same infrastructure, you can reuse custom `ClientHttpRequestFactory` or `ClientHttpRequestInterceptor`
in your setup. See xref:integration/rest-clients.adoc#rest-restclient[the `RestClient` builder API].
in your setup. See <<rest-restclient,the `RestClient` builder API>>.
If no other library is available on the classpath, `RestClient` will choose the `JdkClientHttpRequestFactory`
powered by the modern JDK `HttpClient`, whereas `RestTemplate` would pick the `SimpleClientHttpRequestFactory` that
@@ -829,7 +829,7 @@ The following table shows `RestClient` equivalents for `RestTemplate` methods.
`RestClient` and `RestTemplate` instances share the same behavior when it comes to throwing exceptions
(with the `RestClientException` type being at the top of the hierarchy).
When `RestTemplate` consistently throws `HttpClientErrorException` for "4xx" response statues,
`RestClient` allows for more flexibility with custom xref:integration/rest-clients.adoc#rest-http-service-client-exceptions["status handlers"].
`RestClient` allows for more flexibility with custom <<rest-http-service-client-exceptions,"status handlers">>.
[[rest-http-service-client]]
@@ -183,7 +183,7 @@ default). The following listing shows the available methods for `Trigger` implem
Spring provides two implementations of the `Trigger` interface. The most interesting one
is the `CronTrigger`. It enables the scheduling of tasks based on
xref:integration/scheduling.adoc#scheduling-cron-expression[cron expressions].
<<scheduling-cron-expression,cron expressions>>.
For example, the following task is scheduled to run 15 minutes past each hour but only
during the 9-to-5 "business hours" on weekdays:
@@ -335,7 +335,7 @@ of time to wait before the intended execution of the method:
----
If simple periodic scheduling is not expressive enough, you can provide a
xref:integration/scheduling.adoc#scheduling-cron-expression[cron expression].
<<scheduling-cron-expression,cron expression>>.
The following example runs only on weekdays:
[source,java,indent=0]
@@ -578,7 +578,7 @@ in combination with a custom pointcut.
=== Executor Qualification with `@Async`
By default, when specifying `@Async` on a method, the executor that is used is the
one xref:integration/scheduling.adoc#scheduling-enable-annotation-support[configured when enabling async support],
one <<scheduling-enable-annotation-support,configured when enabling async support>>,
i.e. the "`annotation-driven`" element if you are using XML or your `AsyncConfigurer`
implementation, if any. However, you can use the `value` attribute of the `@Async`
annotation when you need to indicate that an executor other than the default should be
@@ -658,7 +658,7 @@ The following creates a `ThreadPoolTaskExecutor` instance:
<task:executor id="executor" pool-size="10"/>
----
As with the scheduler shown in the xref:integration/scheduling.adoc#scheduling-task-namespace-scheduler[previous section],
As with the scheduler shown in the <<scheduling-task-namespace-scheduler,previous section>>,
the value provided for the `id` attribute is used as the prefix for thread names within
the pool. As far as the pool size is concerned, the `executor` element supports more
configuration options than the `scheduler` element. For one thing, the thread pool for
@@ -770,7 +770,7 @@ any previous execution takes. Additionally, for both `fixed-delay` and `fixed-ra
tasks, you can specify an 'initial-delay' parameter, indicating the number of
milliseconds to wait before the first execution of the method. For more control,
you can instead provide a `cron` attribute to provide a
xref:integration/scheduling.adoc#scheduling-cron-expression[cron expression].
<<scheduling-cron-expression,cron expression>>.
The following example shows these other options:
[source,xml,indent=0]
@@ -791,8 +791,8 @@ The following example shows these other options:
== Cron Expressions
All Spring cron expressions have to conform to the same format, whether you are using them in
xref:integration/scheduling.adoc#scheduling-annotation-support-scheduled[`@Scheduled` annotations],
xref:integration/scheduling.adoc#scheduling-task-namespace-scheduled-tasks[`task:scheduled-tasks` elements],
<<scheduling-annotation-support-scheduled,`@Scheduled` annotations>>,
<<scheduling-task-namespace-scheduled-tasks,`task:scheduled-tasks` elements>>,
or someplace else. A well-formed cron expression, such as `* * * * * *`, consists of six
space-separated time and date fields, each with its own range of valid values:
+21 -21
View File
@@ -131,11 +131,11 @@ demonstrate its API and protocol features.
The `spring-messaging` module contains the following:
* xref:rsocket.adoc#rsocket-requester[RSocketRequester] -- fluent API to make requests
* <<rsocket-requester,RSocketRequester>> -- fluent API to make requests
through an `io.rsocket.RSocket` with data and metadata encoding/decoding.
* xref:rsocket.adoc#rsocket-annot-responders[Annotated Responders] -- `@MessageMapping`
* <<rsocket-annot-responders,Annotated Responders>> -- `@MessageMapping`
and `@RSocketExchange` annotated handler methods for responding.
* xref:rsocket.adoc#rsocket-interface[RSocket Interface] -- RSocket service declaration
* <<rsocket-interface,RSocket Interface>> -- RSocket service declaration
as Java interface with `@RSocketExchange` methods, for use as requester or responder.
The `spring-web` module contains `Encoder` and `Decoder` implementations such as Jackson
@@ -217,7 +217,7 @@ metadata, the default mime type is
metadata value and mime type pairs per request. Typically both don't need to be changed.
Data and metadata in the `SETUP` frame is optional. On the server side,
xref:rsocket.adoc#rsocket-annot-connectmapping[@ConnectMapping] methods can be used to
<<rsocket-annot-connectmapping,@ConnectMapping>> methods can be used to
handle the start of a connection and the content of the `SETUP` frame. Metadata may be
used for connection level security.
@@ -355,7 +355,7 @@ annotation such as `@RSocketClientResponder` vs the default `@Controller`. This
is necessary in scenarios with client and server, or multiple clients in the same
application.
See also xref:rsocket.adoc#rsocket-annot-responders[Annotated Responders], for more on the programming model.
See also <<rsocket-annot-responders,Annotated Responders>>, for more on the programming model.
[[rsocket-requester-client-advanced]]
==== Advanced
@@ -396,7 +396,7 @@ Kotlin::
To make requests from a server to connected clients is a matter of obtaining the
requester for the connected client from the server.
In xref:rsocket.adoc#rsocket-annot-responders[Annotated Responders], `@ConnectMapping` and `@MessageMapping` methods support an
In <<rsocket-annot-responders,Annotated Responders>>, `@ConnectMapping` and `@MessageMapping` methods support an
`RSocketRequester` argument. Use it to access the requester for the connection. Keep in
mind that `@ConnectMapping` methods are essentially handlers of the `SETUP` frame which
must be handled before requests can begin. Therefore, requests at the very start must be
@@ -442,8 +442,8 @@ Kotlin::
[[rsocket-requester-requests]]
=== Requests
Once you have a xref:rsocket.adoc#rsocket-requester-client[client] or
xref:rsocket.adoc#rsocket-requester-server[server] requester, you can make requests as follows:
Once you have a <<rsocket-requester-client,client>> or
<<rsocket-requester-server,server>> requester, you can make requests as follows:
[tabs]
======
@@ -647,7 +647,7 @@ Kotlin::
`RSocketMessageHandler` supports
{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and
{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its
xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a
<<rsocket-metadata-extractor,MetadataExtractor>> if you need to switch to a
different mime type or register additional metadata mime types.
You'll need to set the `Encoder` and `Decoder` instances required for metadata and data
@@ -716,13 +716,13 @@ Kotlin::
Annotated responders on the client side need to be configured in the
`RSocketRequester.Builder`. For details, see
xref:rsocket.adoc#rsocket-requester-client-responder[Client Responders].
<<rsocket-requester-client-responder,Client Responders>>.
[[rsocket-annot-messagemapping]]
=== @MessageMapping
Once xref:rsocket.adoc#rsocket-annot-responders-server[server] or
xref:rsocket.adoc#rsocket-annot-responders-client[client] responder configuration is in place,
Once <<rsocket-annot-responders-server,server>> or
<<rsocket-annot-responders-client,client>> responder configuration is in place,
`@MessageMapping` methods can be used as follows:
[tabs]
@@ -780,10 +780,10 @@ use the following method arguments:
pass:q[`@MessageMapping("find.radar.{id}")`].
| `@Header`
| Metadata value registered for extraction as described in xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor].
| Metadata value registered for extraction as described in <<rsocket-metadata-extractor,MetadataExtractor>>.
| `@Headers Map<String, Object>`
| All metadata values registered for extraction as described in xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor].
| All metadata values registered for extraction as described in <<rsocket-metadata-extractor,MetadataExtractor>>.
|===
@@ -846,7 +846,7 @@ interaction type(s):
As an alternative to `@MessageMapping`, you can also handle requests with
`@RSocketExchange` methods. Such methods are declared on an
xref:rsocket-interface[RSocket Interface] and can be used as a requester via
<<rsocket-interface,RSocket Interface>> and can be used as a requester via
`RSocketServiceProxyFactory` or implemented by a responder.
For example, to handle requests as a responder:
@@ -897,8 +897,8 @@ former needs to remain suitable for requester and responder use. For example, wh
`@MessageMapping` can be declared to handle any number of routes and each route can
be a pattern, `@RSocketExchange` must be declared with a single, concrete route. There are
also small differences in the supported method parameters related to metadata, see
xref:rsocket-annot-messagemapping[@MessageMapping] and
xref:rsocket-interface[RSocket Interface] for a list of supported parameters.
<<rsocket-annot-messagemapping,@MessageMapping>> and
<<rsocket-interface,RSocket Interface>> for a list of supported parameters.
`@RSocketExchange` can be used at the type level to specify a common prefix for all routes
for a given RSocket service interface.
@@ -911,7 +911,7 @@ any subsequent metadata push notifications through the `METADATA_PUSH` frame, i.
`metadataPush(Payload)` in `io.rsocket.RSocket`.
`@ConnectMapping` methods support the same arguments as
xref:rsocket.adoc#rsocket-annot-messagemapping[@MessageMapping] but based on metadata and data from the `SETUP` and
<<rsocket-annot-messagemapping,@MessageMapping>> but based on metadata and data from the `SETUP` and
`METADATA_PUSH` frames. `@ConnectMapping` can have a pattern to narrow handling to
specific connections that have a route in the metadata, or if no patterns are declared
then all connections match.
@@ -920,7 +920,7 @@ then all connections match.
`Mono<Void>` as the return value. If handling returns an error for a new
connection then the connection is rejected. Handling must not be held up to make
requests to the `RSocketRequester` for the connection. See
xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.
<<rsocket-requester-server,Server Requester>> for details.
[[rsocket-metadata-extractor]]
@@ -1036,7 +1036,7 @@ Kotlin::
The Spring Framework lets you define an RSocket service as a Java interface with
`@RSocketExchange` methods. You can pass such an interface to `RSocketServiceProxyFactory`
to create a proxy which performs requests through an
xref:rsocket.adoc#rsocket-requester[RSocketRequester]. You can also implement the
<<rsocket-requester,RSocketRequester>>. You can also implement the
interface as a responder that handles requests.
Start by creating the interface with `@RSocketExchange` methods:
@@ -1064,7 +1064,7 @@ Now you can create a proxy that performs requests when methods are called:
----
You can also implement the interface to handle requests as a responder.
See xref:rsocket.adoc#rsocket-annot-rsocketexchange[Annotated Responders].
See <<rsocket-annot-rsocketexchange,Annotated Responders>>.
[[rsocket-interface-method-parameters]]
=== Method Parameters
@@ -5,13 +5,13 @@ The following annotations are supported when used in conjunction with the
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-extension[`SpringExtension`]
and the JUnit Jupiter testing framework:
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-springextensionconfig[`@SpringExtensionConfig`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-junit-jupiter-springjunitconfig[`@SpringJUnitConfig`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-junit-jupiter-springjunitwebconfig[`@SpringJUnitWebConfig`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration[`@NestedTestConfiguration`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-junit-jupiter-enabledif[`@EnabledIf`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-junit-jupiter-disabledif[`@DisabledIf`]
* <<integration-testing-annotations-springextensionconfig,`@SpringExtensionConfig`>>
* <<integration-testing-annotations-junit-jupiter-springjunitconfig,`@SpringJUnitConfig`>>
* <<integration-testing-annotations-junit-jupiter-springjunitwebconfig,`@SpringJUnitWebConfig`>>
* <<integration-testing-annotations-testconstructor,`@TestConstructor`>>
* <<integration-testing-annotations-nestedtestconfiguration,`@NestedTestConfiguration`>>
* <<integration-testing-annotations-junit-jupiter-enabledif,`@EnabledIf`>>
* <<integration-testing-annotations-junit-jupiter-disabledif,`@DisabledIf`>>
* xref:testing/annotations/integration-spring/annotation-disabledinaotmode.adoc[`@DisabledInAotMode`]
@@ -59,7 +59,7 @@ Consequently, there is no need to declare this annotation on a test class that d
contain `@Nested` test classes.
In addition,
xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration[`@NestedTestConfiguration`]
<<integration-testing-annotations-nestedtestconfiguration,`@NestedTestConfiguration`>>
does not apply to this annotation. `@SpringExtensionConfig` will always be detected
within a `@Nested` test class hierarchy, effectively disregarding any
`@NestedTestConfiguration(OVERRIDE)` declarations.
@@ -291,7 +291,7 @@ following annotations.
* xref:testing/annotations/integration-spring/annotation-sql.adoc[`@Sql`]
* xref:testing/annotations/integration-spring/annotation-sqlconfig.adoc[`@SqlConfig`]
* xref:testing/annotations/integration-spring/annotation-sqlmergemode.adoc[`@SqlMergeMode`]
* xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`]
* <<integration-testing-annotations-testconstructor,`@TestConstructor`>>
NOTE: The use of `@NestedTestConfiguration` typically only makes sense in conjunction
with `@Nested` test classes in JUnit Jupiter; however, there may be other testing
@@ -13,10 +13,10 @@ xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-runne
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit 4 rules], or
xref:testing/testcontext-framework/support-classes.adoc#testcontext-support-classes-junit4[Spring's JUnit 4 support classes]:
* xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-ifprofilevalue[`@IfProfileValue`]
* xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-profilevaluesourceconfiguration[`@ProfileValueSourceConfiguration`]
* xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-timed[`@Timed`]
* xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-repeat[`@Repeat`]
* <<integration-testing-annotations-junit4-ifprofilevalue,`@IfProfileValue`>>
* <<integration-testing-annotations-junit4-profilevaluesourceconfiguration,`@ProfileValueSourceConfiguration`>>
* <<integration-testing-annotations-junit4-timed,`@Timed`>>
* <<integration-testing-annotations-junit4-repeat,`@Repeat`>>
[[integration-testing-annotations-junit4-ifprofilevalue]]
@@ -41,10 +41,10 @@ integration support, and the rest of this chapter then focuses on dedicated topi
Spring's integration testing support has the following primary goals:
* To manage xref:testing/integration.adoc#testing-ctx-management[Spring IoC container caching] between tests.
* To provide xref:testing/integration.adoc#testing-fixture-di[Dependency Injection of test fixture instances].
* To provide xref:testing/integration.adoc#testing-tx[transaction management] appropriate to integration testing.
* To supply xref:testing/integration.adoc#testing-support-classes[Spring-specific base classes] that assist
* To manage <<testing-ctx-management,Spring IoC container caching>> between tests.
* To provide <<testing-fixture-di,Dependency Injection of test fixture instances>>.
* To provide <<testing-tx,transaction management>> appropriate to integration testing.
* To supply <<testing-support-classes,Spring-specific base classes>> that assist
developers in writing integration tests.
The next few sections describe each goal and provide links to implementation and
@@ -139,8 +139,8 @@ xref:integration/rest-clients.adoc#rest-restclient[`RestClient`] and `RestTestCl
the same API up to the point of the call to `exchange()`. After that, `RestTestClient`
provides two alternative ways to verify the response:
1. xref:testing/resttestclient.adoc#resttestclient.workflow[Built-in Assertions] extend the request workflow with a chain of expectations
2. xref:testing/resttestclient.adoc#resttestclient.assertj[AssertJ Integration] to verify the response via `assertThat()` statements
1. <<resttestclient.workflow,Built-in Assertions>> extend the request workflow with a chain of expectations
2. <<resttestclient.assertj,AssertJ Integration>> to verify the response via `assertThat()` statements
TIP: See the xref:integration/rest-clients.adoc#rest-message-conversion[HTTP Message Conversion]
section for examples on how to prepare a request with any content, including form data and multipart data.
@@ -167,7 +167,7 @@ include-code::./RestClientWorkflowTests[tag=soft-assertions,indent=0]
You can then choose to decode the response body through one of the following:
* `expectBody(Class<T>)`: Decode to single object.
* `expectBody()`: Decode to `byte[]` for xref:testing/resttestclient.adoc#resttestclient.json[JSON Content] or an empty body.
* `expectBody()`: Decode to `byte[]` for <<resttestclient.json,JSON Content>> or an empty body.
If the built-in assertions are insufficient, you can consume the object instead and
@@ -58,7 +58,7 @@ implementations to the list of default factories in the same manner through thei
If a custom `ContextCustomizerFactory` is registered via `@ContextCustomizerFactories`, it
will be _merged_ with the default factories that have been registered using the aforementioned
xref:testing/testcontext-framework/ctx-management/context-customizers.adoc#testcontext-context-customizers-automatic-discovery[automatic discovery mechanism].
<<testcontext-context-customizers-automatic-discovery,automatic discovery mechanism>>.
The merging algorithm ensures that duplicates are removed from the list and that locally
declared factories are appended to the list of default factories when merged.
@@ -105,7 +105,7 @@ by default.
====
Method-level `@Sql` declarations override class-level declarations by default, but this
behavior may be configured per test class or per test method via `@SqlMergeMode`. See
xref:testing/testcontext-framework/executing-sql.adoc#testcontext-executing-sql-declaratively-script-merging[Merging and Overriding Configuration with `@SqlMergeMode`]
<<testcontext-executing-sql-declaratively-script-merging,Merging and Overriding Configuration with `@SqlMergeMode`>>
for further details.
However, this does not apply to class-level declarations configured for the
@@ -23,8 +23,8 @@ following features above and beyond the feature set that Spring supports for JUn
TestNG:
* Dependency injection for test constructors, test methods, and test lifecycle callback
methods. See xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[Dependency
Injection with the `SpringExtension`] for further details.
methods. See <<testcontext-junit-jupiter-di,Dependency Injection with the
`SpringExtension`>> for further details.
* Powerful support for link:https://docs.junit.org/current/extensions/conditional-test-execution.html[conditional
test execution] based on SpEL expressions, environment variables, system properties,
and so on. See the documentation for `@EnabledIf` and `@DisabledIf` in
@@ -503,7 +503,7 @@ Kotlin::
====
JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated
since Spring Framework 7.0 in favor of the
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-extension[`SpringExtension`]
<<testcontext-junit-jupiter-extension,`SpringExtension`>>
and JUnit Jupiter.
====
@@ -516,7 +516,7 @@ loading application contexts, dependency injection of test instances, transactio
method execution, and so on. If you want to use the Spring TestContext Framework with an
alternative runner (such as JUnit 4's `Parameterized` runner) or third-party runners
(such as the `MockitoJUnitRunner`), you can, optionally, use
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's support for JUnit rules]
<<testcontext-junit4-rules,Spring's support for JUnit rules>>
instead.
The following code listing shows the minimal requirements for configuring a test class to
@@ -566,7 +566,7 @@ be configured through `@ContextConfiguration`.
====
JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated
since Spring Framework 7.0 in favor of the
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-extension[`SpringExtension`]
<<testcontext-junit-jupiter-extension,`SpringExtension`>>
and JUnit Jupiter.
====
@@ -643,7 +643,7 @@ Kotlin::
====
JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated
since Spring Framework 7.0 in favor of the
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-extension[`SpringExtension`]
<<testcontext-junit-jupiter-extension,`SpringExtension`>>
and JUnit Jupiter.
====
@@ -679,7 +679,7 @@ Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an
TIP: These classes are a convenience for extension. If you do not want your test classes
to be tied to a Spring-specific class hierarchy, you can configure your own custom test
classes by using `@RunWith(SpringRunner.class)` or
xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit rules].
<<testcontext-junit4-rules,Spring's JUnit rules>>.
[[testcontext-support-classes-testng]]
@@ -99,7 +99,7 @@ manner through their own `spring.factories` files.
== Ordering `TestExecutionListener` Implementations
When the TestContext framework discovers default `TestExecutionListener` implementations
through the xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-automatic-discovery[aforementioned]
through the <<testcontext-tel-config-automatic-discovery,aforementioned>>
`SpringFactoriesLoader` mechanism, the instantiated listeners are sorted by using
Spring's `AnnotationAwareOrderComparator`, which honors Spring's `Ordered` interface and
`@Order` annotation for ordering. `AbstractTestExecutionListener` and all default
@@ -167,7 +167,7 @@ introduced in Spring Framework 4.1, and `DirtiesContextBeforeModesTestExecutionL
was introduced in Spring Framework 4.2. Furthermore, third-party frameworks like Spring
Boot and Spring Security register their own default `TestExecutionListener`
implementations by using the aforementioned
xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-automatic-discovery[automatic discovery mechanism].
<<testcontext-tel-config-automatic-discovery,automatic discovery mechanism>>.
To avoid having to be aware of and re-declare all default listeners, you can set the
`mergeMode` attribute of `@TestExecutionListeners` to `MergeMode.MERGE_WITH_DEFAULTS`.
@@ -175,7 +175,7 @@ To avoid having to be aware of and re-declare all default listeners, you can set
default listeners. The merging algorithm ensures that duplicates are removed from the
list and that the resulting set of merged listeners is sorted according to the semantics
of `AnnotationAwareOrderComparator`, as described in
xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-ordering[Ordering `TestExecutionListener` Implementations].
<<testcontext-tel-config-ordering,Ordering `TestExecutionListener` Implementations>>.
If a listener implements `Ordered` or is annotated with `@Order`, it can influence the
position in which it is merged with the defaults. Otherwise, locally declared listeners
are appended to the list of default listeners when merged.
@@ -195,7 +195,7 @@ Kotlin::
----
======
As explained in xref:testing/testcontext-framework/tx.adoc#testcontext-tx-rollback-and-commit-behavior[Transaction Rollback and Commit Behavior],
As explained in <<testcontext-tx-rollback-and-commit-behavior,Transaction Rollback and Commit Behavior>>,
there is no need to clean up the database after the `createUser()` method runs,
since any changes made to the database are automatically rolled back by the
`TransactionalTestExecutionListener`.
@@ -598,7 +598,7 @@ Kotlin::
.Testing ORM entity lifecycle callbacks
[NOTE]
=====
Similar to the note about avoiding xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives]
Similar to the note about avoiding <<testcontext-tx-false-positives,false positives>>
when testing ORM code, if your application makes use of entity lifecycle callbacks (also
known as entity listeners), make sure to flush the underlying unit of work within test
methods that run that code. Failing to _flush_ or _clear_ the underlying unit of work can
@@ -4,7 +4,7 @@
Dependency injection should make your code less dependent on the container than it would
be with traditional J2EE / Java EE development. The POJOs that make up your application
should be testable in JUnit or TestNG tests, with objects instantiated by using the `new`
operator, without Spring or any other container. You can use xref:testing/unit.adoc#mock-objects[mock objects]
operator, without Spring or any other container. You can use <<mock-objects,mock objects>>
(in conjunction with other valuable testing techniques) to test your code in isolation.
If you follow the architecture recommendations for Spring, the resulting clean layering
and componentization of your codebase facilitate easier unit testing. For example,
@@ -24,9 +24,9 @@ are described in this chapter.
Spring includes a number of packages dedicated to mocking:
* xref:testing/unit.adoc#mock-objects-env[Environment]
* xref:testing/unit.adoc#mock-objects-servlet[Servlet API]
* xref:testing/unit.adoc#mock-objects-web-reactive[Spring Web Reactive]
* <<mock-objects-env,Environment>>
* <<mock-objects-servlet,Servlet API>>
* <<mock-objects-web-reactive,Spring Web Reactive>>
[[mock-objects-env]]
=== Environment
@@ -81,8 +81,8 @@ end-to-end tests with a running server.
Spring includes a number of classes that can help with unit testing. They fall into two
categories:
* xref:testing/unit.adoc#unit-testing-utilities[General Testing Utilities]
* xref:testing/unit.adoc#unit-testing-spring-mvc[Spring MVC Testing Utilities]
* <<unit-testing-utilities,General Testing Utilities>>
* <<unit-testing-spring-mvc,Spring MVC Testing Utilities>>
[[unit-testing-utilities]]
=== General Testing Utilities
@@ -144,7 +144,7 @@ that deal with Spring MVC `ModelAndView` objects.
.Unit testing Spring MVC Controllers
TIP: To unit test your Spring MVC `Controller` classes as POJOs, use `ModelAndViewAssert`
combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring's
xref:testing/unit.adoc#mock-objects-servlet[Servlet API mocks]. For thorough integration
<<mock-objects-servlet,Servlet API mocks>>. For thorough integration
testing of your Spring MVC and REST `Controller` classes in conjunction with your
`WebApplicationContext` configuration for Spring MVC, use
xref:testing/mockmvc.adoc[MockMvc] instead.
@@ -279,8 +279,8 @@ xref:web/webflux-webclient.adoc[WebClient] and `WebTestClient` have
the same API up to the point of the call to `exchange()`. After that, `WebTestClient`
provides two alternative ways to verify the response:
1. xref:webtestclient-workflow[Built-in Assertions] extend the request workflow with a chain of expectations
2. xref:webtestclient-assertj[AssertJ Integration] to verify the response via `assertThat()` statements
1. <<webtestclient-workflow,Built-in Assertions>> extend the request workflow with a chain of expectations
2. <<webtestclient-assertj,AssertJ Integration>> to verify the response via `assertThat()` statements
TIP: See the xref:web/webflux-webclient/client-body.adoc[WebClient] documentation for
examples on how to prepare a request with any content including form data,
@@ -356,7 +356,7 @@ You can then choose to decode the response body through one of the following:
* `expectBody(Class<T>)`: Decode to single object.
* `expectBodyList(Class<T>)`: Decode and collect objects to `List<T>`.
* `expectBody()`: Decode to `byte[]` for xref:testing/webtestclient.adoc#webtestclient-json[JSON Content] or an empty body.
* `expectBody()`: Decode to `byte[]` for <<webtestclient-json,JSON Content>> or an empty body.
And perform assertions on the resulting higher level Object(s):
@@ -110,7 +110,7 @@ through one of the built-in xref:web/webflux/reactive-spring.adoc#webflux-httpha
* `RouterFunctions.toHttpHandler(RouterFunction)`
* `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)`
Most applications can run through the WebFlux Java configuration, see xref:web/webflux-functional.adoc#webflux-fn-running[Running a Server].
Most applications can run through the WebFlux Java configuration, see <<webflux-fn-running,Running a Server>>.
[[webflux-fn-handler-functions]]
@@ -369,7 +369,7 @@ parameter, though which additional constraints can be expressed.
You can write your own `RequestPredicate`, but the `RequestPredicates` utility class
offers built-in options for common needs for matching based on the HTTP method, request
path, headers, xref:#api-version[API version], and more.
path, headers, <<api-version,API version>>, and more.
The following example uses an `Accept` header, request predicate:
@@ -496,7 +496,7 @@ Router functions support matching by API version.
First, enable API versioning in the
xref:web/webflux/config.adoc#webflux-config-api-version[WebFlux Config], and then you can
use the `version` xref:#webflux-fn-predicates[predicate] as follows:
use the `version` <<webflux-fn-predicates,predicate>> as follows:
[tabs]
======
@@ -30,9 +30,9 @@ for testing in `WebTestClient`.
This is the central strategy for API versioning that holds all configured preferences
related to versioning. It does the following:
- Resolves versions from the requests via xref:#webflux-versioning-resolver[ApiVersionResolver]
- Parses raw version values into `Comparable<?>` with xref:#webflux-versioning-parser[ApiVersionParser]
- xref:#webflux-versioning-validation[Validates] request versions
- Resolves versions from the requests via <<webflux-versioning-resolver,ApiVersionResolver>>
- Parses raw version values into `Comparable<?>` with <<webflux-versioning-parser,ApiVersionParser>>
- <<webflux-versioning-validation,Validates>> request versions
`ApiVersionStrategy` helps to map requests to `@RequestMapping` controller methods,
and is initialized by the WebFlux config. Typically, applications do not interact
@@ -22,8 +22,8 @@ This section describes the HTTP caching related options available in Spring WebF
configuring settings related to the `Cache-Control` header and is accepted as an argument
in a number of places:
* xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]
* xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]
* <<webflux-caching-etag-lastmodified,Controllers>>
* <<webflux-caching-static-resources,Static Resources>>
While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible
directives for the `Cache-Control` response header, the `CacheControl` type takes a
@@ -12,7 +12,7 @@ in xref:web/webflux/dispatcher-handler.adoc#webflux-special-bean-types[Special B
For more advanced customizations, not available in the configuration API, you can
gain full control over the configuration through the
xref:web/webflux/config.adoc#webflux-config-advanced-java[Advanced Configuration Mode].
<<webflux-config-advanced-java,Advanced Configuration Mode>>.
[[webflux-config-enable]]
@@ -45,7 +45,7 @@ Kotlin::
NOTE: When using Spring Boot, you may want to use `@Configuration` classes of type `WebFluxConfigurer` but without
`@EnableWebFlux` to keep Spring Boot WebFlux customizations. See more details in
xref:#webflux-config-customize[the WebFlux config API section] and in
<<webflux-config-customize,the WebFlux config API section>> and in
{spring-boot-docs-ref}/web/reactive.html#web.reactive.webflux.auto-configuration[the dedicated Spring Boot documentation].
The preceding example registers a number of Spring WebFlux
@@ -713,7 +713,7 @@ to contain the version. The path segment must be declared as a URI variable, e.g
"/\{version}", "/api/\{version}", etc. where the actual name is not important.
As the version is typically at the start of the path, consider configuring it externally
as a common path prefix for all handlers through the
xref:web/webflux/config.adoc#webflux-config-path-matching[Path Matching] options.
<<webflux-config-path-matching,Path Matching>> options.
By default, the version is parsed with `SemanticVersionParser`, but you can also configure
a custom xref:web/webflux-versioning.adoc#webflux-versioning-parser[ApiVersionParser].
@@ -24,7 +24,7 @@ There are also HTTP method specific shortcut variants of `@RequestMapping`:
* `@DeleteMapping`
* `@PatchMapping`
The preceding annotations are xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-composed[Custom Annotations] that are provided
The preceding annotations are <<webflux-ann-requestmapping-composed,Custom Annotations>> that are provided
because, arguably, most controller methods should be mapped to a specific HTTP method versus
using `@RequestMapping`, which, by default, matches to all HTTP methods. At the same time, a
`@RequestMapping` is still needed at the class level to express shared mappings.
@@ -20,7 +20,7 @@ Spring configuration in a WebFlux application typically contains:
* `DispatcherHandler` with the bean name `webHandler`
* `WebFilter` and `WebExceptionHandler` beans
* xref:web/webflux/dispatcher-handler.adoc#webflux-special-bean-types[`DispatcherHandler` special beans]
* <<webflux-special-bean-types,`DispatcherHandler` special beans>>
* Others
The configuration is given to `WebHttpHandlerBuilder` to build the processing chain,
@@ -86,7 +86,7 @@ in the Web Handler API).
| `HandlerResultHandler`
| Process the result from the handler invocation and finalize the response.
See xref:web/webflux/dispatcher-handler.adoc#webflux-resulthandling[Result Handling].
See <<webflux-resulthandling,Result Handling>>.
|===
@@ -97,9 +97,9 @@ in the Web Handler API).
Applications can declare the infrastructure beans (listed under
xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[Web Handler API] and
xref:web/webflux/dispatcher-handler.adoc#webflux-special-bean-types[`DispatcherHandler`])
<<webflux-special-bean-types,`DispatcherHandler`>>)
that are required to process requests. However, in most cases, the
xref:web/webflux/dispatcher-handler.adoc#webflux-framework-config[WebFlux Config]
<<webflux-framework-config,WebFlux Config>>
is the best starting point. It declares the required beans and provides a higher-level
configuration callback API to customize it.
@@ -127,7 +127,7 @@ The return value from the invocation of a handler, through a `HandlerAdapter`, i
as a `HandlerResult`, along with some additional context, and passed to the first
`HandlerResultHandler` that claims support for it. The following table shows the available
`HandlerResultHandler` implementations, all of which are declared in the
xref:web/webflux/dispatcher-handler.adoc#webflux-framework-config[WebFlux Config]:
<<webflux-framework-config,WebFlux Config>>:
[cols="1,2,1", options="header"]
|===
@@ -151,7 +151,7 @@ xref:web/webflux/dispatcher-handler.adoc#webflux-framework-config[WebFlux Config
{spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],
or any other `Object` is treated as a model attribute.
See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].
See also <<webflux-viewresolution,View Resolution>>.
| `Integer.MAX_VALUE`
|===
@@ -183,7 +183,7 @@ xref:web/webflux/reactive-spring.adoc#webflux-exception-handler[Exceptions] in t
View resolution enables rendering to a browser with an HTML template and a model without
tying you to a specific view technology. In Spring WebFlux, view resolution is
supported through a dedicated xref:web/webflux/dispatcher-handler.adoc#webflux-resulthandling[HandlerResultHandler]
supported through a dedicated <<webflux-resulthandling,HandlerResultHandler>>
that uses `ViewResolver` instances to map a String (representing a logical view name) to
a `View` instance. The `View` is then used to render the response.
@@ -167,7 +167,7 @@ unsure what benefits to look for, start by learning about how non-blocking I/O w
Spring WebFlux is supported on Tomcat, Jetty, Servlet containers, as well as on
non-Servlet runtimes such as Netty. All servers are adapted to a low-level,
xref:web/webflux/reactive-spring.adoc#webflux-httphandler[common API] so that higher-level
xref:web/webflux/new-framework.adoc#webflux-programming-models[programming models] can be supported across servers.
<<webflux-programming-models,programming models>> can be supported across servers.
Spring WebFlux does not have built-in support to start or stop a server. However, it is
easy to xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[assemble] an application from Spring configuration and
@@ -269,7 +269,7 @@ of their own.
=== Configuring
The Spring Framework does not provide support for starting and stopping
xref:web/webflux/new-framework.adoc#webflux-server-choice[servers]. To configure the threading model for a server,
<<webflux-server-choice,servers>>. To configure the threading model for a server,
you need to use server-specific configuration APIs, or, if you use Spring Boot,
check the Spring Boot configuration options for each server. You can
xref:web/webflux-webclient/client-builder.adoc[configure] the `WebClient` directly.
@@ -5,10 +5,10 @@ The `spring-web` module contains the following foundational support for reactive
applications:
* For server request processing there are two levels of support.
** xref:web/webflux/reactive-spring.adoc#webflux-httphandler[HttpHandler]: Basic contract for HTTP request handling with
** <<webflux-httphandler,HttpHandler>>: Basic contract for HTTP request handling with
non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty,
Tomcat, Jetty, and any Servlet container.
** xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API]: Slightly higher level, general-purpose web API for
** <<webflux-web-handler-api,`WebHandler` API>>: Slightly higher level, general-purpose web API for
request handling, on top of which concrete programming models such as annotated
controllers and functional endpoints are built.
* For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP
@@ -18,7 +18,7 @@ https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]
and https://hc.apache.org/[Apache HttpComponents].
The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications
builds on this basic contract.
* For client and server, xref:web/webflux/reactive-spring.adoc#webflux-codecs[codecs] for serialization and
* For client and server, <<webflux-codecs,codecs>> for serialization and
deserialization of HTTP request and response content.
@@ -188,14 +188,14 @@ to adapt `HttpHandler` to a `Servlet` via `ServletHttpHandlerAdapter`.
== `WebHandler` API
The `org.springframework.web.server` package builds on the
xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract
<<webflux-httphandler,`HttpHandler`>> contract
to provide a general-purpose web API for processing requests through a chain of multiple
{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple
{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single
{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can
be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring
`ApplicationContext` where components are
xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components
<<webflux-web-handler-api-special-beans,auto-detected>>, and/or by registering components
with the builder.
While `HttpHandler` has a simple goal to abstract the use of different HTTP servers, the
@@ -223,13 +223,13 @@ Spring ApplicationContext, or that can be registered directly with it:
| `WebExceptionHandler`
| 0..N
| Provide handling for exceptions from the chain of `WebFilter` instances and the target
`WebHandler`. For more details, see xref:web/webflux/reactive-spring.adoc#webflux-exception-handler[Exceptions].
`WebHandler`. For more details, see <<webflux-exception-handler,Exceptions>>.
| <any>
| `WebFilter`
| 0..N
| Apply interception style logic to before and after the rest of the filter chain and
the target `WebHandler`. For more details, see xref:web/webflux/reactive-spring.adoc#webflux-filters[Filters].
the target `WebHandler`. For more details, see <<webflux-filters,Filters>>.
| `webHandler`
| `WebHandler`
@@ -287,7 +287,7 @@ Kotlin::
The `DefaultServerWebExchange` uses the configured `HttpMessageReader` to parse form data
(`application/x-www-form-urlencoded`) into a `MultiValueMap`. By default,
`FormHttpMessageReader` is configured for use by the `ServerCodecConfigurer` bean
(see the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[Web Handler API]).
(see the <<webflux-web-handler-api,Web Handler API>>).
[[webflux-multipart]]
@@ -321,7 +321,7 @@ dependencies.
Alternatively, the `SynchronossPartHttpMessageReader` can be used, which is based on the
https://github.com/synchronoss/nio-multipart[Synchronoss NIO Multipart] library.
Both are configured through the `ServerCodecConfigurer` bean
(see the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[Web Handler API]).
(see the <<webflux-web-handler-api,Web Handler API>>).
To parse multipart data in streaming fashion, you can use the `Flux<PartEvent>` returned from the
`PartEventHttpMessageReader` instead of using `@RequestPart`, as that implies `Map`-like access
@@ -342,7 +342,7 @@ include::partial$web/forwarded-headers.adoc[]
from the standard `"Forwarded"` or `"X-Forwarded"` headers, and also removes those headers
to eliminate further impact. If you declare it as a bean with the name
`forwardedHeaderTransformer`, it will be
xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[detected] and used.
<<webflux-web-handler-api-special-beans,detected>> and used.
[[webflux-forwarded-headers-security]]
=== Security Considerations
@@ -363,7 +363,7 @@ forwarded headers from the request without using them.
== Filters
[.small]#xref:web/webmvc/filters.adoc[See equivalent in the Servlet stack]#
In the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API], you can use a `WebFilter` to apply interception-style
In the <<webflux-web-handler-api,`WebHandler` API>>, you can use a `WebFilter` to apply interception-style
logic before and after the rest of the processing chain of filters and the target
`WebHandler`. When using the xref:web/webflux/dispatcher-handler.adoc#webflux-framework-config[WebFlux Config], registering a `WebFilter` is as simple
as declaring it as a Spring bean and (optionally) expressing precedence by using `@Order` on
@@ -408,7 +408,7 @@ not map when trailing slash handling applies; use `@RequestMapping` (no path att
== Exceptions
[.small]#xref:web/webmvc/mvc-servlet/exceptionhandlers.adoc#mvc-ann-customer-servlet-container-error-page[See equivalent in the Servlet stack]#
In the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API], you can use a `WebExceptionHandler` to handle
In the <<webflux-web-handler-api,`WebHandler` API>>, you can use a `WebExceptionHandler` to handle
exceptions from the chain of `WebFilter` instances and the target `WebHandler`. When using the
xref:web/webflux/dispatcher-handler.adoc#webflux-framework-config[WebFlux Config], registering a `WebExceptionHandler` is as simple as declaring it as a
Spring bean and (optionally) expressing precedence by using `@Order` on the bean declaration or
@@ -515,8 +515,8 @@ encode a `Mono<List<String>>`.
On the server side where form content often needs to be accessed from multiple places,
`ServerWebExchange` provides a dedicated `getFormData()` method that parses the content
through `FormHttpMessageReader` and then caches the result for repeated access.
See xref:web/webflux/reactive-spring.adoc#webflux-form-data[Form Data] in the
xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API] section.
See <<webflux-form-data,Form Data>> in the
<<webflux-web-handler-api,`WebHandler` API>> section.
Once `getFormData()` is used, the original raw content can no longer be read from the
request body. For this reason, applications are expected to go through `ServerWebExchange`
@@ -537,8 +537,8 @@ For more information about the `DefaultPartHttpMessageReader`, refer to the
On the server side where multipart form content may need to be accessed from multiple
places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses
the content through `MultipartHttpMessageReader` and then caches the result for repeated access.
See xref:web/webflux/reactive-spring.adoc#webflux-multipart[Multipart Data] in the
xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API] section.
See <<webflux-multipart,Multipart Data>> in the
<<webflux-web-handler-api,`WebHandler` API>> section.
Once `getMultipartData()` is used, the original raw content can no longer be read from the
request body. For this reason applications have to consistently use `getMultipartData()`
@@ -590,7 +590,7 @@ set all codecs, see xref:web/webflux/config.adoc#webflux-config-message-codecs[H
all codecs can be changed in
xref:web/webflux-webclient/client-builder.adoc#webflux-client-builder-maxinmemorysize[WebClient.Builder].
For xref:web/webflux/reactive-spring.adoc#webflux-codecs-multipart[Multipart parsing] the `maxInMemorySize` property limits
For <<webflux-codecs-multipart,Multipart parsing>> the `maxInMemorySize` property limits
the size of non-file parts. For file parts, it determines the threshold at which the part
is written to disk. For file parts written to disk, there is an additional
`maxDiskUsagePerPart` property to limit the amount of disk space per part. There is also
@@ -737,8 +737,8 @@ or specific behaviors that are not supported by the default codecs.
Some configuration options expressed by developers are enforced on default codecs.
Custom codecs might want to get a chance to align with those preferences,
like xref:web/webflux/reactive-spring.adoc#webflux-codecs-limits[enforcing buffering limits]
or xref:web/webflux/reactive-spring.adoc#webflux-logging-sensitive-data[logging sensitive data].
like <<webflux-codecs-limits,enforcing buffering limits>>
or <<webflux-logging-sensitive-data,logging sensitive data>>.
The following example shows how to do so for client-side requests:
@@ -109,7 +109,7 @@ Kotlin::
If you register the `RouterFunction` as a bean, for instance by exposing it in a
`@Configuration` class, it will be auto-detected by the servlet, as explained in
xref:web/webmvc-functional.adoc#webmvc-fn-running[Running a Server].
<<webmvc-fn-running,Running a Server>>.
[[webmvc-fn-handler-functions]]
@@ -568,7 +568,7 @@ parameter, through which additional constraints can be expressed.
You can write your own `RequestPredicate`, but the `RequestPredicates` utility class
offers built-in options for common needs for matching based on the HTTP method, request
path, headers, xref:#api-version[API version], and more.
path, headers, <<api-version,API version>>, and more.
The following example uses an `Accept` header, request predicate:
@@ -778,7 +778,7 @@ Router functions support matching by API version.
First, enable API versioning in the
xref:web/webmvc/mvc-config/api-version.adoc[MVC Config], and then you can use the
`version` xref:#webmvc-fn-predicates[predicate] as follows:
`version` <<webmvc-fn-predicates,predicate>> as follows:
[tabs]
======
@@ -29,9 +29,9 @@ for testing in MockMvc and `WebTestClient`.
This is the central strategy for API versioning that holds all configured preferences
related to versioning. It does the following:
- Resolves versions from the requests via xref:#mvc-versioning-resolver[ApiVersionResolver]
- Parses raw version values into `Comparable<?>` with an xref:#mvc-versioning-parser[ApiVersionParser]
- xref:#mvc-versioning-validation[Validates] request versions
- Resolves versions from the requests via <<mvc-versioning-resolver,ApiVersionResolver>>
- Parses raw version values into `Comparable<?>` with an <<mvc-versioning-parser,ApiVersionParser>>
- <<mvc-versioning-validation,Validates>> request versions
- Sends deprecation hints in the responses
`ApiVersionStrategy` helps to map requests to `@RequestMapping` controller methods,
@@ -164,7 +164,7 @@ following example shows:
=== The `input` Tag
This tag renders an HTML `input` element with the bound value and `type='text'` by default.
For an example of this tag, see xref:web/webmvc-view/mvc-jsp.adoc#mvc-view-jsp-formtaglib-formtag[The Form Tag]. You can also use
For an example of this tag, see <<mvc-view-jsp-formtaglib-formtag,The Form Tag>>. You can also use
HTML5-specific types, such as `email`, `tel`, `date`, and others.
[[mvc-view-jsp-formtaglib-checkboxtag]]
@@ -354,7 +354,7 @@ but with different values, as the following example shows:
This tag renders multiple HTML `input` elements with the `type` set to `radio`.
As with the xref:web/webmvc-view/mvc-jsp.adoc#mvc-view-jsp-formtaglib-checkboxestag[`checkboxes` tag], you might want to
As with the <<mvc-view-jsp-formtaglib-checkboxestag,`checkboxes` tag>>, you might want to
pass in the available options as a runtime variable. For this usage, you can use the
`radiobuttons` tag. You pass in an `Array`, a `List`, or a `Map` that contains the
available options in the `items` property. If you use a `Map`, the map entry key is
@@ -8,11 +8,11 @@ before and after the rest of the processing chain of filters and the target `Ser
The `spring-web` module has a number of built-in `Filter` implementations:
* xref:web/webmvc/filters.adoc#filters-http-put[Form Data]
* xref:web/webmvc/filters.adoc#filters-forwarded-headers[Forwarded Headers]
* xref:web/webmvc/filters.adoc#filters-shallow-etag[Shallow ETag]
* xref:web/webmvc/filters.adoc#filters-cors[CORS]
* xref:web/webmvc/filters.adoc#filters.url-handler[URL Handler]
* <<filters-http-put,Form Data>>
* <<filters-forwarded-headers,Forwarded Headers>>
* <<filters-shallow-etag,Shallow ETag>>
* <<filters-cors,CORS>>
* <<filters.url-handler,URL Handler>>
There are also base class implementations for use in Spring applications:
@@ -2,25 +2,25 @@
= Asynchronous Requests
Spring MVC has an extensive integration with Servlet asynchronous request
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-processing[processing]:
<<mvc-ann-async-processing,processing>>:
* xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-deferredresult[`DeferredResult`],
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-callable[`Callable`], and
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-webasynctask[`WebAsyncTask`] return values
* <<mvc-ann-async-deferredresult,`DeferredResult`>>,
<<mvc-ann-async-callable,`Callable`>>, and
<<mvc-ann-async-webasynctask,`WebAsyncTask`>> return values
in controller methods provide support for a single asynchronous return value.
* Controllers can xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-http-streaming[stream] multiple values, including
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-sse[SSE] and
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-output-stream[raw data].
* Controllers can <<mvc-ann-async-http-streaming,stream>> multiple values, including
<<mvc-ann-async-sse,SSE>> and
<<mvc-ann-async-output-stream,raw data>>.
* Controllers can use reactive clients and return
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[reactive types] for response handling.
<<mvc-ann-async-reactive-types,reactive types>> for response handling.
For an overview of how this differs from Spring WebFlux, see the xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-vs-webflux[Async Spring MVC compared to WebFlux] section below.
For an overview of how this differs from Spring WebFlux, see the <<mvc-ann-async-vs-webflux,Async Spring MVC compared to WebFlux>> section below.
[[mvc-ann-async-deferredresult]]
== `DeferredResult`
Once the asynchronous request processing feature is xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration[enabled]
Once the asynchronous request processing feature is <<mvc-ann-async-configuration,enabled>>
in the Servlet container, controller methods can wrap any supported controller method
return value with `DeferredResult`, as the following example shows:
@@ -94,13 +94,13 @@ Kotlin::
======
The return value can then be obtained by running the given task through the
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured] `AsyncTaskExecutor`.
<<mvc-ann-async-configuration-spring-mvc,configured>> `AsyncTaskExecutor`.
[[mvc-ann-async-webasynctask]]
== `WebAsyncTask`
`WebAsyncTask` is comparable to using xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-callable[Callable]
`WebAsyncTask` is comparable to using <<mvc-ann-async-callable,Callable>>
but allows customizing additional settings such a request timeout value, and the
`AsyncTaskExecutor` to execute the `java.util.concurrent.Callable` with instead
of the defaults set up globally for Spring MVC. Below is an example of using `WebAsyncTask`:
@@ -228,7 +228,7 @@ handling is built into all framework contracts and is intrinsically supported th
stages of request processing.
From a programming model perspective, both Spring MVC and Spring WebFlux support
asynchronous and xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[Reactive Types] as return values in controller methods.
asynchronous and <<mvc-ann-async-reactive-types,Reactive Types>> as return values in controller methods.
Spring MVC even supports streaming, including reactive back pressure. However, individual
writes to the response remain blocking (and are performed on a separate thread), unlike WebFlux,
which relies on non-blocking I/O and does not need an extra thread for each write.
@@ -239,7 +239,7 @@ nor does it have any explicit support for asynchronous and reactive types as mod
Spring WebFlux does support all that.
Finally, from a configuration perspective the asynchronous request processing feature must be
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration[enabled at the Servlet container level].
<<mvc-ann-async-configuration,enabled at the Servlet container level>>.
[[mvc-ann-async-http-streaming]]
@@ -368,7 +368,7 @@ xref:web/websocket.adoc[WebSocket messaging] with
xref:web/websocket/fallback.adoc[SockJS fallback] transports (including SSE) that target
a wide range of browsers.
See also xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-objects[previous section] for notes on exception handling.
See also <<mvc-ann-async-objects,previous section>> for notes on exception handling.
[[mvc-ann-async-output-stream]]
=== Raw Data
@@ -436,7 +436,7 @@ TIP: Spring MVC supports Reactor and RxJava through the
For streaming to the response, reactive back pressure is supported, but writes to the
response are still blocking and are run on a separate thread through the
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured]
<<mvc-ann-async-configuration-spring-mvc,configured>>
`AsyncTaskExecutor`, to avoid blocking the upstream source such as a `Flux` returned
from `WebClient`.
@@ -455,7 +455,7 @@ GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-object
and others.
If Micrometer Context Propagation is present on the classpath, when a controller method
returns a xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[reactive type] such as `Flux` or `Mono`, all
returns a <<mvc-ann-async-reactive-types,reactive type>> such as `Flux` or `Mono`, all
`ThreadLocal` values, for which there is a registered `io.micrometer.ThreadLocalAccessor`,
are written to the Reactor `Context` as key-value pairs, using the key assigned by the
`ThreadLocalAccessor`.
@@ -491,8 +491,8 @@ Micrometer Context Propagation library.
[.small]#xref:web/webflux/reactive-spring.adoc#webflux-codecs-streaming[See equivalent in the Reactive stack]#
The Servlet API does not provide any notification when a remote client goes away.
Therefore, while streaming to the response, whether through xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-sse[SseEmitter]
or xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[reactive types], it is important to send data periodically,
Therefore, while streaming to the response, whether through <<mvc-ann-async-sse,SseEmitter>>
or <<mvc-ann-async-reactive-types,reactive types>>, it is important to send data periodically,
since the write fails if the client has disconnected. The send could take the form of an
empty (comment-only) SSE event or any other data that the other side would have to interpret
as a heartbeat and ignore.
@@ -535,7 +535,7 @@ You can configure the following:
* The default timeout value for async requests depends
on the underlying Servlet container, unless it is set explicitly.
* `AsyncTaskExecutor` to use for blocking writes when streaming with
xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[Reactive Types] and for
<<mvc-ann-async-reactive-types,Reactive Types>> and for
executing `Callable` instances returned from controller methods.
The one used by default is not suitable for production under load.
* `DeferredResultProcessingInterceptor` implementations and `CallableProcessingInterceptor` implementations.
@@ -24,8 +24,8 @@ in a number of places:
* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]
* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]
* xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]
* xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]
* <<mvc-caching-etag-lastmodified,Controllers>>
* <<mvc-caching-static-resources,Static Resources>>
While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible
directives for the `Cache-Control` response header, the `CacheControl` type takes a
@@ -25,7 +25,7 @@ There are also HTTP method specific shortcut variants of `@RequestMapping`:
* `@PatchMapping`
The shortcuts are
xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-composed[Custom Annotations]
<<mvc-ann-requestmapping-composed,Custom Annotations>>
that are provided because, arguably, most controller methods should be mapped to a specific
HTTP method versus using `@RequestMapping`, which, by default, matches to all HTTP methods.
A `@RequestMapping` is still needed at the class level to express shared mappings.
@@ -405,10 +405,9 @@ Kotlin::
<1> Testing whether `myHeader` equals `myValue`.
======
TIP: You can match `Content-Type` and `Accept` with the headers condition, but it is better to use
xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-consumes[consumes]
and xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-produces[produces]
instead.
TIP: You can match `Content-Type` and `Accept` with the headers condition, but it is
better to use <<mvc-ann-requestmapping-consumes,consumes>> and
<<mvc-ann-requestmapping-produces,produces>> instead.
[[mvc-ann-requestmapping-version]]
@@ -521,7 +520,7 @@ is not necessary in the common case.
[[mvc-ann-requestmapping-composed]]
== Custom Annotations
[.small]#xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-head-options[See equivalent in the Reactive stack]#
[.small]#<<mvc-ann-requestmapping-head-options,See equivalent in the Reactive stack>>#
Spring MVC supports the use of xref:core/beans/classpath-scanning.adoc#beans-meta-annotations[composed annotations]
for request mapping. Those are annotations that are themselves meta-annotated with
@@ -648,4 +647,4 @@ xref:web/webmvc/mvc-controller/ann-methods/arguments.adoc[@RequestMapping].
`@HttpExchange` also supports a `headers()` parameter which accepts `"name=value"`-like
pairs like in `@RequestMapping(headers={})` on the client side. On the server side,
this extends to the full syntax that
xref:#mvc-ann-requestmapping-params-and-headers[`@RequestMapping`] supports.
<<mvc-ann-requestmapping-params-and-headers,`@RequestMapping`>> supports.
@@ -19,11 +19,11 @@ Locale resolvers and interceptors are defined in the
context in the normal way. The following selection of locale resolvers is included in
Spring.
* xref:web/webmvc/mvc-servlet/localeresolver.adoc#mvc-timezone[Time Zone]
* xref:web/webmvc/mvc-servlet/localeresolver.adoc#mvc-localeresolver-acceptheader[Header Resolver]
* xref:web/webmvc/mvc-servlet/localeresolver.adoc#mvc-localeresolver-cookie[Cookie Resolver]
* xref:web/webmvc/mvc-servlet/localeresolver.adoc#mvc-localeresolver-session[Session Resolver]
* xref:web/webmvc/mvc-servlet/localeresolver.adoc#mvc-localeresolver-interceptor[Locale Interceptor]
* <<mvc-timezone,Time Zone>>
* <<mvc-localeresolver-acceptheader,Header Resolver>>
* <<mvc-localeresolver-cookie,Cookie Resolver>>
* <<mvc-localeresolver-session,Session Resolver>>
* <<mvc-localeresolver-interceptor,Locale Interceptor>>
[[mvc-timezone]]
@@ -41,7 +41,7 @@ The following table provides more details on the `ViewResolver` hierarchy:
| `ContentNegotiatingViewResolver`
| Implementation of the `ViewResolver` interface that resolves a view based on the
request file name or `Accept` header. See xref:web/webmvc/mvc-servlet/viewresolver.adoc#mvc-multiple-representations[Content Negotiation].
request file name or `Accept` header. See <<mvc-multiple-representations,Content Negotiation>>.
| `BeanNameViewResolver`
| Implementation of the `ViewResolver` interface that interprets a view name as a
@@ -52,7 +52,7 @@ the steps of the WebSocket handshake, including validating the client origin,
negotiating a sub-protocol, and other details. An application may also need to use this
option if it needs to configure a custom `RequestUpgradeStrategy` in order to
adapt to a WebSocket server engine and version that is not yet supported
(see xref:web/websocket/server.adoc#websocket-server-deployment[Deployment] for more on this subject).
(see <<websocket-server-deployment,Deployment>> for more on this subject).
Both the Java configuration and XML namespace make it possible to configure a custom
`HandshakeHandler`.
@@ -5,9 +5,9 @@ Applications can use annotated `@Controller` classes to handle messages from cli
Such classes can declare `@MessageMapping`, `@SubscribeMapping`, and `@ExceptionHandler`
methods, as described in the following topics:
* xref:web/websocket/stomp/handle-annotations.adoc#websocket-stomp-message-mapping[`@MessageMapping`]
* xref:web/websocket/stomp/handle-annotations.adoc#websocket-stomp-subscribe-mapping[`@SubscribeMapping`]
* xref:web/websocket/stomp/handle-annotations.adoc#websocket-stomp-exception-handler[`@MessageExceptionHandler`]
* <<websocket-stomp-message-mapping,`@MessageMapping`>>
* <<websocket-stomp-subscribe-mapping,`@SubscribeMapping`>>
* <<websocket-stomp-exception-handler,`@MessageExceptionHandler`>>
[[websocket-stomp-message-mapping]]
@@ -102,7 +102,7 @@ See xref:web/websocket/stomp/handle-send.adoc[Sending Messages].
`@SubscribeMapping` is similar to `@MessageMapping` but narrows the mapping to
subscription messages only. It supports the same
xref:web/websocket/stomp/handle-annotations.adoc#websocket-stomp-message-mapping[method arguments] as `@MessageMapping`. However
<<websocket-stomp-message-mapping,method arguments>> as `@MessageMapping`. However
for the return value, by default, a message is sent directly to the client (through
`clientOutboundChannel`, in response to the subscription) and not to the broker (through
`brokerChannel`, as a broadcast to matching subscriptions). Adding `@SendTo` or
@@ -173,7 +173,7 @@ The following example declares an exception through a method argument:
`@MessageExceptionHandler` methods support flexible method signatures and support
the same method argument types and return values as
xref:web/websocket/stomp/handle-annotations.adoc#websocket-stomp-message-mapping[`@MessageMapping`] methods.
<<websocket-stomp-message-mapping,`@MessageMapping`>> methods.
Typically, `@MessageExceptionHandler` methods apply within the `@Controller` class
(or class hierarchy) in which they are declared. If you want such methods to apply