General doc revision: configuration updates, consistent formatting etc

This commit is contained in:
Juergen Hoeller
2019-03-05 13:08:34 +01:00
parent 3eb1042a53
commit 216e4eeba4
35 changed files with 1549 additions and 1624 deletions

View File

@@ -10,16 +10,16 @@
This part of the reference documentation covers all the technologies that are
absolutely integral to the Spring Framework.
Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container. A
thorough treatment of the Spring Framework's IoC container is closely followed by
comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies. The
Spring Framework has its own AOP framework, which is conceptually easy to understand
and which successfully addresses the 80% sweet spot of AOP requirements in Java
enterprise programming.
Foremost amongst these is the Spring Framework's Inversion of Control (IoC) container.
A thorough treatment of the Spring Framework's IoC container is closely followed by
comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies.
The Spring Framework has its own AOP framework, which is conceptually easy to
understand and which successfully addresses the 80% sweet spot of AOP requirements
in Java enterprise programming.
Coverage of Spring's integration with AspectJ (currently the richest -- in terms of
features -- and certainly most mature AOP implementation in the Java enterprise space) is
also provided.
features -- and certainly most mature AOP implementation in the Java enterprise space)
is also provided.
include::core/core-beans.adoc[leveloffset=+1]

View File

@@ -5,6 +5,7 @@
[[xsd-schemas]]
== XML Schemas
@@ -38,7 +39,6 @@ correct schema so that the tags in the `util` namespace are available to you):
====
[[xsd-schemas-util-constant]]
==== Using `<util:constant/>`
@@ -78,8 +78,6 @@ developer's intent ("`inject this constant value`"), and it reads better:
----
====
[[xsd-schemas-util-frfb]]
===== Setting a Bean Property or Constructor Argument from a Field Value
@@ -139,10 +137,9 @@ described in the API documentation for the
class.
Injecting enumeration values into beans as either property or constructor arguments is
easy to do in Spring. You do not actually have to do anything or know
anything about the Spring internals (or even about classes such as the
`FieldRetrievingFactoryBean`). The following example enumeration shows how easy injecting an
enum value is:
easy to do in Spring. You do not actually have to do anything or know anything about
the Spring internals (or even about classes such as the `FieldRetrievingFactoryBean`).
The following example enumeration shows how easy injecting an enum value is:
====
[source,java,indent=0]
@@ -186,7 +183,6 @@ Now consider the following setter of type `PersistenceContextType` and the corre
====
[[xsd-schemas-util-property-path]]
==== Using `<util:property-path/>`
@@ -359,7 +355,6 @@ The following example uses a `util:properties` element to make a more concise re
====
[[xsd-schemas-util-list]]
==== Using `<util:list/>`
@@ -424,7 +419,6 @@ following configuration:
If no `list-class` attribute is supplied, the container chooses a `List` implementation.
[[xsd-schemas-util-map]]
==== Using `<util:map/>`
@@ -489,7 +483,6 @@ following configuration:
If no `'map-class'` attribute is supplied, the container chooses a `Map` implementation.
[[xsd-schemas-util-set]]
==== Using `<util:set/>`
@@ -612,69 +605,64 @@ available to you:
====
[[xsd-schemas-context-pphc]]
==== Using `<property-placeholder/>`
This element activates the replacement of `${...}` placeholders, which are resolved against a
specified properties file (as a <<core.adoc#resources,Spring resource location>>). This element is
specified properties file (as a <<core.adoc#resources, Spring resource location>>). This element is
a convenience mechanism that sets up a <<core.adoc#beans-factory-placeholderconfigurer,
`PropertyPlaceholderConfigurer`>> for you. If you need more control over the
`PropertyPlaceholderConfigurer`, you can explicitly define one yourself.
[[xsd-schemas-context-ac]]
==== Using `<annotation-config/>`
This element activates the Spring infrastructure to detect annotations in bean
classes:
This element activates the Spring infrastructure to detect annotations in bean classes:
* Spring's <<core.adoc#beans-required-annotation, `@Required`>> and
<<core.adoc#beans-annotation-config, `@Autowired`>>
* JSR 250's `@PostConstruct`,
`@PreDestroy` and `@Resource` (if available)
* JPA's `@PersistenceContext` and
`@PersistenceUnit` (if available).
* Spring's <<core.adoc#beans-factory-metadata, `@Configuration`>> model
* <<core.adoc#beans-annotation-config, `@Autowired`/`@Inject`>> and `@Value`
* JSR-250's `@Resource`, `@PostConstruct` and `@PreDestroy` (if available)
* JPA's `@PersistenceContext` and `@PersistenceUnit` (if available)
* Spring's <<core.adoc#context-functionality-events-annotation, `@EventListener`>>
Alternatively, you can choose to explicitly activate the
individual `BeanPostProcessors` for those annotations.
Alternatively, you can choose to explicitly activate the individual `BeanPostProcessors`
for those annotations.
NOTE: This element does not activate processing of Spring's
<<data-access.adoc#transaction-declarative-annotations, `@Transactional`>> annotation. You can use the
<<data-access.adoc#tx-decl-explained, `<tx:annotation-driven/>`>> element for that purpose.
<<data-access.adoc#transaction-declarative-annotations, `@Transactional`>> annotation;
you can use the <<data-access.adoc#tx-decl-explained, `<tx:annotation-driven/>`>>
element for that purpose. Similarly, Spring's
<<integration.adoc#cache-annotations, caching annotations>> need to be explicitly
<<integration.adoc#cache-annotation-enable, enabled>> as well.
[[xsd-schemas-context-component-scan]]
==== Using `<component-scan/>`
This element is detailed in <<core.adoc#beans-annotation-config,
Annotation-based container configuration>>.
This element is detailed in the section on <<core.adoc#beans-annotation-config,
annotation-based container configuration>>.
[[xsd-schemas-context-ltw]]
==== Using `<load-time-weaver/>`
This element is detailed in <<core.adoc#aop-aj-ltw,
Load-time weaving with AspectJ in the Spring Framework>>.
This element is detailed in the section on <<core.adoc#aop-aj-ltw,
load-time weaving with AspectJ in the Spring Framework>>.
[[xsd-schemas-context-sc]]
==== Using `<spring-configured/>`
This element is detailed in <<core.adoc#aop-atconfigurable,
Using AspectJ to dependency inject domain objects with Spring>>.
This element is detailed in the section on <<core.adoc#aop-atconfigurable,
using AspectJ to dependency inject domain objects with Spring>>.
[[xsd-schemas-context-mbe]]
==== Using `<mbean-export/>`
This element is detailed in <<integration.adoc#jmx-context-mbeanexport,
Configuring annotation based MBean export>>.
This element is detailed in the section on <<integration.adoc#jmx-context-mbeanexport,
configuring annotation-based MBean export>>.
@@ -684,8 +672,8 @@ Configuring annotation based MBean export>>.
Last but not least, we have the elements in the `beans` schema. These elements
have been in Spring since the very dawn of the framework. Examples of the various elements
in the `beans` schema are not shown here because they are quite comprehensively covered
in <<core.adoc#beans-factory-properties-detailed,Dependencies and configuration in detail>>
(and, indeed, in that entire <<core.adoc#beans,chapter>>).
in <<core.adoc#beans-factory-properties-detailed, dependencies and configuration in detail>>
(and, indeed, in that entire <<core.adoc#beans, chapter>>).
Note that you can add zero or more key-value pairs to `<bean/>` XML definitions.
What, if anything, is done with this extra metadata is totally up to your own custom
@@ -716,9 +704,9 @@ as it stands).
<1> This is the example `meta` element
====
In the case of the preceding example, you could assume that there is some logic that
consumes the bean definition and sets up some caching infrastructure that uses the supplied
metadata.
In the case of the preceding example, you could assume that there is some logic that consumes
the bean definition and sets up some caching infrastructure that uses the supplied metadata.
@@ -738,11 +726,11 @@ Spring distribution, you should first read the appendix entitled <<xsd-config>>.
To create new XML configuration extensions:
. <<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
. <<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).
. <<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
@@ -864,7 +852,7 @@ The `NamespaceHandler` interface features three methods:
* `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)`: Called
when Spring encounters an attribute or nested element of a different namespace.
The decoration of one or more bean definitions is used (for example) with the
<<core.adoc#beans-factory-scopes,scopes that Spring supports>>.
<<core.adoc#beans-factory-scopes, scopes that Spring supports>>.
We start by highlighting a simple example, without using decoration, after which
we show decoration in a somewhat more advanced example.
@@ -964,6 +952,7 @@ is the extraction and setting of the bean definition's unique identifier.
[[xsd-custom-registration]]
=== Registering the Handler and the Schema
The coding is finished. All that remains to be done is to make the Spring XML
parsing infrastructure aware of our custom element. We do so by registering our custom
`namespaceHandler` and custom XSD file in two special-purpose properties files. These
@@ -973,7 +962,6 @@ XML parsing infrastructure automatically picks up your new extension by consumin
these special properties files, the formats of which are detailed in the next two sections.
[[xsd-custom-registration-spring-handlers]]
==== Writing `META-INF/spring.handlers`
@@ -996,7 +984,6 @@ namespace extension and needs to exactly match exactly the value of the `targetN
attribute, as specified in your custom XSD schema.
[[xsd-custom-registration-spring-schemas]]
==== Writing 'META-INF/spring.schemas'
@@ -1067,7 +1054,6 @@ in a Spring XML configuration file:
This section presents some more detailed examples of custom XML extensions.
[[xsd-custom-custom-nested]]
==== Nesting Custom Elements within Custom Elements
@@ -1135,7 +1121,6 @@ The following listing shows the `Component` class:
public void setName(String name) {
this.name = name;
}
}
----
====
@@ -1183,16 +1168,15 @@ setter property for the `components` property. The following listing shows such
public boolean isSingleton() {
return true;
}
}
----
====
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 <<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:
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 <<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:
====
[source,xml,indent=0]
@@ -1220,7 +1204,8 @@ custom tag, as the following listing shows:
----
====
Again following <<xsd-custom-introduction,the process described earlier>>, we then create a custom `NamespaceHandler`:
Again following <<xsd-custom-introduction, the process described earlier>>,
we then create a custom `NamespaceHandler`:
====
[source,java,indent=0]
@@ -1235,14 +1220,13 @@ Again following <<xsd-custom-introduction,the process described earlier>>, we th
public void init() {
registerBeanDefinitionParser("component", new ComponentBeanDefinitionParser());
}
}
----
====
Next up is the custom `BeanDefinitionParser`. Remember that we are creating
`BeanDefinition` that describes a `ComponentFactoryBean`. The following listing shows our
custom `BeanDefinitionParser`:
a `BeanDefinition` that describes a `ComponentFactoryBean`. The following
listing shows our custom `BeanDefinitionParser` implementation:
====
[source,java,indent=0]
@@ -1292,7 +1276,6 @@ custom `BeanDefinitionParser`:
}
factory.addPropertyValue("children", children);
}
}
----
====
@@ -1317,21 +1300,20 @@ http\://www.foo.com/schema/component/component.xsd=com/foo/component.xsd
====
[[xsd-custom-custom-just-attributes]]
==== Custom Attributes on "`Normal`" Elements
Writing your own custom parser and the associated artifacts is not hard. However, it is sometimes
not the right thing to do. Consider a scenario where you need to add metadata to
already existing bean definitions. In this case, you certainly do not want to have to
write your own entire custom extension. Rather, you merely want to add an
additional attribute to the existing bean definition element.
Writing your own custom parser and the associated artifacts is not hard. However,
it is sometimes not the right thing to do. Consider a scenario where you need to
add metadata to already existing bean definitions. In this case, you certainly
do not want to have to write your own entire custom extension. Rather, you merely
want to add an additional attribute to the existing bean definition element.
By way of another example, suppose that you define a bean
definition for a service object that (unknown to it) accesses a clustered
http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the named
JCache instance is eagerly started within the surrounding cluster. The following
listing shows such a definition:
By way of another example, suppose that you define a bean definition for a
service object that (unknown to it) accesses a clustered
http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the
named JCache instance is eagerly started within the surrounding cluster.
The following listing shows such a definition:
====
[source,xml,indent=0]
@@ -1367,13 +1349,12 @@ JCache-initializing `BeanDefinition`. The following listing shows our `JCacheIni
public void initialize() {
// lots of JCache API calls to initialize the named cache...
}
}
----
====
Now we can move onto the custom extension. First, we need to author the XSD schema that describes the
custom attribute, as follows:
Now we can move onto the custom extension. First, we need to author
the XSD schema that describes the custom attribute, as follows:
====
[source,xml,indent=0]
@@ -1413,9 +1394,9 @@ Next, we need to create the associated `NamespaceHandler`, as follows:
----
====
Next, we need to create the parser. Note that, in this case, because we are going to parse an XML
attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`.
The following listing shows our `BeanDefinitionDecorator`:
Next, we need to create the parser. Note that, in this case, because we are going to parse
an XML attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`.
The following listing shows our `BeanDefinitionDecorator` implementation:
====
[source,java,indent=0]
@@ -1470,7 +1451,6 @@ The following listing shows our `BeanDefinitionDecorator`:
}
return beanName;
}
}
----
====

View File

@@ -104,13 +104,13 @@ Spring IoC container.
NOTE: XML-based metadata is not the only allowed form of configuration metadata.
The Spring IoC container itself is totally decoupled from the format in which this
configuration metadata is actually written. These days, many developers choose
<<beans-java,Java-based configuration>> for their Spring applications.
<<beans-java, Java-based configuration>> for their Spring applications.
For information about using other forms of metadata with the Spring container, see:
* <<beans-annotation-config,Annotation-based configuration>>: Spring 2.5 introduced
support for annotation-based configuration metadata.
* <<beans-java,Java-based configuration>>: Starting with Spring 3.0, many features
* <<beans-java, Java-based configuration>>: Starting with Spring 3.0, many features
provided by the Spring JavaConfig project became part of the core Spring Framework.
Thus, you can define beans external to your application classes by using Java rather
than XML files. To use these new features, see the
@@ -265,7 +265,7 @@ XML configuration file represents a logical layer or module in your architecture
You can use the application context constructor to load bean definitions from all these
XML fragments. This constructor takes multiple `Resource` locations, as was shown in the
<<beans-factory-instantiation,previous section>>. Alternatively, use one or more
<<beans-factory-instantiation, 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:
@@ -1024,8 +1024,8 @@ example shows:
Keep in mind that, to make this work out of the box, your code must be compiled with the
debug flag enabled so that Spring can look up the parameter name from the constructor.
If you cannot or do not want to compile your code with the debug flag, you can use
http://download.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties]
If you cannot or do not want to compile your code with the debug flag, you can use the
http://download.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties]
JDK annotation to explicitly name your constructor arguments. The sample class would
then have to look as follows:
@@ -1096,7 +1096,7 @@ load an entire Spring IoC container instance.
****
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
use constructors for mandatory dependencies and setter methods or configuration methods
for optional dependencies. Note that use of the <<beans-required-annotation,@Required>>
for optional dependencies. Note that use of the <<beans-required-annotation, @Required>>
annotation on a setter method can be used to make the property be a required dependency;
however, constructor injection with programmatic validation of arguments is preferable.
@@ -1189,7 +1189,7 @@ to being injected into the dependent bean. This means that, if bean A has a depe
bean B, the Spring IoC container completely configures bean B prior to invoking the
setter method on bean A. In other words, the bean is instantiated (if it is not a
pre-instantiated singleton), its dependencies are set, and the relevant lifecycle
methods (such as a <<beans-factory-lifecycle-initializingbean,configured init method>>
methods (such as a <<beans-factory-lifecycle-initializingbean, configured init method>>
or the <<beans-factory-lifecycle-initializingbean,InitializingBean callback method>>)
are invoked.
@@ -1358,7 +1358,7 @@ do not discuss those details here.
[[beans-factory-properties-detailed]]
=== Dependencies and Configuration in Detail
As mentioned in the <<beans-factory-collaborators,previous section>>, you can define bean
As mentioned in the <<beans-factory-collaborators, previous section>>, you can define bean
properties and constructor arguments as references to other managed beans (collaborators)
or as values defined inline. Spring's XML-based configuration metadata supports
sub-element types within its `<property/>` and `<constructor-arg/>` elements for this
@@ -2195,11 +2195,11 @@ 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 <<beans-factory-autowire-candidate,next section>>.
to `false`, as described in the <<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, as described in <<beans-annotation-config>>.
* Implement the more fine-grained control available with annotation-based configuration,
as described in <<beans-annotation-config>>.
@@ -2304,7 +2304,7 @@ https://spring.io/blog/2004/08/06/method-injection/[this blog entry].
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 <<beans-factory-method-injection,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.
@@ -3524,7 +3524,7 @@ configured with a different method name, then each configured method is executed
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 executed once, as explained in the
<<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:
@@ -3789,7 +3789,7 @@ init-method.
[[aware-list]]
=== Other `Aware` Interfaces
Besides `ApplicationContextAware` and `BeanNameAware` (discussed <<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:
@@ -4459,7 +4459,7 @@ while others argue that annotated classes are no longer POJOs and, furthermore,
configuration becomes decentralized and harder to control.
No matter the choice, Spring can accommodate both styles and even mix them together.
It is worth pointing out that through its <<beans-java,JavaConfig>> option, Spring lets
It is worth pointing out that through its <<beans-java, JavaConfig>> option, Spring lets
annotations be used in a non-invasive way, without touching the target components
source code and that, in terms of tooling, all configuration styles are supported by the
https://spring.io/tools/sts[Spring Tool Suite].
@@ -4864,7 +4864,7 @@ an `ApplicationContext` object:
[NOTE]
====
The `@Autowired`, `@Inject`, `@Resource`, and `@Value` annotations are handled by Spring
The `@Autowired`, `@Inject`, `@Value`, and `@Resource` annotations are handled by Spring
`BeanPostProcessor` implementations. This means that you cannot apply these annotations
within your own `BeanPostProcessor` or `BeanFactoryPostProcessor` types (if any).
These types must be 'wired up' explicitly by using XML or a Spring `@Bean` method.
@@ -5648,9 +5648,9 @@ supported as a marker for automatic exception translation in your persistence la
=== Using Meta-annotations and Composed Annotations
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 <<beans-stereotype-annotations,earlier>> is meta-annotated with
`@Component`, as the following example shows:
own code. A meta-annotation is an annotation that can be applied to another annotation.
For example, the `@Service` annotation mentioned <<beans-stereotype-annotations, earlier>>
is meta-annotated with `@Component`, as the following example shows:
====
[source,java,indent=0]
@@ -5814,16 +5814,16 @@ TIP: The use of `<context:component-scan>` implicitly enables the functionality
====
The scanning of classpath packages requires the presence of corresponding directory
entries in the classpath. When you build JARs with Ant, make sure that you do not
activate the files-only switch of the JAR task. Also, classpath directories may not
be exposed based on security policies in some environments -- for example, standalone apps on
activate the files-only switch of the JAR task. Also, classpath directories may not be
exposed based on security policies in some environments -- for example, standalone apps on
JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see
http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).
On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.
However, make sure that your component classes are exported in your `module-info`
descriptors. If you expect Spring to invoke non-public members of your classes, make
sure that they are 'opened' (that is, that they use an `opens` declaration instead of an `exports`
declaration in your `module-info` descriptor).
sure that they are 'opened' (that is, that they use an `opens` declaration instead of an
`exports` declaration in your `module-info` descriptor).
====
Furthermore, the `AutowiredAnnotationBeanPostProcessor` and
@@ -6855,7 +6855,7 @@ following example shows:
----
====
NOTE: Remember that `@Configuration` classes are <<beans-meta-annotations,meta-annotated>>
NOTE: Remember that `@Configuration` classes are <<beans-meta-annotations, meta-annotated>>
with `@Component`, so they are candidates for component-scanning. In the preceding example,
assuming that `AppConfig` is declared within the `com.acme` package (or any package
underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`
@@ -6935,8 +6935,8 @@ init-param):
`@Bean` is a method-level annotation and a direct analog of the XML `<bean/>` element.
The annotation supports some of the attributes offered by `<bean/>`, such as:
* <<beans-factory-lifecycle-initializingbean,init-method>>
* <<beans-factory-lifecycle-disposablebean,destroy-method>>
* <<beans-factory-lifecycle-initializingbean, init-method>>
* <<beans-factory-lifecycle-disposablebean, destroy-method>>
* <<beans-factory-autowire,autowiring>>
* `name`.
@@ -7048,7 +7048,7 @@ parameter, as the following example shows:
====
The resolution mechanism is pretty much identical to constructor-based dependency
injection. See <<beans-constructor-injection,the relevant section>> for more details.
injection. See <<beans-constructor-injection, the relevant section>> for more details.
[[beans-java-lifecycle-callbacks]]
@@ -7056,17 +7056,17 @@ injection. See <<beans-constructor-injection,the relevant section>> for more det
Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks
and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250. See
<<beans-postconstruct-and-predestroy-annotations,JSR-250 annotations>> for further
<<beans-postconstruct-and-predestroy-annotations, JSR-250 annotations>> for further
details.
The regular Spring <<beans-factory-nature,lifecycle>> callbacks are fully supported as
The regular Spring <<beans-factory-nature, lifecycle>> callbacks are fully supported as
well. If a bean implements `InitializingBean`, `DisposableBean`, or `Lifecycle`, their
respective methods are called by the container.
The standard set of `*Aware` interfaces (such as <<beans-beanfactory,BeanFactoryAware>>,
<<beans-factory-aware,BeanNameAware>>,
<<context-functionality-messagesource,MessageSourceAware>>,
<<beans-factory-aware,ApplicationContextAware>>, and so on) are also fully supported.
The standard set of `*Aware` interfaces (such as <<beans-beanfactory, BeanFactoryAware>>,
<<beans-factory-aware, BeanNameAware>>,
<<context-functionality-messagesource, MessageSourceAware>>,
<<beans-factory-aware, ApplicationContextAware>>, and so on) are also fully supported.
The `@Bean` annotation supports specifying arbitrary initialization and destruction
callback methods, much like Spring XML's `init-method` and `destroy-method` attributes
@@ -7176,7 +7176,7 @@ Spring includes the `@Scope` annotation so that you can specify the scope of a b
You can specify that your beans defined with the `@Bean` annotation should have a
specific scope. You can use any of the standard scopes specified in the
<<beans-factory-scopes,Bean Scopes>> section.
<<beans-factory-scopes, Bean Scopes>> section.
The default scope is `singleton`, but you can override this with the `@Scope` annotation,
as the following example shows:
@@ -7201,14 +7201,15 @@ as the following example shows:
===== `@Scope` and `scoped-proxy`
Spring offers a convenient way of working with scoped dependencies through
<<beans-factory-scopes-other-injection,scoped proxies>>. The easiest way to create such
a proxy when using the XML configuration is the `<aop:scoped-proxy/>` element.
Configuring your beans in Java with a `@Scope` annotation offers equivalent support with
the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`), but you can
specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
<<beans-factory-scopes-other-injection, scoped proxies>>. The easiest way to create
such a proxy when using the XML configuration is the `<aop:scoped-proxy/>` element.
Configuring your beans in Java with a `@Scope` annotation offers equivalent support
with the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`),
but you can specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
If you port the scoped proxy example from the XML reference documentation (see
<<beans-factory-scopes-other-injection,scoped proxies>>) to our `@Bean` using Java, it resembles the following:
<<beans-factory-scopes-other-injection, scoped proxies>>) to our `@Bean` using Java,
it resembles the following:
====
[source,java,indent=0]
@@ -7354,7 +7355,7 @@ by using plain `@Component` classes.
[[beans-java-method-injection]]
==== Lookup Method Injection
As noted earlier, <<beans-factory-method-injection,lookup method injection>> is an
As noted earlier, <<beans-factory-method-injection, lookup method injection>> is an
advanced feature that you should use rarely. It is useful in cases where a
singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this
type of configuration provides a natural means for implementing this pattern. The
@@ -7552,7 +7553,7 @@ issue, because no compiler is involved, and you can declare
When using `@Configuration` classes, the Java compiler places constraints on
the configuration model, in that references to other beans must be valid Java syntax.
Fortunately, solving this problem is simple. As <<beans-java-dependencies,we already discussed>>,
Fortunately, solving this problem is simple. As <<beans-java-dependencies, we already discussed>>,
a `@Bean` method can have an arbitrary number of parameters that describe the bean
dependencies. Consider the following more real-world scenario with several `@Configuration`
classes, each depending on beans declared in the others:
@@ -8030,8 +8031,8 @@ jdbc.password=
The {api-spring-framework}/core/env/Environment.html[`Environment`] interface
is an abstraction integrated in the container that models two key
aspects of the application environment: <<beans-definition-profiles,profiles>>
and <<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
@@ -8174,7 +8175,7 @@ NOTE: You cannot mix the `&` and `|` operators without using parentheses. For ex
`production & us-east | eu-central` is not a valid expression. It must be expressed as
`production & (us-east | eu-central)`.
You can use `@Profile` as a <<beans-meta-annotations,meta-annotation>> for the purpose
You can use `@Profile` as a <<beans-meta-annotations, meta-annotation>> for the purpose
of creating a custom composed annotation. The following example defines a custom
`@Production` annotation that you can use as a drop-in replacement for
`@Profile("production")`:
@@ -8382,9 +8383,9 @@ 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 <<beans-property-source-abstraction>>). In integration tests, active
profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test` module
(see <<testing.adoc#testcontext-ctx-management-env-profiles,
Context configuration with environment profiles>>).
profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test`
module (see <<testing.adoc#testcontext-ctx-management-env-profiles,
context configuration with environment profiles>>).
Note that profiles are not an "`either-or`" proposition. You can activate multiple
profiles at once. Programmatically, you can provide multiple profile names to the
@@ -8656,9 +8657,10 @@ Alternatively, for XML configuration, you can use the `context:load-time-weaver`
Once configured for the `ApplicationContext`, any bean within that `ApplicationContext`
may implement `LoadTimeWeaverAware`, thereby receiving a reference to the load-time
weaver instance. This is particularly useful in combination with
<<data-access.adoc#orm-jpa,Spring's JPA support>> where load-time weaving may be necessary
for JPA class transformation.
Consult the {api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]
<<data-access.adoc#orm-jpa, Spring's JPA support>> where load-time weaving may be
necessary for JPA class transformation.
Consult the
{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]
javadoc for more detail. For more on AspectJ load-time weaving, see <<aop-aj-ltw>>.
@@ -8667,7 +8669,7 @@ javadoc for more detail. For more on AspectJ load-time weaving, see <<aop-aj-ltw
[[context-introduction]]
== Additional Capabilities of the `ApplicationContext`
As discussed in the <<beans,chapter introduction>>, the `org.springframework.beans.factory`
As discussed in the <<beans, chapter introduction>>, the `org.springframework.beans.factory`
package provides basic functionality for managing and manipulating beans, including in a
programmatic way. The `org.springframework.context` package adds the
{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]
@@ -8919,7 +8921,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 <<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.
@@ -9149,12 +9151,12 @@ following example shows how to do so:
----
====
It is also possible to add additional runtime filtering by using the `condition` attribute of the
annotation that defines a <<expressions,`SpEL` expression>> , which should match to actually
invoke the method for a particular event.
It is also possible to add additional runtime filtering by using the `condition` attribute
of the annotation that defines a <<expressions, `SpEL` expression>> , which should match
to actually invoke the method for a particular event.
The following example shows how our notifier can be rewritten to be invoked only if the `content` attribute
of the event is equal to `my-event`:
The following example shows how our notifier can be rewritten to be invoked only if the
`content` attribute of the event is equal to `my-event`:
====
[source,java,indent=0]
@@ -9211,8 +9213,8 @@ method signature to return the event that should be published, as the following
----
====
NOTE: This feature is not supported for <<context-functionality-events-async,asynchronous
listeners>>.
NOTE: This feature is not supported for
<<context-functionality-events-async, asynchronous listeners>>.
This new method publishes a new `ListUpdateEvent` for every `BlackListEvent` handled by the
method above. If you need to publish several events, you can return a `Collection` of events
@@ -9223,8 +9225,8 @@ instead.
==== Asynchronous Listeners
If you want a particular listener to process events asynchronously, you can reuse the
<<integration.adoc#scheduling-annotation-support-async,regular `@Async` support>>. The
following example shows how to do so:
<<integration.adoc#scheduling-annotation-support-async, regular `@Async` support>>.
The following example shows how to do so:
====
[source,java,indent=0]
@@ -9243,8 +9245,9 @@ Be aware of the following limitations when using asynchronous events:
* If the event listener throws an `Exception`, it is not propagated to the caller
See `AsyncUncaughtExceptionHandler` for more details.
* Such event listener cannot send replies. If you need to send another event as the
result of the processing, inject {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`] to send the event
manually.
result of the processing, inject
{api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`ApplicationEventPublisher`]
to send the event manually.
[[context-functionality-events-order]]
@@ -9320,9 +9323,8 @@ an event.
[[context-functionality-resources]]
=== Convenient Access to Low-level Resources
For optimal usage and understanding of application contexts, you should
familiarize yourself with Spring's `Resource` abstraction, as described in
<<resources>>.
For optimal usage and understanding of application contexts, you should familiarize
yourself with Spring's `Resource` abstraction, as described in <<resources>>.
An application context is a `ResourceLoader`, which can be used to load `Resource` objects.
A `Resource` is essentially a more feature rich version of the JDK `java.net.URL` class.
@@ -9478,11 +9480,11 @@ by convention (that is, by bean name or by bean type -- in particular, post-proc
while a plain `DefaultListableBeanFactory` is agnostic about any special beans.
For many extended container features, such as annotation processing and AOP proxying,
the <<beans-factory-extension-bpp,`BeanPostProcessor` extension point>> is essential.
the <<beans-factory-extension-bpp, `BeanPostProcessor` extension point>> is essential.
If you use only a plain `DefaultListableBeanFactory`, such post-processors do not
get detected and activated by default. This situation could be confusing, because
nothing is actually wrong with your bean configuration. Rather, in such a scenario, the
container needs to be fully bootstrapped through additional setup.
nothing is actually wrong with your bean configuration. Rather, in such a scenario,
the container needs to be fully bootstrapped through additional setup.
The following table lists features provided by the `BeanFactory` and
`ApplicationContext` interfaces and implementations.

View File

@@ -10,7 +10,7 @@ APIs as follows:
* <<databuffers-factory>> abstracts the creation of a data buffer.
* <<databuffers-buffer>> represents a byte buffer, which may be
<<databuffers-buffer-pooled,pooled>>.
<<databuffers-buffer-pooled, pooled>>.
* <<databuffers-utils>> offers utility methods for data buffers.
* <<Codecs>> decode or encode streams data buffer streams into higher level objects.
@@ -93,7 +93,6 @@ composite buffers, if that's supported by the underlying byte buffer API.
[[codecs]]
== Codecs
@@ -105,7 +104,7 @@ The `org.springframework.core.codec` package provides the following strategy int
The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
`String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON,
Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
<<web-reactive.adoc#webflux-codecs,Codecs>> in the WebFlux section.
<<web-reactive.adoc#webflux-codecs, Codecs>> in the WebFlux section.
@@ -114,7 +113,7 @@ Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
== Using `DataBuffer`
When working with data buffers, special care must be taken to ensure buffers are released
since they may be <<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.

View File

@@ -10,8 +10,8 @@ While there are several other Java expression languages available -- OGNL, MVEL,
EL, to name a few -- the Spring Expression Language was created to provide the Spring
community with a single well supported expression language that can be used across all
the products in the Spring portfolio. Its language features are driven by the
requirements of the projects in the Spring portfolio, including tooling requirements for
code completion support within the Eclipse-based Spring Tool Suite. That said,
requirements of the projects in the Spring portfolio, including tooling requirements
for code completion support within the Eclipse-based Spring Tool Suite. That said,
SpEL is based on a technology-agnostic API that lets other expression language
implementations be integrated, should the need arise.
@@ -20,14 +20,14 @@ portfolio, it is not directly tied to Spring and can be used independently. To
be self contained, many of the examples in this chapter use SpEL as if it were an
independent expression language. This requires creating a few bootstrapping
infrastructure classes, such as the parser. Most Spring users need not deal with
this infrastructure and can, instead, author only expression strings for evaluation. An
example of this typical use is the integration of SpEL into creating XML or annotation-based
bean definitions, as shown in <<expressions-beandef,Expression support
for defining bean definitions>>.
this infrastructure and can, instead, author only expression strings for evaluation.
An example of this typical use is the integration of SpEL into creating XML or
annotation-based bean definitions, as shown in
<<expressions-beandef, Expression support for defining bean definitions>>.
This chapter covers the features of the expression language, its API, and its language
syntax. In several places, `Inventor` and `Society` classes are used as the
target objects for expression evaluation. These class declarations and the data used to
syntax. In several places, `Inventor` and `Society` classes are used as the target
objects for expression evaluation. These class declarations and the data used to
populate them are listed at the end of the chapter.
The expression language supports the following functionality:
@@ -60,7 +60,7 @@ The expression language supports the following functionality:
This section introduces the simple use of SpEL interfaces and its expression language.
The complete language reference can be found in
<<expressions-language-ref,Language Reference>>.
<<expressions-language-ref, Language Reference>>.
The following code introduces the SpEL API to evaluate the literal string expression,
`Hello World`.
@@ -332,13 +332,14 @@ interpreter and only 3ms using the compiled version of the expression.
[[expressions-compiler-configuration]]
==== Compiler Configuration
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 (<<expressions-parser-configuration,discussed earlier>>)
or by using a system property when SpEL usage is embedded inside another component. This section
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
(<<expressions-parser-configuration, discussed earlier>>) or by using a system
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:
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:
* `OFF` (default): The compiler is switched off.
* `IMMEDIATE`: In immediate mode, the expressions are compiled as soon as possible. This
@@ -641,7 +642,7 @@ By default, real numbers are parsed by using Double.parseDouble().
Navigating with property references is easy. To do so, use a period to indicate a nested
property value. The instances of the `Inventor` class, `pupin` and `tesla`, were populated with
data listed in the <<expressions-example-classes,Classes used in the examples>> section.
data listed in the <<expressions-example-classes, Classes used in the examples>> section.
To navigate "`down`" and get Tesla's year of birth and Pupin's city of birth, we use the following
expressions:

View File

@@ -1,29 +1,31 @@
[[null-safety]]
[-[null-safety]]
= Null-safety
Although Java does not let you express null-safety with its type system, Spring Framework
now provides the following annotations in the `org.springframework.lang` package to let you declare
nullability of APIs and fields:
Although Java does not let you express null-safety with its type system, the Spring Framework
now provides the following annotations in the `org.springframework.lang` package to let you
declare nullability of APIs and fields:
* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific parameter,
return value, or field cannot be `null` (not needed on parameter and return value
where `@NonNullApi` and `@NonNullFields` apply) .
* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a specific
parameter, return value, or field can be `null`.
* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a
specific parameter, return value, or field can be `null`.
* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific
parameter, return value, or field cannot be `null` (not needed on parameters / return values
and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level
that declares non-null as the default behavior for parameters and return values.
that declares non-null as the default semantics for parameters and return values.
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package
level that declares non-null as the default behavior for fields.
level that declares non-null as the default semantics for fields.
Spring Framework leverages itself these annotations, but they can also be used in any Spring based
Java project to declare null-safe APIs and optionally null-safe fields. Generic type arguments,
varargs and array elements nullability are not supported yet, but should be in an upcoming
release, see https://jira.spring.io/browse/SPR-15942[SPR-15942] for up-to-date information.
Nullability declaration are expected to be fine-tuned between Spring Framework release,
including minor ones. Nullability of types used inside method bodies is outside of the
scope of this feature.
The Spring Framework itself leverages these annotations, but they can also be used in any
Spring-based Java project to declare null-safe APIs and optionally null-safe fields.
Generic type arguments, varargs and array elements nullability are not supported yet but
should be in an upcoming release, see https://jira.spring.io/browse/SPR-15942[SPR-15942]
for up-to-date information. Nullability declarations are expected to be fine-tuned between
Spring Framework releases, including minor ones. Nullability of types used inside method
bodies is outside of the scope of this feature.
NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this feature.
NOTE: Other common libraries such as Reactor and Spring Data provide null-safe APIs that
use a similar nullability arrangement, delivering a consistent overall experience for
Spring application developers.
@@ -32,25 +34,23 @@ NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this
In addition to providing an explicit declaration for Spring Framework API nullability,
these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful
warnings related to null-safety in order to avoid `NullPointerException`
at runtime.
warnings related to null-safety in order to avoid `NullPointerException` at runtime.
They are also used to make Spring API null-safe in Kotlin projects, since Kotlin natively
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
are available in the <<languages#kotlin-null-safety,Kotlin support documentation>>.
are available in the <<languages#kotlin-null-safety, Kotlin support documentation>>.
== JSR 305 meta-annotations
== JSR-305 meta-annotations
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors
like IDEA or Kotlin provide null-safety support in a generic way, without having to hard-code
support for Spring annotations.
annotations (a dormant but wide-spread JSR). JSR-305 meta-annotations let tooling vendors
like IDEA or Kotlin provide null-safety support in a generic way, without having to
hard-code support for Spring annotations.
It is not necessary nor recommended to add JSR 305 dependency in the project classpath to
take advantage of Spring null-safe API. Only projects such as
Spring-based libraries that use null-safety annotations in their codebase should add
`com.google.code.findbugs:jsr305:3.0.2` with `compileOnly` Gradle configuration or Maven
`provided` scope to avoid compile warnings.
It is not necessary nor recommended to add a JSR-305 dependency to the project classpath to
take advantage of Spring null-safe API. Only projects such as Spring-based libraries that use
null-safety annotations in their codebase should add `com.google.code.findbugs:jsr305:3.0.2`
with `compileOnly` Gradle configuration or Maven `provided` scope to avoid compile warnings.

View File

@@ -351,10 +351,10 @@ interface if that is all you need. The code would be coupled only to the resourc
interface (which can be considered a utility interface) and not to the whole Spring
`ApplicationContext` interface.
As of Spring 2.5, you can rely upon autowiring of the `ResourceLoader` as an alternative
to implementing the `ResourceLoaderAware` interface. The "`traditional`" `constructor` and
`byType` autowiring modes (as described in <<beans-factory-autowire>>) are now capable of
providing a dependency of type `ResourceLoader` for either a constructor argument or a
In application components, you may also rely upon autowiring of the `ResourceLoader` as
an alternative to implementing the `ResourceLoaderAware` interface. The "`traditional`"
`constructor` and `byType` autowiring modes (as described in <<beans-factory-autowire>>)
are capable of providing a `ResourceLoader` for either a constructor argument or a
setter method parameter, respectively. For more flexibility (including the ability to
autowire fields and multiple parameter methods), consider using the annotation-based
autowiring features. In that case, the `ResourceLoader` is autowired into a field,

View File

@@ -20,18 +20,19 @@ directly. Because this is reference documentation, however, we felt that some ex
might be in order. We explain the `BeanWrapper` in this chapter, since, if you are
going to use it at all, you are most likely do so when trying to bind data to objects.
Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport` implementations to parse
and format property values. The `PropertyEditor` and `PropertyEditorSupport` interfaces are part of the JavaBeans
specification and are also explained in this chapter. Spring 3 introduced a
`core.convert` package that provides a general type conversion facility, as well as a
higher-level "`format`" package for formatting UI field values. You can use these packages
as simpler alternatives to `PropertyEditorSupport` implementations. They are also discussed in this
chapter.
Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport`
implementations to parse and format property values. The `PropertyEditor` and
`PropertyEditorSupport` types are part of the JavaBeans specification and are also
explained in this chapter. Spring 3 introduced a `core.convert` package that provides a
general type conversion facility, as well as a higher-level "`format`" package for
formatting UI field values. You can use these packages as simpler alternatives to
`PropertyEditorSupport` implementations. They are also discussed in this chapter.
.JSR-303/JSR-349 Bean Validation
****
As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1
(JSR-349) for setup support and adapting them to Spring's `Validator` interface.
As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and
Bean Validation 1.1 (JSR-349) for setup support and adapting them to Spring's
`Validator` interface.
An application can choose to enable Bean Validation once globally, as described in
<<validation-beanvalidation>>, and use it exclusively for all validation needs.
@@ -173,22 +174,21 @@ methods it offers can be found in the {api-spring-framework}validation/Errors.ht
[[validation-conversion]]
== Resolving Codes to Error Messages
We covered databinding and validation. This section covers outputting messages that correspond to
validation errors. In the example shown in the <<validator,preceding section>>,
we rejected the `name` and `age` fields. If we want to output the error
messages by using a `MessageSource`, we can do so using the error code we provide when
rejecting the field ('name' and 'age' in this case). When you call (either directly, or
indirectly, by using, for example, the `ValidationUtils` class) `rejectValue` or one of the
other `reject` methods from the `Errors` interface, the underlying implementation
not only registers the code you passed in but also registers a number of additional error
codes. The `MessageCodesResolver` determines which error codes the `Errors` interface registers.
By default, the `DefaultMessageCodesResolver` is used, which (for example) not only
registers a message with the code you gave but also registers messages that include the field
name you passed to the reject method. So, if you reject a field by using
`rejectValue("age", "too.darn.old")`, apart from the `too.darn.old` code, Spring
also registers `too.darn.old.age` and `too.darn.old.age.int` (the first includes
the field name and the second includes the type of the field). This is done as a
convenience to aid developers when targeting error messages.
We covered databinding and validation. This section covers outputting messages that correspond
to validation errors. In the example shown in the <<validator, preceding section>>,
we rejected the `name` and `age` fields. If we want to output the error messages by using a
`MessageSource`, we can do so using the error code we provide when rejecting the field
('name' and 'age' in this case). When you call (either directly, or indirectly, by using,
for example, the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods
from the `Errors` interface, the underlying implementation not only registers the code you
passed in but also registers a number of additional error codes. The `MessageCodesResolver`
determines which error codes the `Errors` interface registers. By default, the
`DefaultMessageCodesResolver` is used, which (for example) not only registers a message
with the code you gave but also registers messages that include the field name you passed
to the reject method. So, if you reject a field by using `rejectValue("age", "too.darn.old")`,
apart from the `too.darn.old` code, Spring also registers `too.darn.old.age` and
`too.darn.old.age.int` (the first includes the field name and the second includes the type
of the field). This is done as a convenience to aid developers when targeting error messages.
More information on the `MessageCodesResolver` and the default strategy can be found
in the javadoc of
@@ -259,8 +259,8 @@ object. The following 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 <<beans-beans-conversion,section about
`PropertyEditors`>>.)
and their default implementations, you should skip ahead to the
<<beans-beans-conversion, section on `PropertyEditors`>>.)
The following two example classes use the `BeanWrapper` to get and set
properties:
@@ -537,17 +537,17 @@ 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 a `BeanWrapper` to
handle property conversions. The standard property editors that the `BeanWrapper`
registers are listed in <<beans-beans-conversion,the previous section>>. Additionally,
`ApplicationContexts` also override or add additional editors to handle
registers are listed in the <<beans-beans-conversion, previous section>>.
Additionally, `ApplicationContexts` also override or add additional editors to handle
resource lookups in a manner appropriate to the specific application context type.
Standard JavaBeans `PropertyEditor` instances are used to convert property values
expressed as strings to the actual complex type of the property.
You can use `CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
expressed as strings to the actual complex type of the property. You can use
`CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
support for additional `PropertyEditor` instances to an `ApplicationContext`.
Consider the following example, which defines a user class called `ExoticType` and another class called `DependsOnExoticType`, which needs
`ExoticType` set as a property:
Consider the following example, which defines a user class called `ExoticType` and
another class called `DependsOnExoticType`, which needs `ExoticType` set as a property:
====
[source,java,indent=0]
@@ -629,14 +629,15 @@ Finally, the following example shows how to use `CustomEditorConfigurer` to regi
Another mechanism for registering property editors with the Spring container is to
create and use a `PropertyEditorRegistrar`. This interface is particularly useful when
you need to use the same set of property editors in several different situations. You can write
a corresponding registrar and reuse it in each case. `PropertyEditorRegistrar` instances work
in conjunction with an interface called `PropertyEditorRegistry`, an interface that is
implemented by the Spring `BeanWrapper` (and `DataBinder`). `PropertyEditorRegistrar` instances
are particularly convenient when used in conjunction with `CustomEditorConfigurer`
(described <<beans-beans-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
you need to use the same set of property editors in several different situations.
You can write a corresponding registrar and reuse it in each case.
`PropertyEditorRegistrar` instances work in conjunction with an interface called
`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper`
(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient
when used in conjunction with `CustomEditorConfigurer` (described
<<beans-beans-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
editors: A `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor`
instances for each bean creation attempt.
@@ -687,7 +688,7 @@ The next example shows how to configure a `CustomEditorConfigurer` and inject an
====
Finally (and in a bit of a departure from the focus of this chapter for those of you
using <<web.adoc#mvc,Spring's MVC web framework>>), using `PropertyEditorRegistrars` in
using <<web.adoc#mvc, Spring's MVC web framework>>), using `PropertyEditorRegistrars` in
conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very
convenient. The following example uses a `PropertyEditorRegistrar` in the
implementation of an `initBinder(..)` method:
@@ -1002,8 +1003,7 @@ It is also common to use a `ConversionService` within a Spring MVC application.
<<web.adoc#mvc-config-conversion, Conversion and Formatting>> in the Spring MVC chapter.
In certain situations, you may wish to apply formatting during conversion. See
<<format-FormatterRegistry-SPI>> for details on using
`FormattingConversionServiceFactoryBean`.
<<format-FormatterRegistry-SPI>> for details on using `FormattingConversionServiceFactoryBean`.

View File

@@ -18,7 +18,7 @@ This part of the appendix lists XML schemas for data access, including the follo
The `tx` tags deal with configuring all of those beans in Spring's comprehensive support
for transactions. These tags are covered in the chapter entitled
<<data-access.adoc#transaction,Transaction Management>>.
<<data-access.adoc#transaction, Transaction Management>>.
TIP: We strongly encourage you to look at the `'spring-tx.xsd'` file that ships with the
Spring distribution. This file contains the XML Schema for Spring's transaction
@@ -67,8 +67,8 @@ to you.
The `jdbc` elements let you quickly configure an embedded database or initialize an
existing data source. These elements are documented in
<<data-access.adoc#jdbc-embedded-database-support,Embedded Database Support>> and
<<data-access.adoc#jdbc-initializing-datasource,Initializing a DataSource>>, respectively.
<<data-access.adoc#jdbc-embedded-database-support, Embedded Database Support>> and
<<data-access.adoc#jdbc-initializing-datasource, Initializing a DataSource>>, respectively.
To use the elements in the `jdbc` schema, you need to have the following preamble at the
top of your Spring XML configuration file. The text in the following snippet references

View File

@@ -26,33 +26,34 @@ management that delivers the following benefits:
* A consistent programming model across different transaction APIs, such as Java
Transaction API (JTA), JDBC, Hibernate, and the Java Persistence API (JPA).
* Support for <<transaction-declarative,declarative transaction management>>.
* A simpler API for <<transaction-programmatic,programmatic>> transaction management than
complex transaction APIs, such as JTA.
* Support for <<transaction-declarative, declarative transaction management>>.
* A simpler API for <<transaction-programmatic, programmatic>> transaction management
than complex transaction APIs, such as JTA.
* Excellent integration with Spring's data access abstractions.
The following sections describe the Spring Framework's transaction features and
technologies:
* <<transaction-motivation,Advantages of the Spring Framework's transaction support
* <<transaction-motivation, Advantages of the Spring Framework's transaction support
model>> describes why you would use the Spring Framework's transaction abstraction
instead of EJB Container-Managed Transactions (CMT) or choosing to drive local
transactions through a proprietary API, such as Hibernate.
* <<transaction-strategies,Understanding the Spring Framework transaction abstraction>>
* <<transaction-strategies, Understanding the Spring Framework transaction abstraction>>
outlines the core classes and describes how to configure and obtain `DataSource`
instances from a variety of sources.
* <<tx-resource-synchronization,Synchronizing resources with transactions>> describes
* <<tx-resource-synchronization, Synchronizing resources with transactions>> describes
how the application code ensures that resources are created, reused, and cleaned up
properly.
* <<transaction-declarative,Declarative transaction management>> describes support for
* <<transaction-declarative, Declarative transaction management>> describes support for
declarative transaction management.
* <<transaction-programmatic,Programmatic transaction management>> covers support for
* <<transaction-programmatic, Programmatic transaction management>> covers support for
programmatic (that is, explicitly coded) transaction management.
* <<transaction-event,Transaction bound event>> describes how you could use application
* <<transaction-event, Transaction bound event>> describes how you could use application
events within a transaction.
(The chapter also includes discussions of best practices, <<transaction-application-server-integration,application
server integration>>, and <<transaction-solutions-to-common-problems,solutions to common problems>>.)
The chapter also includes discussions of best practices,
<<transaction-application-server-integration, application server integration>>,
and <<transaction-solutions-to-common-problems, solutions to common problems>>.
@@ -169,7 +170,7 @@ strategy. A transaction strategy is defined by the
====
This is primarily a service provider interface (SPI), although you can use it
<<transaction-programmatic-ptm,programmatically>> from your application code. Because
<<transaction-programmatic-ptm, programmatically>> from your application code. Because
`PlatformTransactionManager` is an interface, it can be easily mocked or stubbed as
necessary. It is not tied to a lookup strategy, such as JNDI.
`PlatformTransactionManager` implementations are defined like any other object (or bean)
@@ -311,8 +312,8 @@ The `JtaTransactionManager` does not need to know about the `DataSource` (or any
specific resources) because it uses the container's global transaction management
infrastructure.
NOTE: The preceding definition of the `dataSource` bean uses the `<jndi-lookup/>` tag from the
`jee` namespace. For more information see
NOTE: The preceding definition of the `dataSource` bean uses the `<jndi-lookup/>` tag
from the `jee` namespace. For more information see
<<integration.adoc#xsd-schemas-jee, The JEE Schema>>.
You can also use easily Hibernate local transactions, as shown in the following
@@ -322,9 +323,9 @@ which your application code can use to obtain Hibernate `Session` instances.
The `DataSource` bean definition is similar to the local JDBC example shown
previously and, thus, is not shown in the following example.
NOTE: If the `DataSource` (used by any non-JTA transaction manager) is looked up through JNDI and
managed by a Java EE container, it should be non-transactional, because the Spring
Framework (rather than the Java EE container) manages the transactions.
NOTE: If the `DataSource` (used by any non-JTA transaction manager) is looked up through
JNDI and managed by a Java EE container, it should be non-transactional, because the
Spring Framework (rather than the Java EE container) manages the transactions.
The `txManager` bean in this case is of the `HibernateTransactionManager` type. In the
same way as the `DataSourceTransactionManager` needs a reference to the `DataSource`,
@@ -486,7 +487,7 @@ necessary. The differences between the two types of transaction management are:
* You can apply the Spring Framework declarative transaction management to any class,
not merely special classes such as EJBs.
* The Spring Framework offers declarative
<<transaction-declarative-rolling-back,rollback rules>>, a feature with no EJB
<<transaction-declarative-rolling-back, rollback rules>>, a feature with no EJB
equivalent. Both programmatic and declarative support for rollback rules is provided.
* The Spring Framework lets you customize transactional behavior by using AOP.
For example, you can insert custom behavior in the case of transaction rollback. You
@@ -498,16 +499,6 @@ necessary. The differences between the two types of transaction management are:
recommend that you use EJB. However, consider carefully before using such a feature,
because, normally, one does not want transactions to span remote calls.
.Where is TransactionProxyFactoryBean?
****
Declarative transaction configuration in versions of Spring 2.0 and above differs
considerably from previous versions of Spring. The main difference is that there is no
longer any need to configure `TransactionProxyFactoryBean` beans.
The pre-Spring 2.0 configuration style is still 100% valid configuration. Think of the
new `<tx:tags/>` as defining `TransactionProxyFactoryBean` beans on your behalf.
****
The concept of rollback rules is important. They let you specify which exceptions
(and throwables) should cause automatic rollback. You can specify this declaratively, in
configuration, not in Java code. So, although you can still call `setRollbackOnly()` on
@@ -536,7 +527,7 @@ transaction infrastructure in the event of transaction-related issues.
The most important concepts to grasp with regard to the Spring Framework's declarative
transaction support are that this support is enabled
<<core.adoc#aop-understanding-aop-proxies,via AOP proxies>> and that the transactional
<<core.adoc#aop-understanding-aop-proxies, via AOP proxies>> and that the transactional
advice is driven by metadata (currently XML- or annotation-based). The combination of
AOP with transactional metadata yields an AOP proxy that uses a `TransactionInterceptor`
in conjunction with an appropriate `PlatformTransactionManager` implementation to drive
@@ -693,13 +684,14 @@ attribute explicitly, as in the preceding example.
The `<aop:config/>` definition ensures that the transactional advice defined by the
`txAdvice` bean executes at the appropriate points in the program. First, you define a
pointcut that matches the execution of any operation defined in the `FooService`
interface ( `fooServiceOperation`). Then you associate the pointcut with the `txAdvice`
by using an advisor. The result indicates that, at the execution of a `fooServiceOperation`,
pointcut that matches the execution of any operation defined in the `FooService` interface
(`fooServiceOperation`). Then you associate the pointcut with the `txAdvice` by using an
advisor. The result indicates that, at the execution of a `fooServiceOperation`,
the advice defined by `txAdvice` is run.
The expression defined within the `<aop:pointcut/>` element is an AspectJ pointcut
expression. See <<core.adoc#aop, the AOP section>> for more details on pointcut expressions in Spring.
expression. See <<core.adoc#aop, the AOP section>> for more details on pointcut
expressions in Spring.
A common requirement is to make an entire service layer transactional. The best way to
do this is to change the pointcut expression to match any operation in your
@@ -716,18 +708,18 @@ service layer. The following example shows how to do so:
----
====
NOTE: In the preceding example, it is assumed that all your service interfaces are defined in the
`x.y.service` package. See <<core.adoc#aop, the AOP section>> for more details.
NOTE: In the preceding example, it is assumed that all your service interfaces are defined
in the `x.y.service` package. See <<core.adoc#aop, the AOP section>> for more details.
Now that we have analyzed the configuration, you may be asking yourself,
"`What does all this configuration actually do?`"
The configuration shown earlier is used to create a transactional proxy around the object
that is created from the `fooService` bean definition. The proxy is configured with
the transactional advice so that, when an appropriate method is invoked on the
proxy, a transaction is started, suspended, marked as read-only, and so on, depending
on the transaction configuration associated with that method. Consider the following
program that test drives the configuration shown earlier:
the transactional advice so that, when an appropriate method is invoked on the proxy,
a transaction is started, suspended, marked as read-only, and so on, depending on the
transaction configuration associated with that method. Consider the following program
that test drives the configuration shown earlier:
====
[source,java,indent=0]
@@ -1007,7 +999,7 @@ transactional settings:
This section summarizes the various transactional settings that you can specify by using
the `<tx:advice/>` tag. The default `<tx:advice/>` settings are:
* The <<tx-propagation,propagation setting>> is `REQUIRED.`
* The <<tx-propagation, propagation setting>> is `REQUIRED.`
* The isolation level is `DEFAULT.`
* The transaction is read-write.
* The transaction timeout defaults to the default timeout of the underlying transaction
@@ -1225,7 +1217,7 @@ modified) to turn `@Transactional` into runtime behavior on any kind of method.
for classes annotated with the `@Transactional` annotation. If the
`proxy-target-class` attribute is set to `true`, class-based proxies are created.
If `proxy-target-class` is `false` or if the attribute is omitted, then standard JDK
interface-based proxies are created. (See <<core.adoc#aop-proxying, Proxying mechanisms>>
interface-based proxies are created. (See <<core.adoc#aop-proxying, Proxying Mechanisms>>
for a detailed examination of the different proxy types.)
| `order`
@@ -1233,7 +1225,7 @@ modified) to turn `@Transactional` into runtime behavior on any kind of method.
| `Ordered.LOWEST_PRECEDENCE`
| Defines the order of the transaction advice that is applied to beans annotated with
`@Transactional`. (For more information about the rules related to ordering of AOP
advice, see <<core.adoc#aop-ataspectj-advice-ordering,Advice Ordering>>.)
advice, see <<core.adoc#aop-ataspectj-advice-ordering, Advice Ordering>>.)
No specified ordering means that the AOP subsystem determines the order of the advice.
|===
@@ -1404,7 +1396,7 @@ specifically qualified `PlatformTransactionManager` bean is found.
===== Custom Shortcut Annotations
If you find you repeatedly use the same attributes with `@Transactional` on many different
methods, <<core.adoc#beans-meta-annotations,Spring's meta-annotation support>> lets you
methods, <<core.adoc#beans-meta-annotations, Spring's meta-annotation support>> lets you
define custom shortcut annotations for your specific use cases. For example, consider the
following annotation definitions:
@@ -2588,7 +2580,7 @@ The following example invokes a stored procedure:
----
====
More sophisticated stored procedure support is <<jdbc-StoredProcedure,covered later>>.
More sophisticated stored procedure support is <<jdbc-StoredProcedure, covered later>>.
[[jdbc-JdbcTemplate-idioms]]
===== `JdbcTemplate` Best Practices
@@ -2600,7 +2592,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
<<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`. This leads to DAOs that resemble the following:
@@ -3911,7 +3903,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 <<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
@@ -4901,12 +4893,12 @@ call the `setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.DERBY
Embedded databases provide a lightweight way to test data access code. The next example is a
data access integration test template that uses an embedded database. Using such a template
can be useful for one-offs when the embedded database does not need to be
reused across test classes. However, if you wish to create an embedded database that is
shared within a test suite, consider using the <<testing.adoc#testcontext-framework,Spring TestContext
Framework>> and configuring the embedded database as a bean in the Spring
`ApplicationContext` as described in <<jdbc-embedded-database-xml>> and
<<jdbc-embedded-database-java>>. The following listing shows the test template:
can be useful for one-offs when the embedded database does not need to be reused across test
classes. However, if you wish to create an embedded database that is shared within a test suite,
consider using the <<testing.adoc#testcontext-framework, Spring TestContext Framework>> and
configuring the embedded database as a bean in the Spring `ApplicationContext` as described
in <<jdbc-embedded-database-xml>> and <<jdbc-embedded-database-java>>. The following listing
shows the test template:
====
[source,java,indent=0]
@@ -5202,14 +5194,13 @@ The benefits of using the Spring Framework to create your ORM DAOs include:
aspect-oriented programming (AOP) style method interceptor either through the
`@Transactional` annotation or by explicitly configuring the transaction AOP advice in
an XML configuration file. In both cases, transaction semantics and exception handling
(rollback and so on) are handled for you. As discussed in
<<orm-resource-mngmnt>>, you can also swap various
transaction managers, without affecting your ORM-related code. For example, you can
swap between local transactions and JTA, with the same full services (such as
declarative transactions) available in both scenarios. Additionally, JDBC-related code
can fully integrate transactionally with the code you use to do ORM. This is useful
for data access that is not suitable for ORM (such as batch processing and BLOB
streaming) but that still needs to share common transactions with ORM operations.
(rollback and so on) are handled for you. As discussed in <<orm-resource-mngmnt>>,
you can also swap various transaction managers, without affecting your ORM-related code.
For example, you can swap between local transactions and JTA, with the same full services
(such as declarative transactions) available in both scenarios. Additionally,
JDBC-related code can fully integrate transactionally with the code you use to do ORM.
This is useful for data access that is not suitable for ORM (such as batch processing and
BLOB streaming) but that still needs to share common transactions with ORM operations.
TIP: For more comprehensive ORM support, including support for alternative database
technologies such as MongoDB, you might want to check out the
@@ -5222,8 +5213,8 @@ Data with JPA] guide from https://spring.io provides a great introduction.
[[orm-general]]
=== General ORM Integration Considerations
This section highlights considerations that apply to all ORM technologies. The
<<orm-hibernate>> section provides more details and also show these features and
This section highlights considerations that apply to all ORM technologies.
The <<orm-hibernate>> section provides more details and also show these features and
configurations in a concrete context.
The major goal of Spring's ORM integration is clear application layering (with any data
@@ -5252,10 +5243,11 @@ interceptors for the ORM technologies.
The infrastructure provides proper resource handling and appropriate conversion of
specific API exceptions to an unchecked infrastructure exception hierarchy. Spring
introduces a DAO exception hierarchy, applicable to any data access strategy. For direct
JDBC, the `JdbcTemplate` class mentioned in a <<jdbc-JdbcTemplate,previous section>> 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 <<orm-exception-translation,next section>> for how to get the same exception
JDBC, the `JdbcTemplate` class mentioned in a <<jdbc-JdbcTemplate, previous section>>
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
<<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
@@ -5342,7 +5334,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 <<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:
@@ -5410,7 +5402,7 @@ property. On the programmatic `LocalSessionFactoryBuilder`, there is an overload
As of Spring Framework 5.1, such a native Hibernate setup can also expose a JPA
`EntityManagerFactory` for standard JPA interaction next to native Hibernate access.
See <<orm-jpa-hibernate,Native Hibernate Setup for JPA>> for details.
See <<orm-jpa-hibernate, Native Hibernate Setup for JPA>> for details.
====
@@ -5898,7 +5890,7 @@ NOTE: If you want to specifically configure a Hibernate setup, an immediate alte
to go with Hibernate 5.2 or 5.3 and set up a native Hibernate `LocalSessionFactoryBean`
instead of a plain JPA `LocalContainerEntityManagerFactoryBean`, letting it interact
with JPA access code as well as native Hibernate access code.
See <<orm-jpa-hibernate,Native Hibernate setup for JPA interaction>> for details.
See <<orm-jpa-hibernate, Native Hibernate setup for JPA interaction>> for details.
The `LocalContainerEntityManagerFactoryBean` gives full control over
`EntityManagerFactory` configuration and is appropriate for environments where
@@ -5984,18 +5976,17 @@ Spring provides a number of `LoadTimeWeaver` implementations for various environ
letting `ClassTransformer` instances be applied only for each class loader and not
for each VM.
See <<core.adoc#aop-aj-ltw-spring,Spring configuration>> in the AOP chapter for
See the <<core.adoc#aop-aj-ltw-spring, Spring configuration>> in the AOP chapter for
more insight regarding the `LoadTimeWeaver` implementations and their setup, either
generic or customized to various platforms (such as Tomcat, WebLogic, GlassFish,
Resin, and JBoss).
generic or customized to various platforms (such as Tomcat, JBoss and WebSphere).
As described in <<core.adoc#aop-aj-ltw-spring,Spring configuration>>, you can configure a context-wide
`LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation of the
`context:load-time-weaver` XML element. Such a global weaver is automatically picked up by all JPA
`LocalContainerEntityManagerFactoryBean` instances. The following example shows the preferred way of
setting up a load-time weaver, delivering auto-detection of the platform (WebLogic,
GlassFish, Tomcat, Resin, JBoss, or VM agent) and automatic propagation of the weaver to
all weaver-aware beans:
As described in <<core.adoc#aop-aj-ltw-spring, Spring configuration>>, you can configure
a context-wide `LoadTimeWeaver` by using the `@EnableLoadTimeWeaving` annotation of the
`context:load-time-weaver` XML element. Such a global weaver is automatically picked u
by all JPA `LocalContainerEntityManagerFactoryBean` instances. The following example
shows the preferred way of setting up a load-time weaver, delivering auto-detection
of the platform (e.g. Tomcat's weaving-capable class loader or Spring's JVM agent)
and automatic propagation of the weaver to all weaver-aware beans:
====
[source,xml,indent=0]
@@ -6237,8 +6228,8 @@ Even though the new DAO implementation uses method-level
injection of an `EntityManager` instead of an `EntityManagerFactory`, no change is
required in the application context XML, due to annotation usage.
The main advantage of this DAO style is that it depends only on the Java Persistence API. No
import of any Spring class is required. Moreover, as the JPA annotations are understood,
The main advantage of this DAO style is that it depends only on the Java Persistence API.
No import of any Spring class is required. Moreover, as the JPA annotations are understood,
the injections are applied automatically by the Spring container. This is appealing from
a non-invasiveness perspective and can feel more natural to JPA developers.
@@ -6246,8 +6237,8 @@ a non-invasiveness perspective and can feel more natural to JPA developers.
[[orm-jpa-tx]]
==== Spring-driven JPA transactions
NOTE: We strongly encourage you to read <<transaction-declarative>>, if you have not already done
so, to get more detailed coverage of Spring's declarative transaction support.
NOTE: We strongly encourage you to read <<transaction-declarative>>, if you have not
already done so, to get more detailed coverage of Spring's declarative transaction support.
The recommended strategy for JPA is local transactions through JPA's native transaction
support. Spring's `JpaTransactionManager` provides many capabilities known from local
@@ -6258,13 +6249,13 @@ 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 <<orm-jpa-dialect,next section>> for details on the `JpaDialect` mechanism.
See the <<orm-jpa-dialect, next section>> for details on the `JpaDialect` mechanism.
NOTE: As an immediate alternative, Spring's native `HibernateTransactionManager` is capable
of interacting with JPA access code as of Spring Framework 5.1 and Hibernate 5.2/5.3,
adapting to several Hibernate specifics and providing JDBC interaction.
This makes particular sense in combination with `LocalSessionFactoryBean` setup.
See <<orm-jpa-hibernate,Native Hibernate Setup for JPA Interaction>> for details.
See <<orm-jpa-hibernate, Native Hibernate Setup for JPA Interaction>> for details.
[[orm-jpa-dialect]]
@@ -6361,7 +6352,7 @@ seamlessly integrating with `@Bean` style configuration (no `FactoryBean` involv
====
`LocalSessionFactoryBean` and `LocalSessionFactoryBuilder` support background
bootstrapping, just as the JPA `LocalContainerEntityManagerFactoryBean` does.
See <<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
@@ -6430,8 +6421,8 @@ These runtime exceptions wrap the original exception so that no information is l
[[oxm-marshaller-unmarshaller]]
=== `Marshaller` and `Unmarshaller`
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
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.

View File

@@ -3,23 +3,23 @@
:api-spring-framework: {doc-root}/spring-framework/docs/{spring-version}/javadoc-api/org/springframework
****
_What's New_, _Upgrade Notes_, _Supported Versions_, and other topics, independent of
release cadence, are maintained externaly on the project's
_What's New_, _Upgrade Notes_, _Supported Versions_, and other topics,
independent of release cadence, are maintained externaly on the project's
https://github.com/spring-projects/spring-framework/wiki[*Github Wiki*].
****
[horizontal]
<<overview.adoc#overview,Overview>> :: history, design philosophy,feedback,
<<overview.adoc#overview, Overview>> :: history, design philosophy,feedback,
getting started.
<<core.adoc#spring-core,Core>> :: IoC container, Events, Resources, i18n, Validation,
<<core.adoc#spring-core, Core>> :: IoC container, Events, Resources, i18n, Validation,
Data Binding, Type Conversion, SpEL, AOP.
<<testing.adoc#testing,Testing>> :: Mock objects, TestContext framework,
<<testing.adoc#testing, Testing>> :: Mock objects, TestContext framework,
Spring MVC Test, WebTestClient.
<<data-access.adoc#spring-data-tier,Data Access>> :: Transactions, DAO support, JDBC,
<<data-access.adoc#spring-data-tier, Data Access>> :: Transactions, DAO support, JDBC,
ORM, Marshalling XML.
<<web.adoc#spring-web,Web Servlet>> :: Spring MVC, WebSocket, SockJS, STOMP messaging.
<<web-reactive.adoc#spring-webflux,Web Reactive>> :: Spring WebFlux,
<<web.adoc#spring-web, Web Servlet>> :: Spring MVC, WebSocket, SockJS, STOMP messaging.
<<web-reactive.adoc#spring-webflux, Web Reactive>> :: Spring WebFlux,
WebClient, WebSocket.
<<integration.adoc#spring-integration,Integration>> :: Remoting, JMS, JCA, JMX, Email,
<<integration.adoc#spring-integration, Integration>> :: Remoting, JMS, JCA, JMX, Email,
Tasks, Scheduling, Cache.
<<languages.adoc#languages,Languages>> :: Kotlin, Groovy, Dynamic languages.
<<languages.adoc#languages, Languages>> :: Kotlin, Groovy, Dynamic languages.

View File

@@ -311,8 +311,8 @@ SessionBean with `jee`:
=== The `jms` Schema
The `jms` elements deal with configuring JMS-related beans, such as Spring's
<<integration.adoc#jms-mdp,Message Listener Containers>>. These elements are detailed in the
section of the <<integration.adoc#jms,JMS chapter>> entitled <<integration.adoc#jms-namespace,
<<integration.adoc#jms-mdp, Message Listener Containers>>. These elements are detailed in the
section of the <<integration.adoc#jms, JMS chapter>> entitled <<integration.adoc#jms-namespace,
JMS Namespace Support>>. See that chapter for full details on this support
and the `jms` elements themselves.
@@ -352,8 +352,8 @@ This element is detailed in
You can use the `cache` elements to enable support for Spring's `@CacheEvict`, `@CachePut`,
and `@Caching` annotations. It it also supports declarative XML-based caching. See
<<integration.adoc#cache-annotation-enable,Enabling Caching Annotations>> and
<<integration.adoc#cache-declarative-xml,Declarative XML-based Caching>> for details.
<<integration.adoc#cache-annotation-enable, Enabling Caching Annotations>> and
<<integration.adoc#cache-declarative-xml, Declarative XML-based Caching>> for details.
To use the elements in the `cache` schema, you need to have the following preamble at the
top of your Spring XML configuration file. The text in the following snippet references

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,20 @@
[[dynamic-language]]
= Dynamic Language Support
Spring 2.0 introduced comprehensive support for using classes and objects that have been
defined by using a dynamic language (such as JRuby) with Spring. This support lets you
write any number of classes in a supported dynamic language and have the Spring
Spring provides comprehensive support for using classes and objects that have been
defined by using a dynamic language (such as Groovy) with Spring. This support lets
you write any number of classes in a supported dynamic language and have the Spring
container transparently instantiate, configure, and dependency inject the resulting
objects.
Spring currently supports the following dynamic languages:
Spring's scripting support primarily targets Groovy and BeanShell. Beyond those
specifically supported languages, the JSR-223 scripting mechanism is supported
for integration with any JSR-223 capable language provider (as of Spring 4.2),
e.g. JRuby.
* JRuby 1.5+
* Groovy 1.8+
* BeanShell 2.0
You can find fully working examples of where this dynamic language support can be
immediately useful in <<dynamic-language-scenarios>>.
.Why only these languages?
****
We chose to support these languages because:
* The languages have a lot of traction in the Java enterprise community.
* No requests were made for other languages at the time that this support was added
* The Spring developers were most familiar with them.
****
You can find fully working examples of where this dynamic language support can be immediately useful
in <<dynamic-language-scenarios>>.
@@ -37,9 +28,9 @@ language for this first bean is Groovy. (The basis of this example was taken fro
Spring test suite. If you want to see equivalent examples in any of the other
supported languages, take a look at the source code).
The next example shows the `Messenger` interface, which the Groovy bean is going to implement.
Note that this interface is defined in plain Java. Dependent objects that are
injected with a reference to the `Messenger` do not know that the underlying
The next example shows the `Messenger` interface, which the Groovy bean is going to
implement. Note that this interface is defined in plain Java. Dependent objects that
are injected with a reference to the `Messenger` do not know that the underlying
implementation is a Groovy script. The following listing shows the `Messenger` interface:
====
@@ -51,7 +42,6 @@ implementation is a Groovy script. The following listing shows the `Messenger` i
public interface Messenger {
String getMessage();
}
----
====
@@ -75,7 +65,6 @@ The following example defines a class that has a dependency on the `Messenger` i
public void processBooking() {
// use the injected Messenger object...
}
}
----
====
@@ -96,7 +85,6 @@ The following example implements the `Messenger` interface in Groovy:
class GroovyMessenger implements Messenger {
String message
}
----
====
@@ -111,7 +99,7 @@ implementation is supported, but you have to manage the plumbing of the Spring i
to do so.
For more information on schema-based configuration, see <<appendix.adoc#xsd-configuration,
XML Schema-based configuration>>.
XML Schema-based Configuration>>.
====
Finally, the following example shows the bean definitions that effect the injection of the
@@ -143,14 +131,14 @@ Groovy-defined `Messenger` implementation into an instance of the
----
====
The `bookingService` bean (a `DefaultBookingService`) can now use its private
`messenger` member variable as normal, because the `Messenger` instance that was injected
into it is a `Messenger` instance. There is nothing special going on here -- just
plain Java and plain Groovy.
The `bookingService` bean (a `DefaultBookingService`) can now use its private `messenger`
member variable as normal, because the `Messenger` instance that was injected into it is
a `Messenger` instance. There is nothing special going on here -- just plain Java and
plain Groovy.
Hopefully, the preceding XML snippet is self-explanatory, but do not worry unduly if it is not.
Keep reading for the in-depth detail on the whys and wherefores of the preceding
configuration.
Keep reading for the in-depth detail on the whys and wherefores of the preceding configuration.
@@ -160,11 +148,11 @@ configuration.
This section describes exactly how you define Spring-managed beans in any of the
supported dynamic languages.
Note that this chapter does not attempt to explain the syntax and idioms of the
supported dynamic languages. For example, if you want to use Groovy to write certain of
the classes in your application, we assume that you already know Groovy. If
you need further details about the dynamic languages themselves, see
<<dynamic-language-resources>> at the end of this chapter.
Note that this chapter does not attempt to explain the syntax and idioms of the supported
dynamic languages. For example, if you want to use Groovy to write certain of the classes
in your application, we assume that you already know Groovy. If you need further details
about the dynamic languages themselves, see <<dynamic-language-resources>> at the end of
this chapter.
@@ -191,45 +179,43 @@ Spring's dynamic language support does make some (small) assumptions about the c
of your dynamic language source files.
[[dynamic-language-beans-concepts-xml-language-element]]
==== The <lang:language/> element
The final step in the list in the <<dynamic-language-beans-concepts,preceding section>> involves defining dynamic-language-backed bean definitions, one for each
bean that you want to configure (this is no different from normal JavaBean
configuration). However, instead of specifying the fully qualified classname of the
class that is to be instantiated and configured by the container, you can use the
`<lang:language/>` element to define the dynamic language-backed bean.
The final step in the list in the <<dynamic-language-beans-concepts, preceding section>>
involves defining dynamic-language-backed bean definitions, one for each bean that you
want to configure (this is no different from normal JavaBean configuration). However,
instead of specifying the fully qualified classname of the class that is to be
instantiated and configured by the container, you can use the `<lang:language/>`
element to define the dynamic language-backed bean.
Each of the supported languages has a corresponding `<lang:language/>` element:
* `<lang:groovy/>` (Groovy)
* `<lang:bsh/>` (BeanShell)
* `<lang:std/>` (JSR-223)
* `<lang:std/>` (JSR-223, e.g. with JRuby)
The exact attributes and child elements that are available for configuration depends on
exactly which language the bean has been defined in (the language-specific sections
later in this chapter detail this).
[[dynamic-language-refreshable-beans]]
==== Refreshable Beans
One of the (and perhaps the single) most compelling value adds of the dynamic language support
in Spring is the "`refreshable bean`" feature.
One of the (and perhaps the single) most compelling value adds of the dynamic language
support in Spring is the "`refreshable bean`" feature.
A refreshable bean is a dynamic-language-backed bean. With a small amount of
configuration, a dynamic-language-backed bean can monitor changes in its underlying
source file resource and then reload itself when the dynamic language source file is
changed (for example, when you edit and save changes to the file on the
file system).
changed (for example, when you edit and save changes to the file on the file system).
This lets you deploy any number of dynamic language source files as part of
an application, configure the Spring container to create beans backed by dynamic
This lets you deploy any number of dynamic language source files as part of an
application, configure the Spring container to create beans backed by dynamic
language source files (using the mechanisms described in this chapter), and (later,
as requirements change or some other external factor comes into play) edit a
dynamic language source file and have any change they make be reflected in the bean that is
as requirements change or some other external factor comes into play) edit a dynamic
language source file and have any change they make be reflected in the bean that is
backed by the changed dynamic language source file. There is no need to shut down a
running application (or redeploy in the case of a web application). The
dynamic-language-backed bean so amended picks up the new state and logic from the
@@ -238,11 +224,11 @@ changed dynamic language source file.
NOTE: This feature is off by default.
Now we can take a look at an example to see how easy it is to start using refreshable
beans. To turn on the refreshable beans feature, you have to specify exactly
one additional attribute on the `<lang:language/>` element of your bean definition.
So, if we stick with <<dynamic-language-a-first-example,the example>> from earlier in this
chapter, the following example shows what we would change in the Spring XML configuration to effect
refreshable beans:
beans. To turn on the refreshable beans feature, you have to specify exactly one
additional attribute on the `<lang:language/>` element of your bean definition. So,
if we stick with <<dynamic-language-a-first-example, the example>> from earlier in
this chapter, the following example shows what we would change in the Spring XML
configuration to effect refreshable beans:
====
[source,xml,indent=0]
@@ -267,17 +253,17 @@ refreshable beans:
That really is all you have to do. The `refresh-check-delay` attribute defined on the
`messenger` bean definition is the number of milliseconds after which the bean is
refreshed with any changes made to the underlying dynamic language source file. You can
turn off the refresh behavior by assigning a negative value to the
refreshed with any changes made to the underlying dynamic language source file.
You can turn off the refresh behavior by assigning a negative value to the
`refresh-check-delay` attribute. Remember that, by default, the refresh behavior is
disabled. If you do not want the refresh behavior, do not define the attribute.
If we then run the following application, we can exercise the refreshable feature (Please
do excuse the "`jumping-through-hoops-to-pause-the-execution`" shenanigans in this
next slice of code.) The `System.in.read()` call is only there so that the execution of
the program pauses while you (the developer in this scenario) go off and edit the underlying dynamic language
source file so that the refresh triggers on the dynamic-language-backed bean when
the program resumes execution.
If we then run the following application, we can exercise the refreshable feature.
(Please excuse the "`jumping-through-hoops-to-pause-the-execution`" shenanigans
in this next slice of code.) The `System.in.read()` call is only there so that the
execution of the program pauses while you (the developer in this scenario) go off
and edit the underlying dynamic language source file so that the refresh triggers
on the dynamic-language-backed bean when the program resumes execution.
The following listing shows this sample application:
@@ -303,10 +289,11 @@ The following listing shows this sample application:
----
====
Assume then, for the purposes of this example, that all calls to the
`getMessage()` method of `Messenger` implementations have to be changed such that the
message is surrounded by quotation marks. The following listing shows the changes that you (the developer) should make to the
`Messenger.groovy` source file when the execution of the program is paused:
Assume then, for the purposes of this example, that all calls to the `getMessage()`
method of `Messenger` implementations have to be changed such that the message is
surrounded by quotation marks. The following listing shows the changes that you
(the developer) should make to the `Messenger.groovy` source file when the
execution of the program is paused:
====
[source,java,indent=0]
@@ -330,15 +317,14 @@ message is surrounded by quotation marks. The following listing shows the change
----
====
When the program runs, the output before the input pause will be `I Can Do The
Frug`. After the change to the source file is made and saved and the program resumes
execution, the result of calling the `getMessage()` method on the
dynamic-language-backed `Messenger` implementation is `'I Can Do The Frug'`
(notice the inclusion of the additional quotation marks).
When the program runs, the output before the input pause will be `I Can Do The Frug`.
After the change to the source file is made and saved and the program resumes execution,
the result of calling the `getMessage()` method on the dynamic-language-backed
`Messenger` implementation is `'I Can Do The Frug'` (notice the inclusion of the
additional quotation marks).
Changes to a script do not trigger a refresh if
the changes occur within the window of the `refresh-check-delay` value.
Changes to the script are not actually picked up until
Changes to a script do not trigger a refresh if the changes occur within the window of
the `refresh-check-delay` value. Changes to the script are not actually picked up until
a method is called on the dynamic-language-backed bean. It is only when a method is
called on a dynamic-language-backed bean that it checks to see if its underlying script
source has changed. Any exceptions that relate to refreshing the script (such as
@@ -353,7 +339,6 @@ that checks the last modified date of a dynamic language source file that exists
file system).
[[dynamic-language-beans-inline]]
==== Inline Dynamic Language Source Files
@@ -392,7 +377,6 @@ work using inline source. (See <<dynamic-language-scenarios-validators>> for suc
example.)
[[dynamic-language-beans-ctor-injection]]
==== Understanding Constructor Injection in the Context of Dynamic-language-backed Beans
@@ -425,7 +409,6 @@ does not work:
String message
String anotherMessage
}
----
@@ -456,17 +439,6 @@ injection is the injection style favored by the overwhelming majority of develop
This section describes how to use beans defined in Groovy in Spring.
.The Groovy library dependencies
****
The Groovy scripting support in Spring requires the following libraries to be on the
classpath of your application:
* `groovy-1.8.jar`
* `asm-3.2.jar`
* `antlr-2.7.7.jar`
****
The Groovy homepage includes the following description:
"`Groovy is an agile dynamic language for the Java 2 Platform that has many of the
@@ -474,7 +446,7 @@ features that people like so much in languages like Python, Ruby and Smalltalk,
them available to Java developers using a Java-like syntax.`"
If you have read this chapter straight from the top, you have already
<<dynamic-language-a-first-example,seen an example>> of a Groovy-dynamic-language-backed
<<dynamic-language-a-first-example, seen an example>> of a Groovy-dynamic-language-backed
bean. Now consider another example (again using an example from the Spring test suite):
====
@@ -486,7 +458,6 @@ bean. Now consider another example (again using an example from the Spring test
public interface Calculator {
int add(int x, int y);
}
----
====
@@ -505,7 +476,6 @@ The following example implements the `Calculator` interface in Groovy:
int add(int x, int y) {
x + y
}
}
----
====
@@ -546,15 +516,13 @@ Finally, the following small application exercises the preceding configuration:
====
The resulting output from running the above program is (unsurprisingly) `10`.
(For more interesting examples,
see the dynamic language showcase project for a more complex example or see the examples
<<dynamic-language-scenarios>> later in this chapter).
You must not define more than one class per Groovy source file.
While this is perfectly legal in Groovy, it is (arguably) a bad practice. In the
interests of a consistent approach, you should (in the opinion of the Spring team) respect
the standard Java conventions of one (public) class per source file.
(For more interesting examples, see the dynamic language showcase project for a more
complex example or see the examples <<dynamic-language-scenarios>> later in this chapter).
You must not define more than one class per Groovy source file. While this is perfectly
legal in Groovy, it is (arguably) a bad practice. In the interests of a consistent
approach, you should (in the opinion of the Spring team) respect the standard Java
conventions of one (public) class per source file.
[[dynamic-language-beans-groovy-customizer]]
@@ -577,11 +545,11 @@ shows the `GroovyObjectCustomizer` interface definition:
----
====
The Spring Framework instantiates an instance of your Groovy-backed bean and
then passes the created `GroovyObject` to the specified `GroovyObjectCustomizer` (if one
The Spring Framework instantiates an instance of your Groovy-backed bean and then
passes the created `GroovyObject` to the specified `GroovyObjectCustomizer` (if one
has been defined). You can do whatever you like with the supplied `GroovyObject`
reference. We expect that most people want to set a custom `MetaClass` with this callback,
and the following example shows how to do so:
reference. We expect that most people want to set a custom `MetaClass` with this
callback, and the following example shows how to do so:
====
[source,java,indent=0]
@@ -607,8 +575,8 @@ and the following example shows how to do so:
A full discussion of meta-programming in Groovy is beyond the scope of the Spring
reference manual. See the relevant section of the Groovy reference manual or do a
search online. Plenty of articles address this topic. Actually, making use
of a `GroovyObjectCustomizer` is easy if you use the Spring namespace support, as the
search online. Plenty of articles address this topic. Actually, making use of a
`GroovyObjectCustomizer` is easy if you use the Spring namespace support, as the
following example shows:
====
@@ -655,15 +623,6 @@ in the same place as Spring's `GroovyObjectCustomizer`.
This section describes how to use BeanShell beans in Spring.
.The BeanShell library dependencies
****
The BeanShell scripting support in Spring requires the following libraries to be on the
classpath of your application:
* `bsh-2.0b4.jar`
****
The BeanShell homepage includes the following description: {JB}
"`BeanShell is a small, free, embeddable Java source interpreter with dynamic language
@@ -673,12 +632,12 @@ closures like those in Perl and JavaScript.`"
In contrast to Groovy, BeanShell-backed bean definitions require some (small) additional
configuration. The implementation of the BeanShell dynamic language support in Spring is
interesting, because Spring creates a JDK dynamic proxy
that implements all of the interfaces that are specified in the `script-interfaces`
attribute value of the `<lang:bsh>` element (this is why you must supply at least
one interface in the value of the attribute, and, consequently, program to interfaces
when you use BeanShell-backed beans). This means that every method call on a
BeanShell-backed object goes through the JDK dynamic proxy invocation mechanism.
interesting, because Spring creates a JDK dynamic proxy that implements all of the
interfaces that are specified in the `script-interfaces` attribute value of the
`<lang:bsh>` element (this is why you must supply at least one interface in the value
of the attribute, and, consequently, program to interfaces when you use BeanShell-backed
beans). This means that every method call on a BeanShell-backed object goes through the
JDK dynamic proxy invocation mechanism.
Now we can show a fully working example of using a BeanShell-based bean that implements
the `Messenger` interface that was defined earlier in this chapter. We again show the
@@ -693,13 +652,12 @@ definition of the `Messenger` interface:
public interface Messenger {
String getMessage();
}
----
====
The following example shows the BeanShell "`implementation`" (we use the term loosely here) of the
`Messenger` interface:
The following example shows the BeanShell "`implementation`" (we use the term loosely here)
of the `Messenger` interface:
====
[source,java,indent=0]
@@ -717,8 +675,8 @@ The following example shows the BeanShell "`implementation`" (we use the term lo
----
====
The following example shows the Spring XML that defines an "`instance`" of the above "`class`" (again,
we use these terms very loosely here):
The following example shows the Spring XML that defines an "`instance`" of the above
"`class`" (again, we use these terms very loosely here):
====
[source,xml,indent=0]
@@ -737,12 +695,13 @@ BeanShell-based beans.
[[dynamic-language-scenarios]]
== Scenarios
The possible scenarios where defining Spring managed beans in a scripting language would
be beneficial are many and varied. This section describes two possible use
cases for the dynamic language support in Spring.
be beneficial are many and varied. This section describes two possible use cases for the
dynamic language support in Spring.
@@ -796,7 +755,6 @@ by using the Groovy dynamic language:
HttpServletResponse httpServletResponse) {
return new ModelAndView("tell", "fortune", this.fortuneService.tellFortune())
}
}
----
@@ -826,13 +784,12 @@ validation logic by editing and saving a simple text file. Any such changes is
(depending on the configuration) automatically reflected in the execution of a
running application and would not require the restart of an application.
NOTE: To effect the automatic "`pickup`" of any changes to
dynamic-language-backed beans, you have to enable the 'refreshable beans'
feature. See <<dynamic-language-refreshable-beans>> for a full and detailed treatment of
this feature.
NOTE: To effect the automatic "`pickup`" of any changes to dynamic-language-backed
beans, you have to enable the 'refreshable beans' feature. See
<<dynamic-language-refreshable-beans>> for a full and detailed treatment of this feature.
The following example shows a Spring `org.springframework.validation.Validator` implemented
by using the Groovy dynamic language (see <<core.adoc#validator,
The following example shows a Spring `org.springframework.validation.Validator`
implemented by using the Groovy dynamic language (see <<core.adoc#validator,
Validation using Springs Validator interface>> for a discussion of the
`Validator` interface):
@@ -856,13 +813,13 @@ Validation using Springs Validator interface>> for a discussion of the
}
errors.reject("whitespace", "Cannot be composed wholly of whitespace.")
}
}
----
====
[[dynamic-language-final-notes]]
== Additional Details
@@ -876,14 +833,12 @@ This last section contains some additional details related to the dynamic langua
You can use the Spring AOP framework to advise scripted beans. The Spring AOP
framework actually is unaware that a bean that is being advised might be a scripted
bean, so all of the AOP use cases and functionality that you use (or aim to use)
work with scripted beans.
When you advise scripted beans, you cannot use class-based proxies. You must
use <<core.adoc#aop-proxying,interface-based proxies>>.
work with scripted beans. When you advise scripted beans, you cannot use class-based
proxies. You must use <<core.adoc#aop-proxying, interface-based proxies>>.
You are not limited to advising scripted beans. You can also write
aspects themselves in a supported dynamic language and use such beans to advise other
Spring beans. This really would be an advanced use of the dynamic language support
though.
You are not limited to advising scripted beans. You can also write aspects themselves
in a supported dynamic language and use such beans to advise other Spring beans.
This really would be an advanced use of the dynamic language support though.
@@ -893,11 +848,11 @@ though.
In case it is not immediately obvious, scripted beans can be scoped in the same way as
any other bean. The `scope` attribute on the various `<lang:language/>` elements lets
you control the scope of the underlying scripted bean, as it does with a regular
bean. (The default scope is <<core.adoc#beans-factory-scopes-singleton,singleton>>, as it is
with "`regular`" beans.)
bean. (The default scope is <<core.adoc#beans-factory-scopes-singleton, singleton>>,
as it is with "`regular`" beans.)
The following example uses the `scope` attribute to define a Groovy bean scoped as
a <<core.adoc#beans-factory-scopes-prototype,prototype>>:
a <<core.adoc#beans-factory-scopes-prototype, prototype>>:
====
[source,xml,indent=0]
@@ -922,26 +877,24 @@ a <<core.adoc#beans-factory-scopes-prototype,prototype>>:
----
====
See <<core.adoc#beans-factory-scopes,Bean scopes>> in <<core.adoc#beans,The IoC container>>
See <<core.adoc#beans-factory-scopes, Bean Scopes>> in <<core.adoc#beans, The IoC Container>>
for a full discussion of the scoping support in the Spring Framework.
[[xsd-schemas-lang]]
=== The `lang` XML schema
The `lang` elements in Spring XML configuration deal with exposing objects that have been written
in a dynamic language (such as JRuby or Groovy) as beans in the Spring container.
The `lang` elements in Spring XML configuration deal with exposing objects that have been
written in a dynamic language (such as Groovy or BeanShell) as beans in the Spring container.
These elements (and the dynamic language support) are comprehensively covered in
<<integration.adoc#dynamic-language,Dynamic language support>>.
See that chapter for full details on this support and the `lang` elements.
<<integration.adoc#dynamic-language, Dynamic Language Support>>. See that chapter
for full details on this support and the `lang` elements.
To use the elements in the `lang` schema, you need to have
the following preamble at the top of your Spring XML configuration file. The text in the
following snippet references the correct schema so that the tags in the `lang` namespace
are available to you:
To use the elements in the `lang` schema, you need to have the following preamble at the
top of your Spring XML configuration file. The text in the following snippet references
the correct schema so that the tags in the `lang` namespace are available to you:
====
[source,xml,indent=0]
@@ -962,12 +915,13 @@ are available to you:
[[dynamic-language-resources]]
== Further Resources
The following links go to further resources about the various dynamic languages described in
this chapter:
The following links go to further resources about the various dynamic languages referenced
in this chapter:
* The http://jruby.org/[JRuby] homepage
* The http://www.groovy-lang.org/[Groovy] homepage
* The http://www.beanshell.org/[BeanShell] homepage
* The http://jruby.org/[JRuby] homepage

View File

@@ -7,7 +7,7 @@ existing Java application.
The Spring Framework provides a dedicated `ApplicationContext` that supports a Groovy-based
Bean Definition DSL. For more details, see
<<core.adoc#groovy-bean-definition-dsl,The Groovy Bean Definition DSL>>.
<<core.adoc#groovy-bean-definition-dsl, The Groovy Bean Definition DSL>>.
Further support for Groovy, including beans written in Groovy, refreshable script beans,
and more is available in <<dynamic-language>>.

View File

@@ -1,26 +1,27 @@
[[kotlin]]
= Kotlin
https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM (and other platforms),
which allows writing concise and elegant code while providing very good
https://kotlinlang.org/docs/reference/java-interop.html[interoperability] with
existing libraries written in Java.
https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM
(and other platforms), which allows writing concise and elegant code while providing
very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]
with existing libraries written in Java.
The Spring Framework provides first-class support for Kotlin that lets developers write
Kotlin applications almost as if the Spring Framework were a native Kotlin framework.
The easiest way to learn about Spring and Kotlin is to follow
https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial]. Feel
free to join the #spring channel of http://slack.kotlinlang.org/[Kotlin Slack] or ask a
question with `spring` and `kotlin` as tags on
https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial].
Feel free to join the #spring channel of http://slack.kotlinlang.org/[Kotlin Slack]
or ask a question with `spring` and `kotlin` as tags on
https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.
[[kotlin-requirements]]
== Requirements
The Spring Framework supports Kotlin 1.1+ and requires
Spring Framework 5.1 supports Kotlin 1.1+ and requires
https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`]
(or one of its variants, such as https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jre8[`kotlin-stdlib-jre8`]
for Kotlin 1.1 or https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jdk8[`kotlin-stdlib-jdk8`] for Kotlin 1.2+)
@@ -30,6 +31,7 @@ https://start.spring.io/#!language=kotlin[start.spring.io].
[[kotlin-extensions]]
== Extensions
@@ -79,6 +81,7 @@ for shorter syntax.
[[kotlin-null-safety]]
== Null-safety
@@ -90,7 +93,7 @@ declarations and expressing "`value or no value`" semantics without paying the c
http://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)
Although Java does not let you express null-safety in its type-system, the Spring Framework
provides <<core#null-safety,null-safety of the whole Spring Framework API>>
provides <<core#null-safety, null-safety of the whole Spring Framework API>>
via tooling-friendly annotations declared in the `org.springframework.lang` package.
By default, types from Java APIs used in Kotlin are recognized as
https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],
@@ -116,6 +119,7 @@ for up-to-date information.
[[kotlin-classes-interfaces]]
== Classes and Interfaces
@@ -138,6 +142,7 @@ since the later requires a reference to the outer class.
[[kotlin-annotations]]
== Annotations
@@ -166,6 +171,7 @@ https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].
[[kotlin-bean-definition-dsl]]
== Bean Definition DSL
@@ -263,6 +269,7 @@ for more details and up-to-date information.
[[kotlin-web]]
== Web
@@ -272,7 +279,7 @@ for more details and up-to-date information.
Spring Framework now comes with a
{doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-router-function-dsl/[Kotlin routing DSL]
that lets you use the <<web-reactive#webflux-fn,WebFlux functional API>> to write clean and idiomatic Kotlin code,
that lets you use the <<web-reactive#webflux-fn, WebFlux functional API>> to write clean and idiomatic Kotlin code,
as the following example shows:
====
@@ -348,27 +355,27 @@ See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templ
project for more details.
[[kotlin-spring-projects-in-kotlin]]
== Spring Projects in Kotlin
This section provides some specific hints and recommendations worth
for developing Spring projects in Kotlin.
This section provides some specific hints and recommendations worth for developing Spring projects
in Kotlin.
=== Final by Default
By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`].
The `open` modifier on a class is the opposite of Java's `final`: It allows others to
inherit from this class. This also applies to member functions, in that they need to be marked as `open` to
be overridden.
The `open` modifier on a class is the opposite of Java's `final`: It allows others to inherit from this
class. This also applies to member functions, in that they need to be marked as `open` to be overridden.
While Kotlin's JVM-friendly design is generally frictionless with Spring,
this specific Kotlin feature can prevent the application from starting, if this fact is not taken into
consideration. This is because Spring beans
(such as `@Configuration` classes which need to be inherited at runtime for technical reasons) are normally proxied by CGLIB.
The workaround was to add an `open` keyword on each class and member
function of Spring beans that are proxied by CGLIB (such as `@Configuration` classes), which can
While Kotlin's JVM-friendly design is generally frictionless with Spring, this specific Kotlin feature
can prevent the application from starting, if this fact is not taken into consideration. This is because
Spring beans (such as `@Configuration` classes which need to be inherited at runtime for technical
reasons) are normally proxied by CGLIB. The workaround was to add an `open` keyword on each class and
member function of Spring beans that are proxied by CGLIB (such as `@Configuration` classes), which can
quickly become painful and is against the Kotlin principle of keeping code concise and predictable.
Fortunately, Kotlin now provides a
@@ -435,15 +442,16 @@ the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-ar
plugin.
NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and
does not require the `kotlin-noarg` plugin if the module uses Spring Data object
mappings (such as MongoDB, Redis, Cassandra, and others).
does not require the `kotlin-noarg` plugin if the module uses Spring Data object mappings
(such as MongoDB, Redis, Cassandra, and others).
=== Injecting Dependencies
Our recommendation is to try and favor constructor injection with `val` read-only (and non-nullable when possible)
https://kotlinlang.org/docs/reference/properties.html[properties], as the following example shows:
Our recommendation is to try and favor constructor injection with `val` read-only (and
non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],
as the following example shows:
====
[source,kotlin,indent=0]
@@ -456,9 +464,9 @@ https://kotlinlang.org/docs/reference/properties.html[properties], as the follow
----
====
NOTE: As of Spring Framework 4.3, classes with a single constructor have their
parameters automatically autowired, that's why there is no need for an
explicit `@Autowired constructor` in the example shown above.
NOTE: As of Spring Framework 4.3, classes with a single constructor have their parameters
automatically autowired, that's why there is no need for an explicit `@Autowired constructor`
in the example shown above.
If you really need to use field injection, you can use the `lateinit var` construct,
as the following example shows:
@@ -483,13 +491,14 @@ as the following example shows:
=== Injecting Configuration Properties
In Java, you can inject configuration properties by using annotations (such as `@Value("${property}")`).
However, in Kotlin, `$` is a reserved character that is used for https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].
However, in Kotlin, `$` is a reserved character that is used for
https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].
Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`
character by writing `@Value("\${property}")`.
As an alternative, you can customize the properties placeholder prefix by declaring
the following configuration beans:
As an alternative, you can customize the properties placeholder prefix by declaring the
following configuration beans:
====
[source,kotlin,indent=0]
@@ -501,8 +510,8 @@ the following configuration beans:
----
====
You can customize existing code (such as Spring Boot actuators or `@LocalServerPort`) that uses the `${...}` syntax,
with configuration beans, as the following example shows:
You can customize existing code (such as Spring Boot actuators or `@LocalServerPort`)
that uses the `${...}` syntax, with configuration beans, as the following example shows:
====
[source,kotlin,indent=0]
@@ -520,35 +529,38 @@ with configuration beans, as the following example shows:
NOTE: If you use Spring Boot, you can use
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]
instead of `@Value` annotations. However, currently, this only works with `lateinit` or nullable `var`
properties (we recommended the former), since immutable classes initialized by
constructors are not yet supported.
See these issues about https://github.com/spring-projects/spring-boot/issues/8762[`@ConfigurationProperties` binding for immutable POJOs]
instead of `@Value` annotations. However, currently, this only works with `lateinit` or
nullable `var` properties (we recommended the former), since immutable classes initialized
by constructors are not yet supported. See these issues about
https://github.com/spring-projects/spring-boot/issues/8762[`@ConfigurationProperties` binding for immutable POJOs]
and https://github.com/spring-projects/spring-boot/issues/1254[`@ConfigurationProperties` binding on interfaces]
for more details.
=== Checked Exceptions
Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling] are pretty close, with the main
difference being that Kotlin treats all exceptions as unchecked exceptions. However, when using proxied objects
(for example classes or methods annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in
Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]
are pretty close, with the main difference being that Kotlin treats all exceptions as
unchecked exceptions. However, when using proxied objects (for example classes or methods
annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in
an `UndeclaredThrowableException`.
To get the original exception thrown like in Java, methods should be annotated with https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]
To get the original exception thrown like in Java, methods should be annotated with
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]
to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).
=== Annotation Array Attributes
Kotlin annotations are mostly similar to Java annotations, but array attributes (which are
extensively used in Spring) behave differently. As explained in
https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation]
you can omit the `value` attribute name, unlike other attributes, and
specify it as a `vararg` parameter.
https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit
the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.
To understand what that means, consider `@RequestMapping` (which is one
of the most widely used Spring annotations) as an example. This Java annotation is declared as follows:
To understand what that means, consider `@RequestMapping` (which is one of the most widely
used Spring annotations) as an example. This Java annotation is declared as follows:
====
[source,java,indent=0]
@@ -569,8 +581,8 @@ of the most widely used Spring annotations) as an example. This Java annotation
====
The typical use case for `@RequestMapping` is to map a handler method to a specific path
and method. In Java, you can specify a single value for the
annotation array attribute, and it is automatically converted to an array.
and method. In Java, you can specify a single value for the annotation array attribute,
and it is automatically converted to an array.
That is why one can write
`@RequestMapping(value = "/toys", method = RequestMethod.GET)` or
@@ -590,14 +602,16 @@ all HTTP methods will be matched, not only the `GET` one.
=== Testing
This section addresses testing with the combination of Kotlin and Spring Framework. The recommended testing framework
is https://junit.org/junit5/[JUnit 5], as well as https://mockk.io/[Mockk] for mocking.
This section addresses testing with the combination of Kotlin and Spring Framework.
The recommended testing framework is https://junit.org/junit5/[JUnit 5], as well as
https://mockk.io/[Mockk] for mocking.
==== Constructor injection
As described in the <<testing#testcontext-junit-jupiter-di#spring-web-reactive,dedicated section>>, JUnit 5 allows
constructor injection of beans which is pretty useful with Kotlin in order to use `val` instead of `lateinit var`.
As described in the <<testing#testcontext-junit-jupiter-di#spring-web-reactive, dedicated section>>,
JUnit 5 allows constructor injection of beans which is pretty useful with Kotlin
in order to use `val` instead of `lateinit var`.
====
@@ -632,12 +646,11 @@ class OrderServiceIntegrationTests @Autowired constructor(
Kotlin lets you specify meaningful test function names between backticks (```).
As of JUnit 5, Kotlin test classes can use the `@TestInstance(TestInstance.Lifecycle.PER_CLASS)`
annotation to enable a single instantiation of test classes, which allows the use of `@BeforeAll` and `@AfterAll`
annotations on non-static methods, which is a good fit for Kotlin.
annotation to enable a single instantiation of test classes, which allows the use of `@BeforeAll`
and `@AfterAll` annotations on non-static methods, which is a good fit for Kotlin.
You can also change the default behavior to `PER_CLASS` thanks to a
`junit-platform.properties` file with a
`junit.jupiter.testinstance.lifecycle.default = per_class` property.
You can also change the default behavior to `PER_CLASS` thanks to a `junit-platform.properties`
file with a `junit.jupiter.testinstance.lifecycle.default = per_class` property.
The following example demonstrates `@BeforeAll` and `@AfterAll` annotations on non-static methods:
@@ -674,7 +687,6 @@ class IntegrationTests {
====
==== Specification-like Tests
You can create specification-like tests with JUnit 5 and Kotlin.
@@ -707,18 +719,18 @@ class SpecificationLikeTests {
====
[[kotlin-webtestclient-issue]]
==== `WebTestClient` Type Inference Issue in Kotlin
Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must
use the Kotlin `expectBody` extension (such as `.expectBody<String>().isEqualTo("toys")`), since it
provides a workaround for the Kotlin issue with the Java API.
use the Kotlin `expectBody` extension (such as `.expectBody<String>().isEqualTo("toys")`),
since it provides a workaround for the Kotlin issue with the Java API.
See also the related https://jira.spring.io/browse/SPR-16057[SPR-16057] issue.
[[kotlin-getting-started]]
== Getting Started
@@ -726,16 +738,18 @@ The easiest way to learn how to build a Spring application with Kotlin is to fol
https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].
=== `start.spring.io`
The easiest way to start a new Spring Framework 5 project in Kotlin is to create a new Spring
Boot 2 project on https://start.spring.io/#!language=kotlin[start.spring.io].
=== Choosing the Web Flavor
Spring Framework now comes with two different web stacks: <<web#mvc,Spring MVC>> and
<<web-reactive#spring-web-reactive,Spring WebFlux>>.
Spring Framework now comes with two different web stacks: <<web#mvc, Spring MVC>> and
<<web-reactive#spring-web-reactive, Spring WebFlux>>.
Spring WebFlux is recommended if you want to create applications that will deal with latency,
long-lived connections, streaming scenarios or if you want to use the web functional
@@ -746,6 +760,7 @@ MVC and its annotation-based programming model is the recommended choice.
[[kotlin-resources]]
== Resources
@@ -760,6 +775,7 @@ Kotlin and the Spring Framework:
* https://kotlin.link/[Awesome Kotlin]
=== Examples
The following Github projects offer examples that you can learn from and possibly even extend:
@@ -794,4 +810,3 @@ The following list categorizes the pending issues related to Spring and Kotlin s
** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]
** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]
** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]

View File

@@ -7,8 +7,8 @@
Spring makes it easy to create Java enterprise applications. It provides everything you
need to embrace the Java language in an enterprise environment, with support for Groovy
and Kotlin as alternative languages on the JVM, and with the flexibility to create many
kinds of architectures depending on an application's needs. As of Spring Framework 5.0,
Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 9 already.
kinds of architectures depending on an application's needs. As of Spring Framework 5.1,
Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 11 LTS.
Spring supports a wide range of application scenarios. In a large enterprise, applications
often exist for a long time and have to run on a JDK and application server whose upgrade
@@ -44,7 +44,7 @@ A note about modules: Spring's framework jars allow for deployment to JDK 9's mo
"Automatic-Module-Name" manifest entries which define stable language-level module names
("spring.core", "spring.context" etc) independent from jar artifact names (the jars follow
the same naming pattern with "-" instead of ".", e.g. "spring-core" and "spring-context").
Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9.
Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9+.

View File

@@ -4,10 +4,10 @@
`WebTestClient` is a thin shell around <<web-reactive.adoc#webflux-client, WebClient>>,
using it to perform requests and exposing a dedicated, fluent API for verifying responses.
`WebTestClient` binds to a WebFlux application by using a
<<testing.adoc#mock-objects-web-reactive,mock request and response>>, or it can test any
<<testing.adoc#mock-objects-web-reactive, mock request and response>>, or it can test any
web server over an HTTP connection.
TIP: Kotlin users: See <<languages.adoc#kotlin-webtestclient-issue,this section>>
TIP: Kotlin users: See <<languages.adoc#kotlin-webtestclient-issue, this section>>
related to use of the `WebTestClient`.
@@ -35,8 +35,8 @@ The following example shows how to create a server setup to test one `@Controlle
----
====
The preceding example loads the <<web-reactive.adoc#webflux-config,WebFlux Java configuration>> and
registers the given controller. The resulting WebFlux application is tested
The preceding example loads the <<web-reactive.adoc#webflux-config, WebFlux Java configuration>>
and registers the given controller. The resulting WebFlux application is tested
without an HTTP server by using mock request and response objects. There are more methods
on the builder to customize the default WebFlux Java configuration.
@@ -46,7 +46,7 @@ on the builder to customize the default WebFlux Java configuration.
=== Bind to Router Function
The following example shows how to set up a server from a
<<web-reactive.adoc#webflux-fn,RouterFunction>>:
<<web-reactive.adoc#webflux-fn, RouterFunction>>:
====
[source,java,intent=0]
@@ -94,11 +94,10 @@ some subset of it:
<3> Create the `WebTestClient`
====
Internally, the configuration is passed to `WebHttpHandlerBuilder` to set up
the request processing chain. See
<<web-reactive.adoc#webflux-web-handler-api,WebHandler API>> for more details. The
resulting WebFlux application is tested without an HTTP server by using mock request
and response objects.
Internally, the configuration is passed to `WebHttpHandlerBuilder` to set up the request
processing chain. See <<web-reactive.adoc#webflux-web-handler-api, WebHandler API>> for
more details. The resulting WebFlux application is tested without an HTTP server by
using mock request and response objects.
@@ -142,7 +141,7 @@ are readily available following `bindToServer`. For all others, you need to use
[[webtestclient-tests]]
== Writing Tests
`WebTestClient` provides an API identical to <<web-reactive.adoc#webflux-client,WebClient>>
`WebTestClient` provides an API identical to <<web-reactive.adoc#webflux-client, WebClient>>
up to the point of performing a request by using `exchange()`. What follows after
`exchange()` is a chained API workflow to verify responses.
@@ -326,8 +325,8 @@ from the `reactor-test` module to do that, as the following example shows:
[[webtestclient-request-body]]
=== Request Body
When it comes to building requests, the `WebTestClient` offers an API identical to the
`WebClient`, and the implementation is mostly a simple pass-through. See
the <<web-reactive.adoc#webflux-client-body,WebClient documentation>> for examples on
When it comes to building requests, the `WebTestClient` offers an API identical to
the `WebClient`, and the implementation is mostly a simple pass-through. See the
<<web-reactive.adoc#webflux-client-body, WebClient documentation>> for examples on
how to prepare a request with a body, including submitting form data, multipart requests,
and more.

View File

@@ -22,8 +22,8 @@ set up service locator registries and similar structures).
== Introduction to Spring Testing
Testing is an integral part of enterprise software development. This chapter focuses on
the value added by the IoC principle to <<unit-testing,unit testing>> and on the benefits
of the Spring Framework's support for <<integration-testing,integration testing>>. (A
the value added by the IoC principle to <<unit-testing, unit testing>> and on the benefits
of the Spring Framework's support for <<integration-testing, integration testing>>. (A
thorough treatment of testing in the enterprise is beyond the scope of this reference
manual.)
@@ -36,12 +36,12 @@ manual.)
Dependency injection should make your code less dependent on the container than it would
be with traditional 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 <<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, you can test service layer objects by stubbing or mocking DAO or repository
interfaces, without needing to access persistent data while running unit tests.
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,
you can test service layer objects by stubbing or mocking DAO or repository interfaces,
without needing to access persistent data while running unit tests.
True unit tests typically run extremely quickly, as there is no runtime infrastructure to
set up. Emphasizing true unit tests as part of your development methodology can boost
@@ -68,8 +68,8 @@ Spring includes a number of packages dedicated to mocking:
The `org.springframework.mock.env` package contains mock implementations of the
`Environment` and `PropertySource` abstractions (see
<<core.adoc#beans-definition-profiles,Bean Definition Profiles>>
and <<core.adoc#beans-property-source-abstraction,`PropertySource` Abstraction>>).
<<core.adoc#beans-definition-profiles, Bean Definition Profiles>>
and <<core.adoc#beans-property-source-abstraction, `PropertySource` Abstraction>>).
`MockEnvironment` and `MockPropertySource` are useful for developing
out-of-container tests for code that depends on environment-specific properties.
@@ -177,8 +177,8 @@ TIP: To unit test your Spring MVC `Controller` classes as POJOs, use `ModelAndVi
combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring's
<<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 the <<spring-mvc-test-framework,Spring MVC Test
Framework>> instead.
configuration for Spring MVC, use the
<<spring-mvc-test-framework, Spring MVC Test Framework>> instead.
@@ -212,17 +212,17 @@ Doing so lets you test things such as:
The Spring Framework provides first-class support for integration testing in the
`spring-test` module. The name of the actual JAR file might include the release version
and might also be in the long `org.springframework.test` form, depending on where you get
it from (see the <<core.adoc#dependency-management,section on Dependency Management>> for
an explanation). This library includes the `org.springframework.test` package, which
it from (see the <<core.adoc#dependency-management, section on Dependency Management>>
for an explanation). This library includes the `org.springframework.test` package, which
contains valuable classes for integration testing with a Spring container. This testing
does not rely on an application server or other deployment environment. Such tests are
slower to run than unit tests but much faster than the equivalent Selenium tests or
remote tests that rely on deployment to an application server.
In Spring 2.5 and later, unit and integration testing support is provided in the form of
the annotation-driven <<testcontext-framework,Spring TestContext Framework>>. The
TestContext framework is agnostic of the actual testing framework in use, which allows
instrumentation of tests in various environments, including JUnit, TestNG, and others.
Unit and integration testing support is provided in the form of the annotation-driven
<<testcontext-framework, Spring TestContext Framework>>. The TestContext framework is
agnostic of the actual testing framework in use, which allows instrumentation of tests
in various environments, including JUnit, TestNG, and others.
@@ -231,10 +231,10 @@ instrumentation of tests in various environments, including JUnit, TestNG, and o
Spring's integration testing support has the following primary goals:
* 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
* 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
@@ -294,8 +294,8 @@ integration tests that test the following areas:
* The logic of the `HibernateTitleRepository`: Does the configured instance of this class
perform as anticipated?
See dependency injection of test fixtures with the <<testcontext-fixture-di,TestContext
framework>>.
See dependency injection of test fixtures with the
<<testcontext-fixture-di, TestContext framework>>.
[[testing-tx]]
@@ -320,7 +320,7 @@ particular test to populate or modify the database), you can tell the TestContex
framework to cause the transaction to commit instead of roll back by using the
<<integration-testing-annotations, `@Commit`>> annotation.
See transaction management with the <<testcontext-tx,TestContext framework>>.
See transaction management with the <<testcontext-tx, TestContext framework>>.
[[testing-support-classes]]
@@ -337,12 +337,12 @@ which let you access:
queries to confirm database state both before and after execution of database-related
application code, and Spring ensures that such queries run in the scope of the same
transaction as the application code. When used in conjunction with an ORM tool, be sure
to avoid <<testcontext-tx-false-positives,false positives>>.
to avoid <<testcontext-tx-false-positives, false positives>>.
In addition, you may want to create your own custom, application-wide superclass with
instance variables and methods specific to your project.
See support classes for the <<testcontext-support-classes,TestContext framework>>.
See support classes for the <<testcontext-support-classes, TestContext framework>>.
@@ -364,15 +364,15 @@ methods.
[TIP]
====
<<testcontext-support-classes-junit4,`AbstractTransactionalJUnit4SpringContextTests`>>
and <<testcontext-support-classes-testng,`AbstractTransactionalTestNGSpringContextTests`>>
<<testcontext-support-classes-junit4, `AbstractTransactionalJUnit4SpringContextTests`>>
and <<testcontext-support-classes-testng, `AbstractTransactionalTestNGSpringContextTests`>>
provide convenience methods that delegate to the aforementioned methods in
`JdbcTestUtils`.
The `spring-jdbc` module provides support for configuring and launching an embedded
database, which you can use in integration tests that interact with a database. For
details, see <<data-access.adoc#jdbc-embedded-database-support,Embedded Database
Support>> and <<data-access.adoc#jdbc-embedded-database-dao-testing,Testing Data Access
database, which you can use in integration tests that interact with a database.
For details, see <<data-access.adoc#jdbc-embedded-database-support, Embedded Database
Support>> and <<data-access.adoc#jdbc-embedded-database-dao-testing, Testing Data Access
Logic with an Embedded Database>>.
====
@@ -381,8 +381,8 @@ Logic with an Embedded Database>>.
[[integration-testing-annotations]]
=== Annotations
This section covers annotations that you can use when you test Spring applications. It
includes the following topics:
This section covers annotations that you can use when you test Spring applications.
It includes the following topics:
* <<integration-testing-annotations-spring>>
* <<integration-testing-annotations-standard>>
@@ -422,9 +422,8 @@ Spring's testing annotations include the following:
`@BootstrapWith` is a class-level annotation that you can use to configure how the Spring
TestContext Framework is bootstrapped. Specifically, you can use `@BootstrapWith` to
specify a custom `TestContextBootstrapper`. See the
<<testcontext-bootstrapping,Bootstrapping the TestContext framework>> section for further
details.
specify a custom `TestContextBootstrapper`. See the section on
<<testcontext-bootstrapping, bootstrapping the TestContext framework>> for further details.
[[spring-testing-annotation-contextconfiguration]]
===== `@ContextConfiguration`
@@ -645,7 +644,7 @@ be active:
NOTE: `@ActiveProfiles` provides support for inheriting active bean definition profiles
declared by superclasses by default. You can also resolve active bean definition profiles
programmatically by implementing a custom
<<testcontext-ctx-management-env-profiles-ActiveProfilesResolver,`ActiveProfilesResolver`>>
<<testcontext-ctx-management-env-profiles-ActiveProfilesResolver, `ActiveProfilesResolver`>>
and registering it by using the `resolver` attribute of `@ActiveProfiles`.
See <<testcontext-ctx-management-env-profiles>> and the
@@ -1080,8 +1079,8 @@ you use test lifecycle callbacks from the underlying test framework instead of
==== Spring JUnit 4 Testing Annotations
The following annotations are supported only when used in conjunction with the
<<testcontext-junit4-runner,SpringRunner>>, <<testcontext-junit4-rules,Spring's JUnit 4
rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>:
<<testcontext-junit4-runner, SpringRunner>>, <<testcontext-junit4-rules, Spring's JUnit 4
rules>>, or <<testcontext-support-classes-junit4, Spring's JUnit 4 support classes>>:
* <<integration-testing-annotations-junit4-ifprofilevalue>>
* <<integration-testing-annotations-junit4-profilevaluesourceconfiguration>>
@@ -1214,8 +1213,8 @@ how to use the `@Repeat` annotation:
==== Spring JUnit Jupiter Testing Annotations
The following annotations are supported only when used in conjunction with the
<<testcontext-junit-jupiter-extension,`SpringExtension`>> and JUnit Jupiter (that is, the
programming model in JUnit 5):
<<testcontext-junit-jupiter-extension, `SpringExtension`>> and JUnit Jupiter
(that is, the programming model in JUnit 5):
* <<integration-testing-annotations-junit-jupiter-springjunitconfig>>
* <<integration-testing-annotations-junit-jupiter-springjunitwebconfig>>
@@ -1326,11 +1325,10 @@ within that class are automatically enabled by default as well.
Expressions can be any of the following:
* <<core.adoc#expressions,Spring Expression Language>> (SpEL) expression. For example:
* <<core.adoc#expressions, Spring Expression Language>> (SpEL) expression. For example:
`@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")`
* Placeholder for a property available in the Spring
<<core.adoc#beans-environment,`Environment`>>. For example:
`@EnabledIf("${smoke.tests.enabled}")`
* Placeholder for a property available in the Spring <<core.adoc#beans-environment, `Environment`>>.
For example: `@EnabledIf("${smoke.tests.enabled}")`
* Text literal. For example: `@EnabledIf("true")`
Note, however, that a text literal that is not the result of dynamic resolution of a
@@ -1365,11 +1363,10 @@ test methods within that class are automatically disabled as well.
Expressions can be any of the following:
* <<core.adoc#expressions,Spring Expression Language>> (SpEL) expression. For example:
* <<core.adoc#expressions, Spring Expression Language>> (SpEL) expression. For example:
`@DisabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")`
* Placeholder for a property available in the Spring
<<core.adoc#beans-environment,`Environment`>>. For example:
`@DisabledIf("${smoke.tests.disabled}")`
* Placeholder for a property available in the Spring <<core.adoc#beans-environment, `Environment`>>.
For example: `@DisabledIf("${smoke.tests.disabled}")`
* Text literal. For example: `@DisabledIf("true")`
Note, however, that a text literal that is not the result of dynamic resolution of a
@@ -1398,11 +1395,11 @@ example, you can create a custom `@DisabledOnMac` annotation as follows:
==== Meta-Annotation Support for Testing
You can use most test-related annotations as
<<core.adoc#beans-meta-annotations,meta-annotations>> to create custom composed
<<core.adoc#beans-meta-annotations, meta-annotations>> to create custom composed
annotations and reduce configuration duplication across a test suite.
You can use each of the following as a meta-annotation in conjunction with the
<<testcontext-framework,TestContext framework>>.
<<testcontext-framework, TestContext framework>>.
* `@BootstrapWith`
* `@ContextConfiguration`
@@ -1599,10 +1596,10 @@ required to extend a particular class hierarchy, such as the `abstract` support
The following section provides an overview of the internals of the TestContext framework.
If you are interested only in using the framework and are not interested in extending it
with your own custom listeners or custom loaders, feel free to go directly to the
configuration (<<testcontext-ctx-management,context management>>,
<<testcontext-fixture-di,dependency injection>>, <<testcontext-tx,transaction
management>>), <<testcontext-support-classes,support classes>>, and
<<integration-testing-annotations,annotation support>> sections.
configuration (<<testcontext-ctx-management, context management>>,
<<testcontext-fixture-di, dependency injection>>, <<testcontext-tx,transaction
management>>), <<testcontext-support-classes, support classes>>, and
<<integration-testing-annotations, annotation support>> sections.
[[testcontext-key-abstractions]]
@@ -1643,24 +1640,22 @@ responsible for managing a single `TestContext` and signaling events to each reg
===== `TestExecutionListener`
`TestExecutionListener` defines the API for reacting to test-execution events published
by the `TestContextManager` with which the listener is registered. See
<<testcontext-tel-config>>.
`TestExecutionListener` defines the API for reacting to test-execution events published by
the `TestContextManager` with which the listener is registered. See <<testcontext-tel-config>>.
===== Context Loaders
`ContextLoader` is a strategy interface that was introduced in Spring 2.5 for loading an
`ApplicationContext` for an integration test managed by the Spring TestContext Framework.
You should implement `SmartContextLoader` instead of this interface to provide support
for annotated classes, active bean definition profiles, test property sources, context
hierarchies, and `WebApplicationContext` support.
`ContextLoader` is a strategy interface for loading an `ApplicationContext` for an
integration test managed by the Spring TestContext Framework. You should implement
`SmartContextLoader` instead of this interface to provide support for annotated classes,
active bean definition profiles, test property sources, context hierarchies, and
`WebApplicationContext` support.
`SmartContextLoader` is an extension of the `ContextLoader` interface introduced in
Spring 3.1. The `SmartContextLoader` SPI supersedes the `ContextLoader` SPI that was
introduced in Spring 2.5. Specifically, a `SmartContextLoader` can choose to process
resource locations, annotated classes, or context initializers. Furthermore, a
`SmartContextLoader` can set active bean definition profiles and test property sources in
the context that it loads.
Spring 3.1, superseding the original minimal `ContextLoader` SPI. Specifically, a
`SmartContextLoader` can choose to process resource locations, annotated classes,
or context initializers. Furthermore, a `SmartContextLoader` can set active bean
definition profiles and test property sources in the context that it loads.
Spring provides the following implementations:
@@ -1741,7 +1736,7 @@ by default, exactly in the following order:
You can register custom `TestExecutionListener` implementations for a test class
and its subclasses by using the `@TestExecutionListeners` annotation.
See <<integration-testing-annotations,annotation support>> and the javadoc for
See <<integration-testing-annotations, annotation support>> and the javadoc for
{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]
for details and examples.
@@ -1766,7 +1761,7 @@ file.
===== Ordering `TestExecutionListener` Implementations
When the TestContext framework discovers default `TestExecutionListener` implementations
through the <<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
@@ -1810,8 +1805,8 @@ which listeners are registered by default. Moreover, the set of default listener
change from release to release -- for example, `SqlScriptsTestExecutionListener` was
introduced in Spring Framework 4.1, and `DirtiesContextBeforeModesTestExecutionListener`
was introduced in Spring Framework 4.2. Furthermore, third-party frameworks like Spring
Security register their own default `TestExecutionListener` implementations by using the
aforementioned <<testcontext-tel-config-automatic-discovery, automatic discovery
Security register their own default `TestExecutionListener` implementations by using
the aforementioned <<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
@@ -1905,8 +1900,8 @@ the web application context into your test, as follows:
====
Dependency injection by using `@Autowired` is provided by the
`DependencyInjectionTestExecutionListener`, which is configured by default (see
<<testcontext-fixture-di>>).
`DependencyInjectionTestExecutionListener`, which is configured by default
(see <<testcontext-fixture-di>>).
=====
Test classes that use the TestContext framework do not need to extend any particular
@@ -2011,11 +2006,11 @@ example shows how to do so:
===== Context Configuration with Groovy Scripts
To load an `ApplicationContext` for your tests by using Groovy scripts that use the
<<core.adoc#groovy-bean-definition-dsl,Groovy Bean Definition DSL>>, you can annotate
<<core.adoc#groovy-bean-definition-dsl, Groovy Bean Definition DSL>>, you can annotate
your test class with `@ContextConfiguration` and configure the `locations` or `value`
attribute with an array that contains the resource locations of Groovy scripts. Resource
lookup semantics for Groovy scripts are the same as those described for
<<testcontext-ctx-management-xml,XML configuration files>>.
<<testcontext-ctx-management-xml, XML configuration files>>.
.Enabling Groovy script support
TIP: Support for using Groovy scripts to load an `ApplicationContext` in the Spring
@@ -3000,7 +2995,7 @@ Contrast the comments in this example with the previous example.
--
To provide comprehensive web testing support, Spring 3.2 introduced a
`ServletTestExecutionListener` that is enabled by default. When testing against a
`WebApplicationContext`, this <<testcontext-key-abstractions,`TestExecutionListener`>>
`WebApplicationContext`, this <<testcontext-key-abstractions, `TestExecutionListener`>>
sets up default thread-local state by using Spring Web's `RequestContextHolder` before
each test method and creates a `MockHttpServletRequest`, a `MockHttpServletResponse`, and
a `ServletWebRequest` based on the base resource path configured with
@@ -3287,7 +3282,7 @@ shows this configuration scenario:
NOTE: If you use `@DirtiesContext` in a test whose context is configured as part of a
context hierarchy, you can use the `hierarchyMode` flag to control how the context cache
is cleared. For further details, see the discussion of `@DirtiesContext` in
<<spring-testing-annotation-dirtiescontext,Spring Testing Annotations>> and the
<<spring-testing-annotation-dirtiescontext, Spring Testing Annotations>> and the
{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.
--
@@ -3297,12 +3292,12 @@ is cleared. For further details, see the discussion of `@DirtiesContext` in
When you use the `DependencyInjectionTestExecutionListener` (which is configured by
default), the dependencies of your test instances are injected from beans in the
application context that you configured with `@ContextConfiguration` or related
annotations. You may use setter injection, field injection, or both, depending on which
annotations you choose and whether you place them on setter methods or fields. If you are
using JUnit Jupiter you may also optionally use constructor injection (see
<<testcontext-junit-jupiter-di>>). For consistency with the annotation support introduced
in Spring 2.5 and 3.0, you can use Spring's `@Autowired` annotation or the `@Inject`
annotation from JSR 330 for field and setter injection.
annotations. You may use setter injection, field injection, or both, depending on
which annotations you choose and whether you place them on setter methods or fields.
If you are using JUnit Jupiter you may also optionally use constructor injection
(see <<testcontext-junit-jupiter-di>>). For consistency with Spring's annotation-based
injection support, you may also use Spring's `@Autowired` annotation or the `@Inject`
annotation from JSR-330 for field and setter injection.
TIP: For testing frameworks other than JUnit Jupiter, the TestContext framework does not
participate in instantiation of the test class. Thus, the use of `@Autowired` or
@@ -3328,7 +3323,7 @@ dependency injection altogether by explicitly configuring your class with
from the list of listeners.
Consider the scenario of testing a `HibernateTitleRepository` class, as outlined in the
<<integration-testing-goals,Goals>> section. The next two code listings demonstrate the
<<integration-testing-goals, Goals>> section. The next two code listings demonstrate the
use of `@Autowired` on fields and setter methods. The application context configuration
is presented after all sample code listings.
@@ -3459,7 +3454,7 @@ bean by name there (as shown earlier, assuming that `myDataSource` is the bean `
[[testcontext-web-scoped-beans]]
==== Testing Request- and Session-scoped Beans
Spring has supported <<core#beans-factory-scopes-other,Request- and session-scoped
Spring has supported <<core#beans-factory-scopes-other, Request- and session-scoped
beans>> since the early years. Since Spring 3.2, you can test your request-scoped and
session-scoped beans by following these steps:
@@ -3473,7 +3468,7 @@ session-scoped beans by following these steps:
The next code snippet shows the XML configuration for a login use case. Note that the
`userService` bean has a dependency on a request-scoped `loginAction` bean. Also, the
`LoginAction` is instantiated by using <<core.adoc#expressions,SpEL expressions>> that
`LoginAction` is instantiated by using <<core.adoc#expressions, SpEL expressions>> that
retrieve the username and password from the current HTTP request. In our test, we want to
configure these request parameters through the mock managed by the TestContext framework.
The following listing shows the configuration for this use case:
@@ -3615,7 +3610,7 @@ application code that is invoked by tests). Spring-managed and application-manag
transactions typically participate in test-managed transactions. However, you should use
caution if Spring-managed or application-managed transactions are configured with any
propagation type other than `REQUIRED` or `SUPPORTS` (see the discussion on
<<data-access.adoc#tx-propagation,transaction propagation>> for details).
<<data-access.adoc#tx-propagation, transaction propagation>> for details).
.Preemptive timeouts and test-managed transactions
[WARNING]
@@ -3715,7 +3710,7 @@ database are automatically rolled back by the `TransactionalTestExecutionListene
By default, test transactions will be automatically rolled back after completion of the
test; however, transactional commit and rollback behavior can be configured declaratively
via the `@Commit` and `@Rollback` annotations. See the corresponding entries in the
<<integration-testing-annotations,annotation support>> section for further details.
<<integration-testing-annotations, annotation support>> section for further details.
[[testcontext-tx-programmatic-tx-mgt]]
===== Programmatic Transaction Management
@@ -3802,7 +3797,7 @@ algorithm used to look up a transaction manager in the test's `ApplicationContex
The following JUnit 4 based example displays a fictitious integration testing scenario
that highlights all transaction-related annotations. The example is not intended to
demonstrate best practices but rather to demonstrate how these annotations can be used.
See the <<integration-testing-annotations,annotation support>> section for further
See the <<integration-testing-annotations, annotation support>> section for further
information and configuration examples. <<testcontext-executing-sql-declaratively-tx,
Transaction management for `@Sql`>> contains an additional example that uses `@Sql` for
declarative SQL script execution with default transaction rollback semantics. The
@@ -3992,7 +3987,7 @@ specifies SQL scripts for a test schema and test data, sets the statement separa
Note that `ResourceDatabasePopulator` internally delegates to `ScriptUtils` for parsing
and running SQL scripts. Similarly, the `executeSqlScript(..)` methods in
<<testcontext-support-classes-junit4, `AbstractTransactionalJUnit4SpringContextTests`>>
and <<testcontext-support-classes-testng,`AbstractTransactionalTestNGSpringContextTests`>>
and <<testcontext-support-classes-testng, `AbstractTransactionalTestNGSpringContextTests`>>
internally use a `ResourceDatabasePopulator` to run SQL scripts. See the javadoc for the
various `executeSqlScript(..)` methods for further details.
@@ -4259,8 +4254,8 @@ This may be due to the use of `@DirtiesContext` or due to automatic eviction fro
`ContextCache`. If `@DirtiesContext` is the culprit, you either need to find a way to
avoid using `@DirtiesContext` or exclude such tests from parallel execution. If the
maximum size of the `ContextCache` has been exceeded, you can increase the maximum size
of the cache. See the discussion on <<testcontext-ctx-management-caching,context
caching>> for details.
of the cache. See the discussion on <<testcontext-ctx-management-caching, context caching>>
for details.
====
WARNING: Parallel test execution in the Spring TestContext Framework is only possible if
@@ -4288,7 +4283,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
<<testcontext-junit4-rules,Spring's support for JUnit rules>> instead.
<<testcontext-junit4-rules, Spring's support for JUnit rules>> instead.
The following code listing shows the minimal requirements for configuring a test class to
run with the custom Spring `Runner`:
@@ -4381,8 +4376,8 @@ extend `AbstractTransactionalJUnit4SpringContextTests`, you can access a `protec
database. You can use such queries to confirm database state both before and after
running database-related application code, and Spring ensures that such queries run in
the scope of the same transaction as the application code. When used in conjunction with
an ORM tool, be sure to avoid <<testcontext-tx-false-positives,false positives>>. As
mentioned in <<integration-testing-support-jdbc>>,
an ORM tool, be sure to avoid <<testcontext-tx-false-positives, false positives>>.
As mentioned in <<integration-testing-support-jdbc>>,
`AbstractTransactionalJUnit4SpringContextTests` also provides convenience methods that
delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`.
Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an
@@ -4390,7 +4385,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 <<testcontext-junit4-rules,Spring's
classes by using `@RunWith(SpringRunner.class)` or <<testcontext-junit4-rules, Spring's
JUnit rules>>.
[[testcontext-junit-jupiter-extension]]
@@ -4635,8 +4630,8 @@ extend `AbstractTransactionalTestNGSpringContextTests`, you can access a `protec
database. You can use such queries to confirm database state both before and after
running database-related application code, and Spring ensures that such queries run in
the scope of the same transaction as the application code. When used in conjunction with
an ORM tool, be sure to avoid <<testcontext-tx-false-positives,false positives>>. As
mentioned in <<integration-testing-support-jdbc>>,
an ORM tool, be sure to avoid <<testcontext-tx-false-positives, false positives>>.
As mentioned in <<integration-testing-support-jdbc>>,
`AbstractTransactionalTestNGSpringContextTests` also provides convenience methods that
delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`.
Furthermore, `AbstractTransactionalTestNGSpringContextTests` provides an
@@ -4687,7 +4682,7 @@ Furthermore, other controller methods such as `@InitBinder`, `@ModelAttribute`,
The goal of Spring MVC Test is to provide an effective way to test controllers by
performing requests and generating responses through the actual `DispatcherServlet`.
Spring MVC Test builds on the familiar <<mock-objects-servlet,"`mock`" implementations of
Spring MVC Test builds on the familiar <<mock-objects-servlet, "`mock`" implementations of
the Servlet API>> available in the `spring-test` module. This allows performing requests
and generating responses without the need for running in a Servlet container. For the
most part, everything should work as it does at runtime with a few notable exceptions, as
@@ -4738,7 +4733,7 @@ discussed later in this document.
[[spring-mvc-test-server-static-imports]]
===== Static Imports
The fluent API in the example from the <<spring-mvc-test-server,preceding section>>
The fluent API in the example from the <<spring-mvc-test-server, preceding section>>
requires a few static imports, such as `MockMvcRequestBuilders.{asterisk}`,
`MockMvcResultMatchers.{asterisk}`, and `MockMvcBuilders.{asterisk}`. An easy way to find
these classes is to search for types that match `MockMvc*`. If you use Eclipse or the
@@ -5197,7 +5192,7 @@ full test coverage based on Spring MVC Test.
[[spring-mvc-test-server-htmlunit]]
==== HtmlUnit Integration
Spring provides integration between <<spring-mvc-test-server,MockMvc>> and
Spring provides integration between <<spring-mvc-test-server, MockMvc>> and
http://htmlunit.sourceforge.net/[HtmlUnit]. This simplifies performing end-to-end testing
when using HTML-based views. This integration lets you:
@@ -5456,7 +5451,7 @@ assertions use the http://joel-costigliola.github.io/assertj/[AssertJ] library:
====
The preceding code improves on our
<<spring-mvc-test-server-htmlunit-mock-mvc-test,MockMvc test>> in a number of ways.
<<spring-mvc-test-server-htmlunit-mock-mvc-test, MockMvc test>> in a number of ways.
First, we no longer have to explicitly verify our form and then create a request that
looks like the form. Instead, we request the form, fill it out, and submit it, thereby
significantly reducing the overhead.
@@ -5702,8 +5697,8 @@ We can then fill out the form and submit it to create a message, as follows:
----
====
This improves on the design of our <<spring-mvc-test-server-htmlunit-mah-usage,HtmlUnit
test>> by leveraging the Page Object Pattern. As we mentioned in
This improves on the design of our <<spring-mvc-test-server-htmlunit-mah-usage, HtmlUnit test>>
by leveraging the Page Object Pattern. As we mentioned in
<<spring-mvc-test-server-htmlunit-webdriver-why>>, we can use the Page Object Pattern
with HtmlUnit, but it is much easier with WebDriver. Consider the following
`CreateMessagePage` implementation:
@@ -5892,7 +5887,7 @@ use http://www.gebish.org/[Geb] to make our tests even Groovy-er.
====== Why Geb and MockMvc?
Geb is backed by WebDriver, so it offers many of the
<<spring-mvc-test-server-htmlunit-webdriver-why,same benefits>> that we get from
<<spring-mvc-test-server-htmlunit-webdriver-why, same benefits>> that we get from
WebDriver. However, Geb makes things even easier by taking care of some of the
boilerplate code for us.
@@ -5952,7 +5947,7 @@ forwarded to the current page object. This removes a lot of the boilerplate code
needed when using WebDriver directly.
As with direct WebDriver usage, this improves on the design of our
<<spring-mvc-test-server-htmlunit-mah-usage,HtmlUnit test>> by using the Page Object
<<spring-mvc-test-server-htmlunit-mah-usage, HtmlUnit test>> by using the Page Object
Pattern. As mentioned previously, we can use the Page Object Pattern with HtmlUnit and
WebDriver, but it is even easier with Geb. Consider our new Groovy-based
`CreateMessagePage` implementation:

View File

@@ -7,13 +7,13 @@
:tabsize: 4
:docinfo1:
This part of the documentation covers support for reactive-stack web applications built on a
http://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking
This part of the documentation covers support for reactive-stack web applications built
on a http://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking
servers, such as Netty, Undertow, and Servlet 3.1+ containers. Individual chapters cover
the <<webflux,Spring WebFlux>> framework,
the reactive <<webflux-client,`WebClient`>>, support for <<webflux-test, testing>>,
and <<webflux-reactive-libraries, reactive libraries>>. For Servlet-stack web applications, see
<<web.adoc#spring-web,Web on Servlet Stack>>.
the <<webflux, Spring WebFlux>> framework,
the reactive <<webflux-client, `WebClient`>>, support for <<webflux-test, testing>>,
and <<webflux-reactive-libraries, reactive libraries>>. For Servlet-stack web applications,
see <<web.adoc#spring-web, Web on Servlet Stack>>.
include::web/webflux.adoc[leveloffset=+1]
@@ -26,13 +26,14 @@ include::web/webflux-websocket.adoc[leveloffset=+1]
[[webflux-test]]
== Testing
[.small]#<<web.adoc#testing,Same in Spring MVC>>#
[.small]#<<web.adoc#testing, Same in Spring MVC>>#
The `spring-test` module provides mock implementations of `ServerHttpRequest`,
`ServerHttpResponse`, and `ServerWebExchange`.
See <<testing.adoc#mock-objects-web-reactive,Spring Web Reactive>> for a discussion of mock objects.
See <<testing.adoc#mock-objects-web-reactive, Spring Web Reactive>> for a
discussion of mock objects.
<<testing.adoc#webtestclient,`WebTestClient`>> builds on these mock request and
<<testing.adoc#webtestclient, `WebTestClient`>> builds on these mock request and
response objects to provide support for testing WebFlux applications without an HTTP
server. You can use the `WebTestClient` for end-to-end integration tests, too.
@@ -53,10 +54,10 @@ server. You can use the `WebTestClient` for end-to-end integration tests, too.
`spring-webflux` depends on `reactor-core` and uses it internally to compose asynchronous
logic and to provide Reactive Streams support. Generally, WebFlux APIs return `Flux` or
`Mono` (since those are used internally) and leniently accept any Reactive Streams
`Publisher` implementation as input. The use of `Flux` versus `Mono` is important, because it
helps to express cardinality -- for example, whether a single or multiple asynchronous values are
expected, and that can be essential for making decisions (for example, when encoding or
decoding HTTP messages).
`Publisher` implementation as input. The use of `Flux` versus `Mono` is important, because
it helps to express cardinality -- for example, whether a single or multiple asynchronous
values are expected, and that can be essential for making decisions (for example, when
encoding or decoding HTTP messages).
For annotated controllers, WebFlux transparently adapts to the reactive library chosen by
the application. This is done with the help of the

View File

@@ -8,9 +8,9 @@
:docinfo1:
This part of the documentation covers support for Servlet-stack web applications built on the
Servlet API and deployed to Servlet containers. Individual chapters include <<mvc,Spring MVC>>,
<<mvc-view,View Technologies>>, <<mvc-cors,CORS Support>>, and <<websocket,WebSocket Support>>.
For reactive-stack web applications, see <<web-reactive.adoc#spring-web-reactive,Web on Reactive Stack>>.
Servlet API and deployed to Servlet containers. Individual chapters include <<mvc, Spring MVC>>,
<<mvc-view,View Technologies>>, <<mvc-cors,CORS Support>>, and <<websocket, WebSocket Support>>.
For reactive-stack web applications, see <<web-reactive.adoc#spring-web-reactive, Web on Reactive Stack>>.
include::web/webmvc.adoc[leveloffset=+1]

View File

@@ -1,16 +1,16 @@
[[web-integration]]
= Other Web Frameworks
This chapter details Spring's integration with third party web frameworks.
This chapter details Spring's integration with third-party web frameworks.
One of the core value propositions of the Spring Framework is that of enabling
_choice_. In a general sense, Spring does not force you to use or buy into any
particular architecture, technology, or methodology (although it certainly recommends
some over others). This freedom to pick and choose the architecture, technology, or
methodology that is most relevant to a developer and their development team is
arguably most evident in the web area, where Spring provides its own web framework
(<<mvc,Spring MVC>>) while, at the same time, providing integration with a number of
popular third party web frameworks.
arguably most evident in the web area, where Spring provides its own web frameworks
(<<mvc, Spring MVC>> and <<webflux, Spring WebFlux>>) while, at the same time,
supporting integration with a number of popular third-party web frameworks.
@@ -19,9 +19,8 @@ popular third party web frameworks.
== Common Configuration
Before diving into the integration specifics of each supported web framework, let us
first take a look at the Spring configuration that is not specific to any one web
framework. (This section is equally applicable to Spring's own web framework, Spring
MVC.)
first take a look at common Spring configuration that is not specific to any one web
framework. (This section is equally applicable to Spring's own web framework variants.)
One of the concepts (for want of a better word) espoused by Spring's lightweight
application model is that of a layered architecture. Remember that in a "`classic`"
@@ -96,14 +95,14 @@ key. Rather than risk getting `NullPointerExceptions` in your application, it is
to use the `getRequiredWebApplicationContext()` method. This method throws an exception
when the `ApplicationContext` is missing.
Once you have a reference to the `WebApplicationContext`, you can retrieve beans by
their name or type. Most developers retrieve beans by name and then cast them to one of
their implemented interfaces.
Once you have a reference to the `WebApplicationContext`, you can retrieve beans by their
name or type. Most developers retrieve beans by name and then cast them to one of their
implemented interfaces.
Fortunately, most of the frameworks in this section have simpler ways of looking up
beans. Not only do they make it easy to get beans from a Spring container, but they also
let you use dependency injection on their controllers. Each web framework section
has more detail on its specific integration strategies.
Fortunately, most of the frameworks in this section have simpler ways of looking up beans.
Not only do they make it easy to get beans from a Spring container, but they also let you
use dependency injection on their controllers. Each web framework section has more detail
on its specific integration strategies.
@@ -111,18 +110,14 @@ has more detail on its specific integration strategies.
[[jsf]]
== JSF
JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web user
interface framework. As of Java EE 5, it is an official part of the Java EE umbrella.
JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web
user interface framework. It is an official part of the Java EE umbrella but also
individually usable, e.g. through embedding Mojarra or MyFaces within Tomcat.
For a popular JSF runtime as well as for popular JSF component libraries, check out the
http://myfaces.apache.org/[Apache MyFaces project]. The MyFaces project also provides
common JSF extensions, such as http://myfaces.apache.org/orchestra/[MyFaces Orchestra]
(a Spring-based JSF extension that provides rich conversation scope support).
NOTE: Spring Web Flow 2.0 provides rich JSF support through its newly established Spring Faces
module, both for JSF-centric usage (as described in this section) and for Spring-centric
usage (using JSF views within a Spring MVC dispatcher). See the
http://projects.spring.io/spring-webflow[Spring Web Flow website] for details.
Please note that recent versions of JSF became closely tied to CDI infrastructure
in application servers, with some new JSF functionality only working in such an
environment. Spring's JSF support is not actively evolved anymore and primarily
exists for migration purposes when modernizing older JSF-based applications.
The key element in Spring's JSF integration is the JSF `ELResolver` mechanism.
@@ -131,11 +126,10 @@ The key element in Spring's JSF integration is the JSF `ELResolver` mechanism.
[[jsf-springbeanfaceselresolver]]
=== Spring Bean Resolver
`SpringBeanFacesELResolver` is a JSF 1.2+ compliant `ELResolver` implementation,
integrating with the standard Unified EL as used by JSF 1.2 and JSP 2.1. As
`SpringBeanVariableResolver`, it delegates to Spring's "`business context`"
`WebApplicationContext` first and then to the default resolver of the underlying JSF
implementation.
`SpringBeanFacesELResolver` is a JSF compliant `ELResolver` implementation,
integrating with the standard Unified EL as used by JSF and JSP. It delegates to
Spring's "`business context`" `WebApplicationContext` first and then to the
default resolver of the underlying JSF implementation.
Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF
`faces-context.xml` file, as the following example shows:
@@ -158,11 +152,11 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF
[[jsf-facescontextutils]]
=== Using `FacesContextUtils`
A custom `VariableResolver` works well when mapping your properties to beans
in `faces-config.xml`, but, at times, you may need to explicitly grab a bean. The
{api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]
class makes this easy. It is similar to `WebApplicationContextUtils`, except that it
takes a `FacesContext` parameter rather than a `ServletContext` parameter.
A custom `ELResolver` works well when mapping your properties to beans in
`faces-config.xml`, but, at times, you may need to explicitly grab a bean.
The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]
class makes this easy. It is similar to `WebApplicationContextUtils`, except that
it takes a `FacesContext` parameter rather than a `ServletContext` parameter.
The following example shows how to use `FacesContextUtils`:
@@ -183,30 +177,29 @@ The following example shows how to use `FacesContextUtils`:
Invented by Craig McClanahan, http://struts.apache.org[Struts] is an open-source project
hosted by the Apache Software Foundation. At the time, it greatly simplified the
JSP/Servlet programming paradigm and won over many developers who were using proprietary
frameworks. It simplified the programming model, it was open source (and thus free, as in
beer), and it had a large community, which let the project grow and become popular
among Java web developers.
frameworks. It simplified the programming model, it was open source (and thus free as in
beer), and it had a large community, which let the project grow and become popular among
Java web developers.
Check out the Struts
As a successor to the original Struts 1.x, check out Struts 2.x and the Struts-provided
https://struts.apache.org/release/2.3.x/docs/spring-plugin.html[Spring Plugin] for the
built-in Spring integration shipped with Struts.
built-in Spring integration.
[[tapestry]]
== Tapestry 5.x
== Apache Tapestry 5.x
http://tapestry.apache.org/[Tapestry] is a ""Component oriented framework for creating dynamic, robust,
highly scalable web applications in Java.""
http://tapestry.apache.org/[Tapestry] is a ""Component oriented framework for creating
dynamic, robust, highly scalable web applications in Java.""
While Spring has its own <<mvc,powerful web layer>>, there are a number of unique
While Spring has its own <<mvc, powerful web layer>>, there are a number of unique
advantages to building an enterprise Java application by using a combination of Tapestry
for the web user interface and the Spring container for the lower layers.
For more information, see Tapestry's dedicated
https://tapestry.apache.org/integrating-with-spring-framework.html[integration module for
Spring].
https://tapestry.apache.org/integrating-with-spring-framework.html[integration module for Spring].
@@ -214,8 +207,8 @@ Spring].
[[web-integration-resources]]
== Further Resources
The following links go to further resources about the various web frameworks described in this
chapter.
The following links go to further resources about the various web frameworks described in
this chapter.
* The http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[JSF] homepage
* The http://struts.apache.org/[Struts] homepage

View File

@@ -71,10 +71,10 @@ You shorter it further still with a full URI template, as the following example
= UriBuilder
[.small]#Spring MVC and Spring WebFlux#
<<web-uricomponents,`UriComponentsBuilder`>> implements `UriBuilder`. You can create a `UriBuilder`, in turn,
with a `UriBuilderFactory`. Together, `UriBuilderFactory` and `UriBuilder`
provide a pluggable mechanism to build URIs from URI templates, based on shared
configuration, such as a base URL, encoding preferences, and other details.
<<web-uricomponents, `UriComponentsBuilder`>> implements `UriBuilder`. You can create a
`UriBuilder`, in turn, with a `UriBuilderFactory`. Together, `UriBuilderFactory` and
`UriBuilder` provide a pluggable mechanism to build URIs from URI templates, based on
shared configuration, such as a base URL, encoding preferences, and other details.
You can configure `RestTemplate` and `WebClient` with a `UriBuilderFactory`
to customize the preparation of URIs. `DefaultUriBuilderFactory` is a default

View File

@@ -1,6 +1,6 @@
[[webflux-cors]]
= CORS
[.small]#<<web.adoc#mvc-cors,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors, Same as in Spring MVC>>#
Spring WebFlux lets you handle CORS (Cross-Origin Resource Sharing). This section
describes how to do so.
@@ -10,7 +10,7 @@ describes how to do so.
[[webflux-cors-intro]]
== Introduction
[.small]#<<web.adoc#mvc-cors-intro,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors-intro, Same as in Spring MVC>>#
For security reasons, browsers prohibit AJAX calls to resources outside the current origin.
For example, you could have your bank account in one tab and evil.com in another. Scripts
@@ -27,7 +27,7 @@ powerful workarounds based on IFRAME or JSONP.
[[webflux-cors-processing]]
== Processing
[.small]#<<web.adoc#mvc-cors-processing,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors-processing, Same as in Spring MVC>>#
The CORS specification distinguishes between preflight, simple, and actual requests.
To learn how CORS works, you can read
@@ -77,7 +77,7 @@ To learn more from the source or to make advanced customizations, see:
[[webflux-cors-controller]]
== `@CrossOrigin`
[.small]#<<web.adoc#mvc-cors-controller,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors-controller, Same as in Spring MVC>>#
The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]
annotation enables cross-origin requests on annotated controller methods, as the
@@ -176,7 +176,7 @@ public class AccountController {
[[webflux-cors-global]]
== Global Configuration
[.small]#<<web.adoc#mvc-cors-global,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors-global, Same as in Spring MVC>>#
In addition to fine-grained, controller method-level configuration, you probably want to
define some global CORS configuration, too. You can set URL-based `CorsConfiguration`
@@ -227,11 +227,11 @@ public class WebConfig implements WebFluxConfigurer {
[[webflux-cors-webfilter]]
== CORS `WebFilter`
[.small]#<<web.adoc#mvc-cors-filter,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-cors-filter, Same as in Spring MVC>>#
You can apply CORS support through the built-in
{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a
good fit with <<webflux-fn,functional endpoints>>.
good fit with <<webflux-fn, functional endpoints>>.
NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring
Security has

View File

@@ -66,7 +66,7 @@ public class PersonHandler {
====
One way to run a `RouterFunction` is to turn it into an `HttpHandler` and install it
through one of the built-in <<web-reactive.adoc#webflux-httphandler,server adapters>>:
through one of the built-in <<web-reactive.adoc#webflux-httphandler, server adapters>>:
* `RouterFunctions.toHttpHandler(RouterFunction)`
* `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)`
@@ -85,7 +85,7 @@ Both request and response provide http://www.reactive-streams.org[Reactive Strea
against the body streams.
The request body is represented with a Reactor `Flux` or `Mono`.
The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.
For more on that, see <<web-reactive.adoc#webflux-reactive-libraries,Reactive Libraries>>.
For more on that, see <<web-reactive.adoc#webflux-reactive-libraries, Reactive Libraries>>.
@@ -255,9 +255,9 @@ found. If it is not found, we use `switchIfEmpty(Mono<T>)` to return a 404 Not F
[[webflux-fn-handler-validation]]
=== Validation
A functional endpoint can use Spring's <<core.adoc#validation,validation facilities>> to
A functional endpoint can use Spring's <<core.adoc#validation, validation facilities>> to
apply validation to the request body. For example, given a custom Spring
<<core.adoc#validation,Validator>> implementation for a `Person`:
<<core.adoc#validation, Validator>> implementation for a `Person`:
====
[source,java,indent=0]
@@ -290,7 +290,7 @@ public class PersonHandler {
Handlers can also use the standard bean validation API (JSR-303) by creating and injecting
a global `Validator` instance based on `LocalValidatorFactoryBean`.
See <<core.adoc#validation-beanvalidation,Spring Validation>>.
See <<core.adoc#validation-beanvalidation, Spring Validation>>.
@@ -454,10 +454,10 @@ function to an `HttpHandler` by using one of the following:
* `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)`
You can then use the returned `HttpHandler` with a number of server adapters by following
<<web-reactive.adoc#webflux-httphandler,HttpHandler>> for server-specific instructions.
<<web-reactive.adoc#webflux-httphandler, HttpHandler>> for server-specific instructions.
A more typical option, also used by Spring Boot, is to run with a
<<web-reactive.adoc#webflux-dispatcher-handler,`DispatcherHandler`>>-based setup through the
<<web-reactive.adoc#webflux-dispatcher-handler, `DispatcherHandler`>>-based setup through the
<<web-reactive.adoc#webflux-config>>, which uses Spring configuration to declare the
components required to process requests. The WebFlux Java configuration declares the following
infrastructure components to support functional endpoints:
@@ -476,7 +476,7 @@ any are declared. It is also how functional endpoints are enabled by the Spring
starter.
The following example shows a WebFlux Java configuration (see
<<web-reactive.adoc#webflux-dispatcher-handler,DispatcherHandler>> for how to run it):
<<web-reactive.adoc#webflux-dispatcher-handler, DispatcherHandler>> for how to run it):
====
[source,java,indent=0]
@@ -590,4 +590,5 @@ We allow only the handler function to be executed when access is allowed.
Besides using the `filter` method on the router function builder, it is possible to apply a
filter to an existing router function via `RouterFunction.filter(HandlerFilterFunction)`.
NOTE: CORS support for functional endpoints is provided through a dedicated <<webflux-cors-webfilter,`CorsWebFilter`>>.
NOTE: CORS support for functional endpoints is provided through a dedicated
<<webflux-cors-webfilter, `CorsWebFilter`>>.

View File

@@ -1,6 +1,6 @@
[[webflux-view]]
= View Technologies
[.small]#<<web.adoc#mvc-view,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view, Same as in Spring MVC>>#
The use of view technologies in Spring WebFlux is pluggable. Whether you decide to
use Thymeleaf, FreeMarker, or some other view technology is primarily a matter of a
@@ -12,7 +12,7 @@ WebFlux. We assume you are already familiar with <<webflux-viewresolution>>.
[[webflux-view-thymeleaf]]
== Thymeleaf
[.small]#<<web.adoc#mvc-view-thymeleaf,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-thymeleaf, Same as in Spring MVC>>#
Thymeleaf is a modern server-side Java template engine that emphasizes natural HTML
templates that can be previewed in a browser by double-clicking, which is very
@@ -33,7 +33,7 @@ http://forum.thymeleaf.org/Thymeleaf-3-0-8-JUST-PUBLISHED-td4030687.html[announc
[[webflux-view-freemarker]]
== FreeMarker
[.small]#<<web.adoc#mvc-view-freemarker,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-freemarker, Same as in Spring MVC>>#
http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any
kind of text output from HTML to email and others. The Spring Framework has a built-in
@@ -43,7 +43,7 @@ integration for using Spring WebFlux with FreeMarker templates.
[[webflux-view-freemarker-contextconfig]]
=== View Configuration
[.small]#<<web.adoc#mvc-view-freemarker-contextconfig,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-freemarker-contextconfig, Same as in Spring MVC>>#
The following example shows how to configure FreeMarker as a view technology:
@@ -81,7 +81,7 @@ shown in the preceding example. Given the preceding configuration, if your contr
[[webflux-views-freemarker]]
=== FreeMarker Configuration
[.small]#<<web.adoc#mvc-views-freemarker,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-views-freemarker, Same as in Spring MVC>>#
You can pass FreeMarker 'Settings' and 'SharedVariables' directly to the FreeMarker
`Configuration` object (managed by Spring) by setting the appropriate bean properties on
@@ -121,7 +121,7 @@ the `Configuration` object.
[[webflux-view-script]]
== Script Views
[.small]#<<web.adoc#mvc-view-script,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-script, Same as in Spring MVC>>#
The Spring Framework has a built-in integration for using Spring WebFlux with any
templating library that can run on top of the
@@ -147,7 +147,7 @@ TIP: The basic rule for integrating any other script engine is that it must impl
[[webflux-view-script-dependencies]]
=== Requirements
[.small]#<<web.adoc#mvc-view-script-dependencies,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-script-dependencies, Same as in Spring MVC>>#
You need to have the script engine on your classpath, the details of which vary by script engine:
@@ -167,7 +167,7 @@ through http://www.webjars.org/[WebJars].
[[webflux-view-script-integrate]]
=== Script Templates
[.small]#<<web.adoc#mvc-view-script-integrate,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-script-integrate, Same as in Spring MVC>>#
You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use,
the script files to load, what function to call to render templates, and so on.
@@ -286,20 +286,20 @@ for more configuration examples.
[[webflux-view-httpmessagewriter]]
== JSON and XML
[.small]#<<web.adoc#mvc-view-jackson,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-view-jackson, Same as in Spring MVC>>#
For <<webflux-multiple-representations>> purposes, it is useful to be able to alternate
between rendering a model with an HTML template or as other formats (such as JSON or XML),
depending on the content type requested by the client. To support doing so, Spring WebFlux
provides the `HttpMessageWriterView`, which you can use to plug in any of the available
<<webflux-codecs>> from `spring-web`, such as `Jackson2JsonEncoder`,
`Jackson2SmileEncoder`, or `Jaxb2XmlEncoder`.
<<webflux-codecs>> from `spring-web`, such as `Jackson2JsonEncoder`, `Jackson2SmileEncoder`,
or `Jaxb2XmlEncoder`.
Unlike other view technologies, `HttpMessageWriterView` does not require a `ViewResolver`
but is instead <<webflux-config-view-resolvers,configured>> as a default view. You can
configure one or more such default views, wrapping different `HttpMessageWriter` instances or
`Encoder` instances. The one that matches the requested content type is used at runtime.
but is instead <<webflux-config-view-resolvers, configured>> as a default view. You can
configure one or more such default views, wrapping different `HttpMessageWriter` instances
or `Encoder` instances. The one that matches the requested content type is used at runtime.
In most cases, a model contains multiple attributes. To determine which one
to serialize, you can configure `HttpMessageWriterView` with the name of the model
attribute to use for rendering. If the model contains only one attribute, that one is used.
In most cases, a model contains multiple attributes. To determine which one to serialize,
you can configure `HttpMessageWriterView` with the name of the model attribute to use for
rendering. If the model contains only one attribute, that one is used.

View File

@@ -4,7 +4,7 @@
Spring WebFlux includes a reactive, non-blocking `WebClient` for HTTP requests. The client
has a functional, fluent API with reactive types for declarative composition, see
<<web-reactive.adoc#webflux-reactive-libraries>>. WebFlux client and server rely on the
same non-blocking <<web-reactive.adoc#webflux-codecs,codecs>> to encode and decode request
same non-blocking <<web-reactive.adoc#webflux-codecs, codecs>> to encode and decode request
and response content.
Internally `WebClient` delegates to an HTTP client library. By default, it uses
@@ -36,7 +36,7 @@ You can also use `WebClient.builder()` with further options:
* `exchangeStrategies`: HTTP message reader/writer customizations.
* `clientConnector`: HTTP client library settings.
The following example configures <<web-reactive.adoc#webflux-codecs,HTTP codecs>>:
The following example configures <<web-reactive.adoc#webflux-codecs, HTTP codecs>>:
====
[source,java,intent=0]

View File

@@ -1,6 +1,6 @@
[[webflux-websocket]]
= WebSockets
[.small]#<<web.adoc#websocket,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket, Same as in the Servlet stack>>#
This part of the reference documentation covers support for reactive-stack WebSocket
messaging.
@@ -12,7 +12,7 @@ include::websocket-intro.adoc[leveloffset=+1]
[[webflux-websocket-server]]
== WebSocket API
[.small]#<<web.adoc#websocket-server,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket-server, Same as in the Servlet stack>>#
The Spring Framework provides a WebSocket API that you can use to write client- and
server-side applications that handle WebSocket messages.
@@ -21,7 +21,7 @@ server-side applications that handle WebSocket messages.
[[webflux-websocket-server-handler]]
=== Server
[.small]#<<web.adoc#websocket-server-handler,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket-server-handler, Same as in the Servlet stack>>#
To create a WebSocket server, you can first create a `WebSocketHandler`.
The following example shows how to do so:
@@ -138,7 +138,7 @@ class ExampleHandler implements WebSocketHandler {
TIP: For nested, asynchronous operations, you may need to call `message.retain()` on underlying
servers that use pooled data buffers (for example, Netty). Otherwise, the data buffer may be
released before you have had a chance to read the data. For more background, see
<<core.adoc#databuffers,Data Buffers and Codecs>>.
<<core.adoc#databuffers, Data Buffers and Codecs>>.
The following implementation combines the inbound and outbound streams:
@@ -209,7 +209,7 @@ class ExampleHandler implements WebSocketHandler {
`DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of
the reference has more on that in the section on
<<core#databuffers,Data Buffers and Codecs>>. The key point to understand is that on some
<<core#databuffers, Data Buffers and Codecs>>. The key point to understand is that on some
servers like Netty, byte buffers are pooled and reference counted, and must be released
when consumed to avoid memory leaks.
@@ -222,7 +222,7 @@ subsequently use `DataBufferUtils.release(dataBuffer)` when the buffers are cons
[[webflux-websocket-server-handshake]]
=== Handshake
[.small]#<<web.adoc#websocket-server-handshake,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket-server-handshake, Same as in the Servlet stack>>#
`WebSocketHandlerAdapter` delegates to a `WebSocketService`. By default, that is an instance
of `HandshakeWebSocketService`, which performs basic checks on the WebSocket request and
@@ -237,7 +237,7 @@ into the attributes of the `WebSocketSession`.
[[webflux-websocket-server-config]]
=== Server Configation
[.small]#<<web.adoc#websocket-server-runtime-configuration,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket-server-runtime-configuration, Same as in the Servlet stack>>#
The `RequestUpgradeStrategy` for each server exposes WebSocket-related configuration
options available for the underlying WebSocket engine. The following example sets
@@ -272,7 +272,7 @@ only Tomcat and Jetty expose such options.
[[webflux-websocket-server-cors]]
=== CORS
[.small]#<<web.adoc#websocket-server-allowed-origins,Same as in the Servlet stack>>#
[.small]#<<web.adoc#websocket-server-allowed-origins, Same as in the Servlet stack>>#
The easiest way to configure CORS and restrict access to a WebSocket endpoint is to
have your `WebSocketHandler` implement `CorsConfigurationSource` and return a

View File

@@ -107,8 +107,8 @@ of RxJava or another reactive library. See <<webflux-reactive-libraries>> for mo
=== Programming Models
The `spring-web` module contains the reactive foundation that underlies Spring WebFlux,
including HTTP abstractions, Reactive Streams <<webflux-httphandler,adapters>> for supported
servers, <<webflux-codecs,codecs>>, and a core <<webflux-web-handler-api>> comparable to
including HTTP abstractions, Reactive Streams <<webflux-httphandler, adapters>> for supported
servers, <<webflux-codecs, codecs>>, and a core <<webflux-web-handler-api>> comparable to
the Servlet API but with non-blocking contracts.
On that foundation, Spring WebFlux provides a choice of two programming models:
@@ -167,7 +167,7 @@ RxJava to perform blocking calls on a separate thread but you would not be makin
most of a non-blocking web stack.
* If you have a Spring MVC application with calls to remote services, try the reactive `WebClient`.
You can return reactive types (Reactor, RxJava, <<webflux-reactive-libraries,or other>>)
You can return reactive types (Reactor, RxJava, <<webflux-reactive-libraries, or other>>)
directly from Spring MVC controller methods. The greater the latency per call or the
interdependency among calls, the more dramatic the benefits. Spring MVC controllers
can call other reactive components too.
@@ -186,12 +186,12 @@ unsure what benefits to look for, start by learning about how non-blocking I/O w
Spring WebFlux is supported on Tomcat, Jetty, Servlet 3.1+ containers, as well as on
non-Servlet runtimes such as Netty and Undertow. All servers are adapted to a low-level,
<<webflux-httphandler,common API>> so that higher-level
<<webflux-programming-models,programming models>> can be supported across servers.
<<webflux-httphandler, common API>> so that higher-level
<<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 <<webflux-web-handler-api,assemble>> an application from Spring configuration and
<<webflux-config,WebFlux infrastructure>> and <<webflux-httphandler,run it>> with a few
easy to <<webflux-web-handler-api, assemble>> an application from Spring configuration and
<<webflux-config, WebFlux infrastructure>> and <<webflux-httphandler, run it>> with a few
lines of code.
Spring Boot has a WebFlux starter that automates these steps. By default, the starter uses
@@ -284,11 +284,11 @@ of their own.
.Configuring
The Spring Framework does not provide support for starting and stopping
<<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 <<web-reactive.adoc#webflux-client-builder,configure>> The `WebClient`
directly. For all other
libraries, see their respective documentation.
<<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
<<web-reactive.adoc#webflux-client-builder, configure>> the `WebClient` directly.
For all other libraries, see their respective documentation.
@@ -300,7 +300,7 @@ The `spring-web` module contains the following foundational support for reactive
applications:
* For server request processing there are two levels of support.
** <<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,
Undertow, Tomcat, Jetty, and any Servlet 3.1+ container.
** <<webflux-web-handler-api>>: Slightly higher level, general-purpose web API for
@@ -310,9 +310,9 @@ controllers and functional endpoints are built.
requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for
https://github.com/reactor/reactor-netty[Reactor Netty] and for the reactive
https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient].
The higher level <<web-reactive.adoc#webflux-client,WebClient>> used in applications
The higher level <<web-reactive.adoc#webflux-client, WebClient>> used in applications
builds on this basic contract.
* For client and server, <<webflux-codecs,codecs>> to use to serialize and
* For client and server, <<webflux-codecs, codecs>> to use to serialize and
deserialize HTTP request and response content.
@@ -453,7 +453,7 @@ to provide a general-purpose web API for processing requests through a chain of
{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can
be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring
`ApplicationContext` where components are
<<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
@@ -536,12 +536,12 @@ Mono<MultiValueMap<String, String>> getFormData();
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 <<webflux-web-handler-api,Web Handler API>>).
(see the <<webflux-web-handler-api, Web Handler API>>).
[[webflux-multipart]]
==== Multipart Data
[.small]#<<web.adoc#mvc-multipart,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-multipart, Same as in Spring MVC>>#
`ServerWebExchange` exposes the following method for access to multipart data:
@@ -559,7 +559,7 @@ into a `MultiValueMap`. At present,
https://github.com/synchronoss/nio-multipart[Synchronoss NIO Multipart] is the only
third-party library supported and the only library we know for non-blocking parsing of
multipart requests. It is enabled through the `ServerCodecConfigurer` bean
(see the <<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<Part>` returned from an
`HttpMessageReader<Part>` instead. For example, in an annotated controller, use of
@@ -570,7 +570,7 @@ content to `Flux<Part>` without collecting to a `MultiValueMap`.
[[webflux-forwarded-headers]]
==== Forwarded Headers
[.small]#<<web.adoc#filters-forwarded-headers,Same as in Spring MVC>>#
[.small]#<<web.adoc#filters-forwarded-headers, Same as in Spring MVC>>#
As a request goes through proxies (such as load balancers), the host, port, and
scheme may change, and that makes it a challenge, from a client perspective, to create links that point to the correct
@@ -601,7 +601,7 @@ filters, and `ForwardedHeaderTransformer` is used instead.
[[webflux-filters]]
=== Filters
[.small]#<<web.adoc#filters,Same as in Spring MVC>>#
[.small]#<<web.adoc#filters, Same as in Spring MVC>>#
In the <<webflux-web-handler-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
@@ -612,7 +612,7 @@ the bean declaration or by implementing `Ordered`.
[[webflux-filters-cors]]
==== CORS
[.small]#<<web.adoc#filters-cors,Same as in Spring MVC>>#
[.small]#<<web.adoc#filters-cors, Same as in Spring MVC>>#
Spring WebFlux provides fine-grained support for CORS configuration through annotations on
controllers. However, when you use it with Spring Security, we advise relying on the built-in
@@ -624,7 +624,7 @@ See the section on <<webflux-cors>> and the <<webflux-cors-webfilter>> for more
[[webflux-exception-handler]]
=== Exceptions
[.small]#<<web.adoc#mvc-ann-customer-servlet-container-error-page,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-customer-servlet-container-error-page, Same as in Spring MVC>>#
In the <<webflux-web-handler-api>>, you can use a `WebExceptionHandler` to handle
exceptions from the chain of `WebFilter` instances and the target `WebHandler`. When using the
@@ -655,7 +655,7 @@ The following table describes the available `WebExceptionHandler` implementation
[[webflux-codecs]]
=== Codecs
[.small]#<<integration.adoc#rest-message-conversion,Same as in Spring MVC>>#
[.small]#<<integration.adoc#rest-message-conversion, Same as in Spring MVC>>#
The `spring-web` and `spring-core` modules provide support for serializing and
deserializing byte content to and from higher level objects through non-blocking I/O with
@@ -763,7 +763,7 @@ for repeated, map-like access to parts, or otherwise rely on the
[[webflux-codecs-streaming]]
==== Streaming
[.small]#<<web.adoc#mvc-ann-async-http-streaming,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-async-http-streaming, Same as in Spring MVC>>#
When streaming to the HTTP response (for example, `text/event-stream`,
`application/stream+json`), it is important to send data periodically, in order to
@@ -777,15 +777,15 @@ a heartbeat.
`DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of
the reference has more on that in the section on
<<core#databuffers,Data Buffers and Codecs>>. The key point to understand is that on some
<<core#databuffers, Data Buffers and Codecs>>. The key point to understand is that on some
servers like Netty, byte buffers are pooled and reference counted, and must be released
when consumed to avoid memory leaks.
WebFlux applications generally do not need to be concerned with such issues, unless they
consume or produce data buffers directly, as opposed to relying on codecs to convert to
and from higher level objects. Or unless they choose to create custom codecs. For such
cases please review the the information in <<core#databuffers,Data Buffers and Codecs>>,
especially the section on <<core#databuffers-using,Using DataBuffer>>.
cases please review the the information in <<core#databuffers, Data Buffers and Codecs>>,
especially the section on <<core#databuffers-using, Using DataBuffer>>.
@@ -793,7 +793,7 @@ especially the section on <<core#databuffers-using,Using DataBuffer>>.
[[webflux-logging]]
=== Logging
[.small]#<<web.adoc#mvc-logging,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-logging, Same as in Spring MVC>>#
DEBUG level logging in Spring WebFlux is designed to be compact, minimal, and
human-friendly. It focuses on high value bits of information that are useful over and
@@ -825,7 +825,7 @@ while a fully formatted prefix based on that ID is available from
[[webflux-logging-sensitive-data]]
==== Sensitive Data
[.small]#<<web.adoc#mvc-logging-sensitive-data,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-logging-sensitive-data, Same as in Spring MVC>>#
`DEBUG` and `TRACE` logging can log sensitive information. This is why form parameters and
headers are masked by default and you must explicitly enable their logging in full.
@@ -868,11 +868,11 @@ WebClient webClient = WebClient.builder()
[[webflux-dispatcher-handler]]
== `DispatcherHandler`
[.small]#<<web.adoc#mvc-servlet,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-servlet, Same as in Spring MVC>>#
Spring WebFlux, similarly to Spring MVC, is designed around the front controller pattern, where a
central `WebHandler`, the `DispatcherHandler`, provides a shared algorithm for request
processing, while actual work is performed by configurable, delegate components.
Spring WebFlux, similarly to Spring MVC, is designed around the front controller pattern,
where a central `WebHandler`, the `DispatcherHandler`, provides a shared algorithm for
request processing, while actual work is performed by configurable, delegate components.
This model is flexible and supports diverse workflows.
`DispatcherHandler` discovers the delegate components it needs from Spring configuration.
@@ -880,8 +880,7 @@ It is also designed to be a Spring bean itself and implements `ApplicationContex
for access to the context in which it runs. If `DispatcherHandler` is declared with a bean
name of `webHandler`, it is, in turn, discovered by
{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],
which puts together a request-processing chain, as described in
<<webflux-web-handler-api>>.
which puts together a request-processing chain, as described in <<webflux-web-handler-api>>.
Spring configuration in a WebFlux application typically contains:
@@ -902,14 +901,13 @@ HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context);
----
====
The resulting `HttpHandler` is ready for use with a
<<webflux-httphandler,server adapter>>.
The resulting `HttpHandler` is ready for use with a <<webflux-httphandler, server adapter>>.
[[webflux-special-bean-types]]
=== Special Bean Types
[.small]#<<web.adoc#mvc-servlet-special-bean-types,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-servlet-special-bean-types, Same as in Spring MVC>>#
The `DispatcherHandler` delegates to special beans to process requests and render the
appropriate responses. By "`special beans,`" we mean Spring-managed `Object` instances that
@@ -951,11 +949,11 @@ there are also some other beans detected at a lower level (see
[[webflux-framework-config]]
=== WebFlux Config
[.small]#<<web.adoc#mvc-servlet-config,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-servlet-config, Same as in Spring MVC>>#
Applications can declare the infrastructure beans (listed under
<<webflux-web-handler-api-special-beans,Web Handler API>> and
<<webflux-special-bean-types,`DispatcherHandler`>>) that are required to process requests.
<<webflux-web-handler-api-special-beans, Web Handler API>> and
<<webflux-special-bean-types, `DispatcherHandler`>>) that are required to process requests.
However, in most cases, the <<webflux-config>> is the best starting point. It declares the
required beans and provides a higher-level configuration callback API to customize it.
@@ -966,7 +964,7 @@ many extra convenient options.
[[webflux-dispatcher-handler-sequence]]
=== Processing
[.small]#<<web.adoc#mvc-servlet-sequence,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-servlet-sequence, Same as in Spring MVC>>#
`DispatcherHandler` processes requests as follows:
@@ -1017,7 +1015,7 @@ as a `HandlerResult`, along with some additional context, and passed to the firs
[[webflux-dispatcher-exceptions]]
=== Exceptions
[.small]#<<web.adoc#mvc-exceptionhandlers,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-exceptionhandlers, Same as in Spring MVC>>#
The `HandlerResult` returned from a `HandlerAdapter` can expose a function for error
handling based on some handler-specific mechanism. This error function is called if:
@@ -1040,18 +1038,18 @@ See also <<webflux-ann-controller-exceptions>> in the "`Annotated Controller`" s
[[webflux-viewresolution]]
=== View Resolution
[.small]#<<web.adoc#mvc-viewresolver,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-viewresolver, Same as in Spring MVC>>#
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 <<webflux-resulthandling,HandlerResultHandler>> that uses
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.
[[webflux-viewresolution-handling]]
==== Handling
[.small]#<<web.adoc#mvc-handling,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-handling, Same as in Spring MVC>>#
The `HandlerResult` passed into `ViewResolutionResultHandler` contains the return value
from the handler and the model that contains attributes added during request
@@ -1079,7 +1077,7 @@ value or no value (if empty), while multi-value reactive types (for example, `Fl
collected and resolved to `List<T>`.
To configure view resolution is as simple as adding a `ViewResolutionResultHandler` bean
to your Spring configuration. <<webflux-config-view-resolvers,WebFlux Config>> provides a
to your Spring configuration. <<webflux-config-view-resolvers, WebFlux Config>> provides a
dedicated configuration API for view resolution.
See <<webflux-view>> for more on the view technologies integrated with Spring WebFlux.
@@ -1087,7 +1085,7 @@ See <<webflux-view>> for more on the view technologies integrated with Spring We
[[webflux-redirecting-redirect-prefix]]
==== Redirecting
[.small]#<<web.adoc#mvc-redirecting-redirect-prefix,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-redirecting-redirect-prefix, Same as in Spring MVC>>#
The special `redirect:` prefix in a view name lets you perform a redirect. The
`UrlBasedViewResolver` (and sub-classes) recognize this as an instruction that a
@@ -1102,7 +1100,7 @@ operate in terms of logical view names. A view name such as
[[webflux-multiple-representations]]
==== Content Negotiation
[.small]#<<web.adoc#mvc-multiple-representations,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-multiple-representations, Same as in Spring MVC>>#
`ViewResolutionResultHandler` supports content negotiation. It compares the request
media types with the media types supported by each selected `View`. The first `View`
@@ -1110,8 +1108,8 @@ that supports the requested media type(s) is used.
In order to support media types such as JSON and XML, Spring WebFlux provides
`HttpMessageWriterView`, which is a special `View` that renders through an
<<webflux-codecs,HttpMessageWriter>>. Typically, you would configure these as default
views through the <<webflux-config-view-resolvers,WebFlux Configuration>>. Default views are
<<webflux-codecs, HttpMessageWriter>>. Typically, you would configure these as default
views through the <<webflux-config-view-resolvers, WebFlux Configuration>>. Default views are
always selected and used if they match the requested media type.
@@ -1119,7 +1117,7 @@ always selected and used if they match the requested media type.
[[webflux-controller]]
== Annotated Controllers
[.small]#<<web.adoc#mvc-controller,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-controller, Same as in Spring MVC>>#
Spring WebFlux provides an annotation-based programming model, where `@Controller` and
`@RestController` components use annotations to express request mappings, request input,
@@ -1149,7 +1147,7 @@ In the preceding example, the method returns a `String` to be written to the res
[[webflux-ann-controller]]
=== `@Controller`
[.small]#<<web.adoc#mvc-ann-controller,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-controller, Same as in Spring MVC>>#
You can define controller beans by using a standard Spring bean definition.
The `@Controller` stereotype allows for auto-detection and is aligned with Spring general support
@@ -1174,7 +1172,7 @@ your Java configuration, as the following example shows:
<1> Scan the `org.example.web` package.
====
`@RestController` is a <<core.adoc#beans-meta-annotations,composed annotation>> that is
`@RestController` is a <<core.adoc#beans-meta-annotations, composed annotation>> that is
itself meta-annotated with `@Controller` and `@ResponseBody`, indicating a controller whose
every method inherits the type-level `@ResponseBody` annotation and, therefore, writes
directly to the response body versus view resolution and rendering with an HTML template.
@@ -1183,7 +1181,7 @@ directly to the response body versus view resolution and rendering with an HTML
[[webflux-ann-requestmapping]]
=== Request Mapping
[.small]#<<web.adoc#mvc-ann-requestmapping,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping, Same as in Spring MVC>>#
The `@RequestMapping` annotation is used to map requests to controllers methods. It has
various attributes to match by URL, HTTP method, request parameters, headers, and media
@@ -1230,7 +1228,7 @@ The following example uses type and method level mappings:
[[webflux-ann-requestmapping-uri-templates]]
==== URI Patterns
[.small]#<<web.adoc#mvc-ann-requestmapping-uri-templates,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-uri-templates, Same as in Spring MVC>>#
You can map requests by using glob patterns and wildcards:
@@ -1317,7 +1315,7 @@ explicit, and less vulnerable to URL path based exploits.
[[webflux-ann-requestmapping-pattern-comparison]]
==== Pattern Comparison
[.small]#<<web.adoc#mvc-ann-requestmapping-pattern-comparison,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-pattern-comparison, Same as in Spring MVC>>#
When multiple patterns match a URL, they must be compared to find the best match. This is done
with `PathPattern.SPECIFICITY_COMPARATOR`, which looks for patterns that are more specific.
@@ -1332,7 +1330,7 @@ sorted last instead. If two patterns are both catch-all, the longer is chosen.
[[webflux-ann-requestmapping-consumes]]
==== Consumable Media Types
[.small]#<<web.adoc#mvc-ann-requestmapping-consumes,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-consumes, Same as in Spring MVC>>#
You can narrow the request mapping based on the `Content-Type` of the request,
as the following example shows:
@@ -1361,7 +1359,7 @@ TIP: `MediaType` provides constants for commonly used media types -- for example
[[webflux-ann-requestmapping-produces]]
==== Producible Media Types
[.small]#<<web.adoc#mvc-ann-requestmapping-produces,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-produces, Same as in Spring MVC>>#
You can narrow the request mapping based on the `Accept` request header and the list of
content types that a controller method produces, as the following example shows:
@@ -1396,7 +1394,7 @@ TIP: `MediaType` provides constants for commonly used media types -- e.g.
[[webflux-ann-requestmapping-params-and-headers]]
==== Parameters and Headers
[.small]#<<web.adoc#mvc-ann-requestmapping-params-and-headers,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-params-and-headers, Same as in Spring MVC>>#
You can narrow request mappings based on query parameter conditions. You can test for the
presence of a query parameter (`myParam`), for its absence (`!myParam`), or for a
@@ -1431,7 +1429,7 @@ You can also use the same with request header conditions, as the follwing exampl
[[webflux-ann-requestmapping-head-options]]
==== HTTP HEAD, OPTIONS
[.small]#<<web.adoc#mvc-ann-requestmapping-head-options,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-head-options, Same as in Spring MVC>>#
`@GetMapping` and `@RequestMapping(method=HttpMethod.GET)` support HTTP HEAD
transparently for request mapping purposes. Controller methods need not change.
@@ -1452,9 +1450,9 @@ is not necessary in the common case.
[[webflux-ann-requestmapping-composed]]
==== Custom Annotations
[.small]#<<web.adoc#mvc-ann-requestmapping-composed,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-composed, Same as in Spring MVC>>#
Spring WebFlux supports the use of <<core.adoc#beans-meta-annotations,composed annotations>>
Spring WebFlux supports the use of <<core.adoc#beans-meta-annotations, composed annotations>>
for request mapping. Those are annotations that are themselves meta-annotated with
`@RequestMapping` and composed to redeclare a subset (or all) of the `@RequestMapping`
attributes with a narrower, more specific purpose.
@@ -1473,7 +1471,7 @@ you can check the custom attribute and return your own `RequestCondition`.
[[webflux-ann-requestmapping-registration]]
==== Explicit Registrations
[.small]#<<web.adoc#mvc-ann-requestmapping-registration,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestmapping-registration, Same as in Spring MVC>>#
You can programmatically register Handler methods, which can be used for dynamic
registrations or for advanced cases, such as different instances of the same handler
@@ -1510,7 +1508,7 @@ public class MyConfig {
[[webflux-ann-methods]]
=== Handler Methods
[.small]#<<web.adoc#mvc-ann-methods,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-methods, Same as in Spring MVC>>#
`@RequestMapping` handler methods have a flexible signature and can choose from a range of
supported controller method arguments and return values.
@@ -1518,11 +1516,11 @@ supported controller method arguments and return values.
[[webflux-ann-arguments]]
==== Method Arguments
[.small]#<<web.adoc#mvc-ann-arguments,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-arguments, Same as in Spring MVC>>#
The following table shows the supported controller method arguments.
Reactive types (Reactor, RxJava, <<webflux-reactive-libraries,or other>>) are
Reactive types (Reactor, RxJava, <<webflux-reactive-libraries, or other>>) are
supported on arguments that require blocking I/O (for example, reading the request body) to
be resolved. This is marked in the Description column. Reactive types are not expected
on arguments that do not require blocking.
@@ -1639,10 +1637,10 @@ and others) and is equivalent to `required=false`.
[[webflux-ann-return-types]]
==== Return Values
[.small]#<<web.adoc#mvc-ann-return-types,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-return-types, Same as in Spring MVC>>#
The following table shows the supported controller method return values. Note that reactive types
from libraries such as Reactor, RxJava, <<webflux-reactive-libraries,or other>> are
The following table shows the supported controller method return values. Note that reactive
types from libraries such as Reactor, RxJava, <<webflux-reactive-libraries, or other>> are
generally supported for all return values.
[cols="1,2", options="header"]
@@ -1665,12 +1663,13 @@ generally supported for all return values.
| A view name to be resolved with `ViewResolver` instances and used together with the implicit
model -- determined through command objects and `@ModelAttribute` methods. The handler
method can also programmatically enrich the model by declaring a `Model` argument
(described <<webflux-viewresolution-handling,earlier>>).
(described <<webflux-viewresolution-handling, earlier>>).
| `View`
| A `View` instance to use for rendering together with the implicit model -- determined
through command objects and `@ModelAttribute` methods. The handler method can also
programmatically enrich the model by declaring a `Model` argument (described <<webflux-viewresolution-handling,earlier>>).
programmatically enrich the model by declaring a `Model` argument
(described <<webflux-viewresolution-handling, earlier>>).
| `java.util.Map`, `org.springframework.ui.Model`
| Attributes to be added to the implicit model, with the view name implicitly determined
@@ -1712,7 +1711,7 @@ generally supported for all return values.
[[webflux-ann-typeconversion]]
==== Type Conversion
[.small]#<<web.adoc#mvc-ann-typeconversion,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-typeconversion, Same as in Spring MVC>>#
Some annotated controller method arguments that represent String-based request input (for example,
`@RequestParam`, `@RequestHeader`, `@PathVariable`, `@MatrixVariable`, and `@CookieValue`)
@@ -1721,13 +1720,12 @@ can require type conversion if the argument is declared as something other than
For such cases, type conversion is automatically applied based on the configured converters.
By default, simple types (such as `int`, `long`, `Date`, and others) are supported. Type conversion
can be customized through a `WebDataBinder` (see <<mvc-ann-initbinder>>) or by registering
`Formatters` with the `FormattingConversionService` (see
<<core.adoc#format, Spring Field Formatting>>).
`Formatters` with the `FormattingConversionService` (see <<core.adoc#format, Spring Field Formatting>>).
[[webflux-ann-matrix-variables]]
==== Matrix Variables
[.small]#<<web.adoc#mvc-ann-matrix-variables,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-matrix-variables, Same as in Spring MVC>>#
http://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in
path segments. In Spring WebFlux, we refer to those as "`matrix variables`" based on an
@@ -1820,7 +1818,7 @@ To get all matrix variables, use a `MultiValueMap`, as the following example sho
[[webflux-ann-requestparam]]
==== `@RequestParam`
[.small]#<<web.adoc#mvc-ann-requestparam,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestparam, Same as in Spring MVC>>#
You can use the `@RequestParam` annotation to bind query parameters to a method argument in a
controller. The following code snippet shows the usage:
@@ -1853,7 +1851,7 @@ TIP: The Servlet API "`request parameter`" concept conflates query parameters, f
data, and multiparts into one. However, in WebFlux, each is accessed individually through
`ServerWebExchange`. While `@RequestParam` binds to query parameters only, you can use
data binding to apply query parameters, form data, and multiparts to a
<<webflux-ann-modelattrib-method-args,command object>>.
<<webflux-ann-modelattrib-method-args, command object>>.
Method parameters that use the `@RequestParam` annotation are required by default, but
you can specify that a method parameter is optional by setting the required flag of a `@RequestParam`
@@ -1875,7 +1873,7 @@ with `@RequestParam`.
[[webflux-ann-requestheader]]
==== `@RequestHeader`
[.small]#<<web.adoc#mvc-ann-requestheader,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestheader, Same as in Spring MVC>>#
You can use the `@RequestHeader` annotation to bind a request header to a method argument in a
controller.
@@ -1927,7 +1925,7 @@ example, a method parameter annotated with `@RequestHeader("Accept")` may be of
[[webflux-ann-cookievalue]]
==== `@CookieValue`
[.small]#<<web.adoc#mvc-ann-cookievalue,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-cookievalue, Same as in Spring MVC>>#
You can use the `@CookieValue` annotation to bind the value of an HTTP cookie to a method argument
in a controller.
@@ -1962,7 +1960,7 @@ Type conversion is applied automatically if the target method parameter type is
[[webflux-ann-modelattrib-method-args]]
==== `@ModelAttribute`
[.small]#<<web.adoc#mvc-ann-modelattrib-method-args,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-modelattrib-method-args, Same as in Spring MVC>>#
You can use the `@ModelAttribute` annotation on a method argument to access an attribute from the
model or have it instantiated if not present. The model attribute is also overlain with
@@ -2017,7 +2015,7 @@ immediately next to the `@ModelAttribute`, as the following example shows:
You can automatically apply validation after data binding by adding the
`javax.validation.Valid` annotation or Spring's `@Validated` annotation (see also
<<core.adoc#validation-beanvalidation, Bean validation>> and
<<core.adoc#validation-beanvalidation, Bean Validation>> and
<<core.adoc#validation, Spring validation>>). The following example uses the `@Valid` annotation:
====
@@ -2069,7 +2067,7 @@ with `@ModelAttribute`.
[[webflux-ann-sessionattributes]]
==== `@SessionAttributes`
[.small]#<<web.adoc#mvc-ann-sessionattributes,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-sessionattributes, Same as in Spring MVC>>#
`@SessionAttributes` is used to store model attributes in the `WebSession` between
requests. It is a type-level annotation that declares session attributes used by a
@@ -2125,7 +2123,7 @@ as the following example shows:
[[webflux-ann-sessionattribute]]
==== `@SessionAttribute`
[.small]#<<web.adoc#mvc-ann-sessionattribute,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-sessionattribute, Same as in Spring MVC>>#
If you need access to pre-existing session attributes that are managed globally
(that is, outside the controller -- for example, by a filter) and may or may not be present,
@@ -2153,7 +2151,7 @@ workflow, consider using `SessionAttributes`, as described in
[[webflux-ann-requestattrib]]
==== `@RequestAttribute`
[.small]#<<web.adoc#mvc-ann-requestattrib,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestattrib, Same as in Spring MVC>>#
Similarly to `@SessionAttribute`, you can use the `@RequestAttribute` annotation to
access pre-existing request attributes created earlier (for example, by a `WebFilter`),
@@ -2174,11 +2172,11 @@ as the following example shows:
[[webflux-multipart-forms]]
==== Multipart Content
[.small]#<<web.adoc#mvc-multipart-forms,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-multipart-forms, Same as in Spring MVC>>#
As explained in <<webflux-multipart>>, `ServerWebExchange` provides access to multipart
content. The best way to handle a file upload form (for example, from a browser) in a controller
is through data binding to a <<webflux-ann-modelattrib-method-args,command object>>,
is through data binding to a <<webflux-ann-modelattrib-method-args, command object>>,
as the following example shows:
====
@@ -2317,7 +2315,7 @@ To access multipart data sequentially, in streaming fashion, you can use `@Reque
[[webflux-ann-requestbody]]
==== `@RequestBody`
[.small]#<<web.adoc#mvc-ann-requestbody,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-requestbody, Same as in Spring MVC>>#
You can use the `@RequestBody` annotation to have the request body read and deserialized into an
`Object` through an <<webflux-codecs,HttpMessageReader>>.
@@ -2373,7 +2371,7 @@ example uses a `BindingResult` argument`:
[[webflux-ann-httpentity]]
==== `HttpEntity`
[.small]#<<web.adoc#mvc-ann-httpentity,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-httpentity, Same as in Spring MVC>>#
`HttpEntity` is more or less identical to using <<webflux-ann-requestbody>> but is based on a
container object that exposes request headers and the body. The following example uses an
@@ -2393,10 +2391,11 @@ container object that exposes request headers and the body. The following exampl
[[webflux-ann-responsebody]]
==== `@ResponseBody`
[.small]#<<web.adoc#mvc-ann-responsebody,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-responsebody, Same as in Spring MVC>>#
You can use the `@ResponseBody` annotation on a method to have the return serialized to the
response body through an <<webflux-codecs,HttpMessageWriter>>. The following example shows how to do so:
You can use the `@ResponseBody` annotation on a method to have the return serialized
to the response body through an <<webflux-codecs, HttpMessageWriter>>. The following
example shows how to do so:
====
[source,java,indent=0]
@@ -2428,7 +2427,7 @@ configure or customize message writing.
[[webflux-ann-responseentity]]
==== `ResponseEntity`
[.small]#<<web.adoc#mvc-ann-responseentity,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-responseentity, Same as in Spring MVC>>#
`ResponseEntity` is like <<webflux-ann-responsebody>> but with status and headers. For example:
@@ -2445,7 +2444,7 @@ configure or customize message writing.
----
====
WebFlux supports using a single value <<webflux-reactive-libraries,reactive type>> to
WebFlux supports using a single value <<webflux-reactive-libraries, reactive type>> to
produce the `ResponseEntity` asynchronously, and/or single and multi-value reactive types
for the body.
@@ -2457,7 +2456,7 @@ Spring offers support for the Jackson JSON library.
[[webflux-ann-jsonview]]
===== JSON Views
[.small]#<<web.adoc#mvc-ann-jackson,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-jackson, Same as in Spring MVC>>#
Spring WebFlux provides built-in support for
http://wiki.fasterxml.com/JacksonJsonViews[Jackson's Serialization Views],
@@ -2515,11 +2514,11 @@ controller method. Use a composite interface if you need to activate multiple vi
[[webflux-ann-modelattrib-methods]]
=== `Model`
[.small]#<<web.adoc#mvc-ann-modelattrib-methods,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-modelattrib-methods, Same as in Spring MVC>>#
You can use the `@ModelAttribute` annotation:
* On a <<webflux-ann-modelattrib-method-args,method argument>> in `@RequestMapping` methods
* On a <<webflux-ann-modelattrib-method-args, method argument>> in `@RequestMapping` methods
to create or access an Object from the model and to bind it to the request through a
`WebDataBinder`.
* As a method-level annotation in `@Controller` or `@ControllerAdvice` classes, helping
@@ -2618,7 +2617,7 @@ as the following example shows:
[[webflux-ann-initbinder]]
=== `DataBinder`
[.small]#<<web.adoc#mvc-ann-initbinder,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-initbinder, Same as in Spring MVC>>#
`@Controller` or `@ControllerAdvice` classes can have `@InitBinder` methods, to
initialize instances of `WebDataBinder`. Those, in turn, are used to:
@@ -2630,7 +2629,7 @@ headers, cookies, and others) to the target type of controller method arguments.
`@InitBinder` methods can register controller-specific `java.bean.PropertyEditor` or
Spring `Converter` and `Formatter` components. In addition, you can use the
<<webflux-config-conversion,WebFlux Java configuration>> to register `Converter` and
<<webflux-config-conversion, WebFlux Java configuration>> to register `Converter` and
`Formatter` types in a globally shared `FormattingConversionService`.
`@InitBinder` methods support many of the same arguments that `@RequestMapping` methods
@@ -2684,9 +2683,9 @@ controller-specific `Formatter` instances, as the following example shows:
[[webflux-ann-controller-exceptions]]
=== Managing Exceptions
[.small]#<<web.adoc#mvc-ann-exceptionhandler,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-exceptionhandler, Same as in Spring MVC>>#
`@Controller` and <<mvc-ann-controller-advice,@ControllerAdvice>> classes can have
`@Controller` and <<mvc-ann-controller-advice, @ControllerAdvice>> classes can have
`@ExceptionHandler` methods to handle exceptions from controller methods. The following
example includes such a handler method:
@@ -2709,14 +2708,15 @@ example includes such a handler method:
====
The exception can match against a top-level exception being propagated (that is, a direct
`IOException` being thrown) or against the immediate cause within a top-level wrapper exception
(for example, an `IOException` wrapped inside an `IllegalStateException`).
`IOException` being thrown) or against the immediate cause within a top-level wrapper
exception (for example, an `IOException` wrapped inside an `IllegalStateException`).
For matching exception types, preferably declare the target exception as a method argument,
as shown in the preceding example. Alternatively, the annotation declaration can narrow the exception types to
match. We generally recommend being as specific as possible in the argument signature and to
declare your primary root exception mappings on a `@ControllerAdvice` prioritized with a
corresponding order. See <<web.adoc#mvc-ann-exceptionhandler,the MVC section>> for details.
as shown in the preceding example. Alternatively, the annotation declaration can narrow the
exception types to match. We generally recommend being as specific as possible in the
argument signature and to declare your primary root exception mappings on a
`@ControllerAdvice` prioritized with a corresponding order.
See <<web.adoc#mvc-ann-exceptionhandler, the MVC section>> for details.
NOTE: An `@ExceptionHandler` method in WebFlux supports the same method arguments and
return values as a `@RequestMapping` method, with the exception of request body-
@@ -2729,7 +2729,7 @@ for more detail.
[[webflux-ann-rest-exceptions]]
==== REST API exceptions
[.small]#<<web.adoc#mvc-ann-rest-exceptions,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-rest-exceptions, Same as in Spring MVC>>#
A common requirement for REST services is to include error details in the body of the
response. The Spring Framework does not automatically do so, because the representation
@@ -2747,7 +2747,7 @@ an HTTP status code.
[[webflux-ann-controller-advice]]
=== Controller Advice
[.small]#<<web.adoc#mvc-ann-controller-advice,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-ann-controller-advice, Same as in Spring MVC>>#
Typically, the `@ExceptionHandler`, `@InitBinder`, and `@ModelAttribute` methods apply within
the `@Controller` class (or class hierarchy) in which they are declared. If you want such
@@ -2755,7 +2755,7 @@ methods to apply more globally (across controllers), you can declare them in a c
marked with `@ControllerAdvice` or `@RestControllerAdvice`.
`@ControllerAdvice` is marked with `@Component`, which means that such classes can be registered
as Spring beans through <<core.adoc#beans-java-instantiating-container-scan,component scanning>>.
as Spring beans through <<core.adoc#beans-java-instantiating-container-scan, component scanning>>.
`@RestControllerAdvice` is also a meta-annotation marked with both `@ControllerAdvice` and
`@ResponseBody`, which essentially means `@ExceptionHandler` methods are rendered to the
response body through message conversion (versus view resolution or template rendering).
@@ -2800,7 +2800,7 @@ include::webflux-functional.adoc[leveloffset=+1]
[[webflux-uri-building]]
== URI Links
[.small]#<<web.adoc#mvc-uri-building,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-uri-building, Same as in Spring MVC>>#
This section describes various options available in the Spring Framework to prepare URIs.
@@ -2813,7 +2813,7 @@ include::webflux-cors.adoc[leveloffset=+1]
[[webflux-web-security]]
== Web Security
[.small]#<<web.adoc#mvc-web-security,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-web-security, Same as in Spring MVC>>#
The http://projects.spring.io/spring-security/[Spring Security] project provides support
for protecting web applications from malicious exploits. See the Spring Security
@@ -2831,7 +2831,7 @@ include::webflux-view.adoc[leveloffset=+1]
[[webflux-caching]]
== HTTP Caching
[.small]#<<web.adoc#mvc-caching,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-caching, Same as in Spring MVC>>#
HTTP caching can significantly improve the performance of a web application. HTTP caching
revolves around the `Cache-Control` response header and subsequent conditional request
@@ -2847,7 +2847,7 @@ This section describes the HTTP caching related options available in Spring WebF
[[webflux-caching-cachecontrol]]
=== `CacheControl`
[.small]#<<web.adoc#mvc-caching-cachecontrol,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-caching-cachecontrol, Same as in Spring MVC>>#
{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for
configuring settings related to the `Cache-Control` header and is accepted as an argument
@@ -2881,7 +2881,7 @@ use case-oriented approach that focuses on the common scenarios, as the followin
[[webflux-caching-etag-lastmodified]]
=== Controllers
[.small]#<<web.adoc#mvc-caching-etag-lastmodified,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-caching-etag-lastmodified, Same as in Spring MVC>>#
Controllers can add explicit support for HTTP caching. We recommend doing so, since the
`lastModified` or `ETag` value for a resource needs to be calculated before it can be compared
@@ -2946,7 +2946,7 @@ to 409 (PRECONDITION_FAILED) to prevent concurrent modification.
[[webflux-caching-static-resources]]
=== Static Resources
[.small]#<<web.adoc#mvc-caching-static-resources,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-caching-static-resources, Same as in Spring MVC>>#
You should serve static resources with a `Cache-Control` and conditional response headers
for optimal performance. See the section on configuring <<webflux-config-static-resources>>.
@@ -2956,13 +2956,14 @@ for optimal performance. See the section on configuring <<webflux-config-static-
[[webflux-config]]
== WebFlux Config
[.small]#<<web.adoc#mvc-config,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config, Same as in Spring MVC>>#
The WebFlux Java configuration declares the components that are required to process requests with annotated
controllers or functional endpoints, and it offers an API to customize the configuration.
That means you do not need to understand the underlying beans created by the Java configuration.
However, if you want to understand them, you can see them in `WebFluxConfigurationSupport` or read more
about what they are in <<webflux-special-bean-types>>.
The WebFlux Java configuration declares the components that are required to process
requests with annotated controllers or functional endpoints, and it offers an API to
customize the configuration. That means you do not need to understand the underlying
beans created by the Java configuration. However, if you want to understand them,
you can see them in `WebFluxConfigurationSupport` or read more about what they are
in <<webflux-special-bean-types>>.
For more advanced customizations, not available in the configuration API, you can
gain full control over the configuration through the
@@ -2972,7 +2973,7 @@ gain full control over the configuration through the
[[webflux-config-enable]]
=== Enabling WebFlux Config
[.small]#<<web.adoc#mvc-config-enable,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-enable, Same as in Spring MVC>>#
You can use the `@EnableWebFlux` annotation in your Java config, as the following example shows:
@@ -2988,14 +2989,14 @@ You can use the `@EnableWebFlux` annotation in your Java config, as the followin
====
The preceding example registers a number of Spring WebFlux
<<mvc-webflux-special-bean-types,infrastructure beans>> and adapts to dependencies
<<mvc-webflux-special-bean-types, infrastructure beans>> and adapts to dependencies
available on the classpath -- for JSON, XML, and others.
[[webflux-config-customize]]
=== WebFlux config API
[.small]#<<web.adoc#mvc-config-customize,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-customize, Same as in Spring MVC>>#
In your Java configuration, you can implement the `WebFluxConfigurer` interface,
as the following example shows:
@@ -3018,7 +3019,7 @@ as the following example shows:
[[webflux-config-conversion]]
=== Conversion, formatting
[.small]#<<web.adoc#mvc-config-conversion,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-conversion, Same as in Spring MVC>>#
By default, formatters for `Number` and `Date` types are installed, including support for
the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time
@@ -3043,19 +3044,20 @@ The following example shows how to register custom formatters and converters:
----
====
NOTE: See <<core.adoc#format-FormatterRegistrar-SPI,`FormatterRegistrar` SPI>>
and the `FormattingConversionServiceFactoryBean` for more information on when to use `FormatterRegistrar` implementations.
NOTE: See <<core.adoc#format-FormatterRegistrar-SPI, `FormatterRegistrar` SPI>>
and the `FormattingConversionServiceFactoryBean` for more information on when to
use `FormatterRegistrar` implementations.
[[webflux-config-validation]]
=== Validation
[.small]#<<web.adoc#mvc-config-validation,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-validation, Same as in Spring MVC>>#
By default, if <<core.adoc#validation-beanvalidation-overview,Bean Validation>> is present
on the classpath (for example, the Hibernate Validator), the `LocalValidatorFactoryBean` is registered
as a global <<core.adoc#validator,validator>> for use with `@Valid` and `Validated` on
`@Controller` method arguments.
By default, if <<core.adoc#validation-beanvalidation-overview, Bean Validation>> is present
on the classpath (for example, the Hibernate Validator), the `LocalValidatorFactoryBean`
is registered as a global <<core.adoc#validator,validator>> for use with `@Valid` and
`Validated` on `@Controller` method arguments.
In your Java configuration, you can customize the global `Validator` instance,
as the following example shows:
@@ -3103,11 +3105,11 @@ mark it with `@Primary` in order to avoid conflict with the one declared in the
[[webflux-config-content-negotiation]]
=== Content Type Resolvers
[.small]#<<web.adoc#mvc-config-content-negotiation,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-content-negotiation, Same as in Spring MVC>>#
You can configure how Spring WebFlux determines the requested media types for
`@Controller` instances from the request. By default, only the `Accept` header is checked, but you
can also enable a query parameter-based strategy.
`@Controller` instances from the request. By default, only the `Accept` header is checked,
but you can also enable a query parameter-based strategy.
The following example shows how to customize the requested content type resolution:
@@ -3131,7 +3133,7 @@ The following example shows how to customize the requested content type resoluti
[[webflux-config-message-codecs]]
=== HTTP message codecs
[.small]#<<web.adoc#mvc-config-message-converters,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-message-converters, Same as in Spring MVC>>#
The following example shows how to customize how the request and response body are read and written:
@@ -3172,7 +3174,7 @@ It also automatically registers the following well-known modules if they are det
[[webflux-config-view-resolvers]]
=== View Resolvers
[.small]#<<web.adoc#mvc-config-view-resolvers,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-view-resolvers, Same as in Spring MVC>>#
The following example shows how to configure view resolution:
@@ -3275,7 +3277,7 @@ See <<webflux-view>> for more on the view technologies that are integrated with
[[webflux-config-static-resources]]
=== Static Resources
[.small]#<<web.adoc#mvc-config-static-resources,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-static-resources, Same as in Spring MVC>>#
This option provides a convenient way to serve static resources from a list of
{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.
@@ -3363,7 +3365,7 @@ match to incoming URLs without versions (for example, `/jquery/jquery.min.js` to
[[webflux-config-path-matching]]
=== Path Matching
[.small]#<<web.adoc#mvc-config-path-matching,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-path-matching, Same as in Spring MVC>>#
You can customize options related to path matching. For details on the individual options, see the
{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.
@@ -3399,7 +3401,7 @@ whether to decode the request path nor whether to remove semicolon content for
path matching purposes.
Spring WebFlux also does not support suffix pattern matching, unlike in Spring MVC, where we
are also <<web.adoc#mvc-ann-requestmapping-suffix-pattern-match,recommend>> moving away from
are also <<web.adoc#mvc-ann-requestmapping-suffix-pattern-match, recommend>> moving away from
reliance on it.
====
@@ -3407,7 +3409,7 @@ reliance on it.
[[webflux-config-advanced-java]]
=== Advanced Configuration Mode
[.small]#<<web.adoc#mvc-config-advanced-java,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-config-advanced-java, Same as in Spring MVC>>#
`@EnableWebFlux` imports `DelegatingWebFluxConfiguration` that:
@@ -3441,7 +3443,7 @@ the classpath.
[[webflux-http2]]
== HTTP/2
[.small]#<<web.adoc#mvc-http2,Same as in Spring MVC>>#
[.small]#<<web.adoc#mvc-http2, Same as in Spring MVC>>#
Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is compatible
with Servlet API 4. From a programming model perspective, there is nothing specific that

View File

@@ -15,12 +15,12 @@ libraries.
NOTE: As of 5.0, the non-blocking, reactive `WebClient` offers a modern alternative to the
`RestTemplate`, with efficient support for both
<<web-reactive.adoc#webflux-client-synchronous,synchronous and asynchronous>>, as well as
<<web-reactive.adoc#webflux-client-synchronous, synchronous and asynchronous>>, as well as
streaming scenarios. The `RestTemplate` will be deprecated in a future version and will
not have major new features added going forward.
See <<integration.adoc#rest-client-access,REST Endpoints>> for details.
See <<integration.adoc#rest-client-access, REST Endpoints>> for details.
@@ -41,4 +41,4 @@ In contrast to `RestTemplate`, `WebClient` supports the following:
* Synchronous and asynchronous interactions.
* Streaming up to or streaming down from a server.
See <<web-reactive.adoc#webflux-client,WebClient>> for more details.
See <<web-reactive.adoc#webflux-client, WebClient>> for more details.

View File

@@ -1,6 +1,6 @@
[[mvc-cors]]
= CORS
[.small]#<<web-reactive.adoc#webflux-cors,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors, Same as in Spring WebFlux>>#
Spring MVC lets you handle CORS (Cross-Origin Resource Sharing). This section
describes how to do so.
@@ -10,7 +10,7 @@ describes how to do so.
[[mvc-cors-intro]]
== Introduction
[.small]#<<web-reactive.adoc#webflux-cors-intro,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-intro, Same as in Spring WebFlux>>#
For security reasons, browsers prohibit AJAX calls to resources outside the current origin.
For example, you could have your bank account in one tab and evil.com in another. Scripts
@@ -27,7 +27,7 @@ powerful workarounds based on IFRAME or JSONP.
[[mvc-cors-processing]]
== Processing
[.small]#<<web-reactive.adoc#webflux-cors-processing,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-processing, Same as in Spring WebFlux>>#
The CORS specification distinguishes between preflight, simple, and actual requests.
To learn how CORS works, you can read
@@ -77,7 +77,7 @@ To learn more from the source or make advanced customizations, check the code be
[[mvc-cors-controller]]
== `@CrossOrigin`
[.small]#<<web-reactive.adoc#webflux-cors-controller,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-controller, Same as in Spring WebFlux>>#
The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]
annotation enables cross-origin requests on annotated controller methods,
@@ -173,7 +173,7 @@ public class AccountController {
[[mvc-cors-global]]
== Global Configuration
[.small]#<<web-reactive.adoc#webflux-cors-global,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-global, Same as in Spring WebFlux>>#
In addition to fine-grained, controller method level configuration, you probably want to
define some global CORS configuration, too. You can set URL-based `CorsConfiguration`
@@ -197,7 +197,7 @@ should only be used where appropriate.
[[mvc-cors-global-java]]
=== Java Configuration
[.small]#<<web-reactive.adoc#webflux-cors-global,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-global, Same as in Spring WebFlux>>#
To enable CORS in the MVC Java config, you can use the `CorsRegistry` callback,
as the following example shows:
@@ -259,13 +259,13 @@ as the following example shows:
[[mvc-cors-filter]]
== CORS Filter
[.small]#<<web-reactive.adoc#webflux-cors-webfilter,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-cors-webfilter, Same as in Spring WebFlux>>#
You can apply CORS support through the built-in
{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].
NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring
Security has
NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that
Spring Security has
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors[built-in support]
for CORS.

View File

@@ -1,26 +1,26 @@
[[testing]]
= Testing
[.small]#<<web-reactive.adoc#webflux-test,Same in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-test, Same in Spring WebFlux>>#
This section summarizes the options available in `spring-test` for Spring MVC applications.
* Servlet API Mocks: Mock implementations of Servlet API contracts for unit testing controllers, filters, and
other web components. See <<testing.adoc#mock-objects-servlet,Servlet API>> mock objects
for more details.
* Servlet API Mocks: Mock implementations of Servlet API contracts for unit testing controllers,
filters, and other web components. See <<testing.adoc#mock-objects-servlet, Servlet API>>
mock objects for more details.
* TestContext Framework: Support for loading Spring configuration in JUnit and TestNG tests, including efficient
caching of the loaded configuration across test methods and support for loading a
`WebApplicationContext` with a `MockServletContext`.
* TestContext Framework: Support for loading Spring configuration in JUnit and TestNG tests,
including efficient caching of the loaded configuration across test methods and support for
loading a `WebApplicationContext` with a `MockServletContext`.
See <<testing.adoc#testcontext-framework,TestContext Framework>> for more details.
* Spring MVC Test: A framework, also known as `MockMvc`, for testing annotated controllers through the
`DispatcherServlet` (that is, supporting annotations), complete with the Spring MVC
infrastructure but without an HTTP server. See
<<testing.adoc#spring-mvc-test-framework,Spring MVC Test>> for more details.
* Spring MVC Test: A framework, also known as `MockMvc`, for testing annotated controllers
through the `DispatcherServlet` (that is, supporting annotations), complete with the
Spring MVC infrastructure but without an HTTP server.
See <<testing.adoc#spring-mvc-test-framework, Spring MVC Test>> for more details.
* Client-side REST: `spring-test` provides a `MockRestServiceServer` that you can use as a mock server for
testing client-side code that internally uses the `RestTemplate`.
See <<testing.adoc#spring-mvc-test-client,Client REST Tests>> for more details.
* Client-side REST: `spring-test` provides a `MockRestServiceServer` that you can use as
a mock server for testing client-side code that internally uses the `RestTemplate`.
See <<testing.adoc#spring-mvc-test-client, Client REST Tests>> for more details.
* `WebTestClient`: Built for testing WebFlux applications, but it can also be used for
end-to-end integration testing, to any server, over an HTTP connection. It is a

View File

@@ -1,18 +1,18 @@
[[mvc-view]]
= View Technologies
[.small]#<<web-reactive.adoc#webflux-view,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view, Same as in Spring WebFlux>>#
The use of view technologies in Spring MVC is pluggable, whether you decide to
use Thymeleaf, Groovy Markup Templates, JSPs, or other technologies, is primarily a matter of a
configuration change. This chapter covers view technologies integrated with Spring MVC.
We assume you are already familiar with <<mvc-viewresolver>>.
The use of view technologies in Spring MVC is pluggable, whether you decide to use
Thymeleaf, Groovy Markup Templates, JSPs, or other technologies, is primarily a matter
of a configuration change. This chapter covers view technologies integrated with
Spring MVC. We assume you are already familiar with <<mvc-viewresolver>>.
[[mvc-view-thymeleaf]]
== Thymeleaf
[.small]#<<web-reactive.adoc#webflux-view-thymeleaf,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-thymeleaf, Same as in Spring WebFlux>>#
Thymeleaf is a modern server-side Java template engine that emphasizes natural HTML
templates that can be previewed in a browser by double-clicking, which is very helpful
@@ -32,7 +32,7 @@ See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more detai
[[mvc-view-freemarker]]
== FreeMarker
[.small]#<<web-reactive.adoc#webflux-view-freemarker,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-freemarker, Same as in Spring WebFlux>>#
http://www.freemarker.org[Apache FreeMarker] is a template engine for generating any
kind of text output from HTML to email and others. The Spring Framework has a built-in
@@ -42,7 +42,7 @@ integration for using Spring MVC with FreeMarker templates.
[[mvc-view-freemarker-contextconfig]]
=== View Configuration
[.small]#<<web-reactive.adoc#webflux-view-freemarker-contextconfig,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-freemarker-contextconfig, Same as in Spring WebFlux>>#
The following example shows how to configure FreeMarker as a view technology:
@@ -111,7 +111,7 @@ of `welcome`, the resolver looks for the `/WEB-INF/freemarker/welcome.ftl` templ
[[mvc-views-freemarker]]
=== FreeMarker Configuration
[.small]#<<web-reactive.adoc#webflux-views-freemarker,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-views-freemarker, Same as in Spring WebFlux>>#
You can pass FreeMarker 'Settings' and 'SharedVariables' directly to the FreeMarker
`Configuration` object (which is managed by Spring) by setting the appropriate bean properties on
@@ -568,7 +568,7 @@ syntax. The following example shows a sample template for an HTML page:
[[mvc-view-script]]
== Script Views
[.small]#<<web-reactive.adoc#webflux-view-script,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-script, Same as in Spring WebFlux>>#
The Spring Framework has a built-in integration for using Spring MVC with any
templating library that can run on top of the
@@ -594,7 +594,7 @@ TIP: The basic rule for integrating any other script engine is that it must impl
[[mvc-view-script-dependencies]]
=== Requirements
[.small]#<<web-reactive.adoc#webflux-view-script-dependencies,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-script-dependencies, Same as in Spring WebFlux>>#
You need to have the script engine on your classpath, the details of which vary by script engine:
@@ -614,7 +614,7 @@ through http://www.webjars.org/[WebJars].
[[mvc-view-script-integrate]]
=== Script Templates
[.small]#<<web-reactive.adoc#webflux-script-integrate,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-script-integrate, Same as in Spring WebFlux>>#
You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use,
the script files to load, what function to call to render templates, and so on.
@@ -1192,13 +1192,13 @@ 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 <<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 used as the value and the map
entry's value are used as the label to be displayed. You can also use a custom
object where you can provide the property names for the value by using `itemValue` and the
label by using `itemLabel`, as the following example shows:
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
used as the value and the map entry's value are used as the label to be displayed.
You can also use a custom object where you can provide the property names for the value
by using `itemValue` and the label by using `itemLabel`, as the following example shows:
====
[source,xml,indent=0]
@@ -2013,7 +2013,7 @@ an external definition (by name) or as a `View` instance from the handler method
[[mvc-view-jackson]]
== Jackson
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter, Same as in Spring WebFlux>>#
Spring offers support for the Jackson JSON library.
@@ -2021,7 +2021,7 @@ Spring offers support for the Jackson JSON library.
[[mvc-view-json-mapping]]
=== Jackson-based JSON MVC Views
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter, Same as in Spring WebFlux>>#
The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response
content as JSON. By default, the entire contents of the model map (with the exception of
@@ -2040,7 +2040,7 @@ serializers and deserializers for specific types.
[[mvc-view-xml-mapping]]
=== Jackson-based XML Views
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter, Same as in Spring WebFlux>>#
`MappingJackson2XmlView` uses the
https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
[[websocket]]
= WebSockets
:doc-spring-security: {doc-root}/spring-security/site/docs/current/reference
[.small]#<<web-reactive.adoc#webflux-websocket,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket, Same as in Spring WebFlux>>#
This part of the reference documentation covers support for Servlet stack, WebSocket
messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and
@@ -14,7 +14,7 @@ include::websocket-intro.adoc[leveloffset=+1]
[[websocket-server]]
== WebSocket API
[.small]#<<web-reactive.adoc#webflux-websocket-server,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket-server, Same as in Spring WebFlux>>#
The Spring Framework provides a WebSocket API that you can use to write client- and
server-side applications that handle WebSocket messages.
@@ -23,7 +23,7 @@ server-side applications that handle WebSocket messages.
[[websocket-server-handler]]
=== `WebSocketHandler`
[.small]#<<web-reactive.adoc#webflux-websocket-server-handler,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket-server-handler, Same as in Spring WebFlux>>#
Creating a WebSocket server is as simple as implementing `WebSocketHandler` or, more
likely, extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`. The following
@@ -102,10 +102,10 @@ The following example shows the XML configuration equivalent of the preceding ex
----
====
The preceding example is for use in Spring MVC applications and should be included in the
configuration of a <<mvc-servlet,`DispatcherServlet`>>. However, Spring's WebSocket
support does not depend on Spring MVC. It is relatively simple to integrate a `WebSocketHandler`
into other HTTP-serving environments with the help of
The preceding example is for use in Spring MVC applications and should be included
in the configuration of a <<mvc-servlet, `DispatcherServlet`>>. However, Spring's
WebSocket support does not depend on Spring MVC. It is relatively simple to
integrate a `WebSocketHandler` into other HTTP-serving environments with the help of
{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].
When using the `WebSocketHandler` API directly vs indirectly, e.g. through the
@@ -118,7 +118,7 @@ sending. One option is to wrap the `WebSocketSession` with
[[websocket-server-handshake]]
=== WebSocket Handshake
[.small]#<<web-reactive.adoc#webflux-websocket-server-handshake,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket-server-handshake, Same as in Spring WebFlux>>#
The easiest way to customize the initial HTTP WebSocket handshake request is through
a `HandshakeInterceptor`, which exposes methods for "`before`" and "`after`" the handshake.
@@ -272,7 +272,7 @@ Java initialization API. The following example shows how to do so:
[[websocket-server-runtime-configuration]]
=== Server Configuration
[.small]#<<web-reactive.adoc#webflux-websocket-server-config,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket-server-config, Same as in Spring WebFlux>>#
Each underlying WebSocket engine exposes configuration properties that control
runtime characteristics, such as the size of message buffer sizes, idle timeout,
@@ -407,7 +407,7 @@ The following example shows the XML configuration equivalent of the preceding ex
[[websocket-server-allowed-origins]]
=== Allowed Origins
[.small]#<<web-reactive.adoc#webflux-websocket-server-cors,Same as in Spring WebFlux>>#
[.small]#<<web-reactive.adoc#webflux-websocket-server-cors, Same as in Spring WebFlux>>#
As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is to accept
only same-origin requests. It is also possible to allow all or a specified list of origins.
@@ -621,7 +621,7 @@ The following example shows the XML configuration equivalent of the preceding ex
====
The preceding example is for use in Spring MVC applications and should be included in the
configuration of a <<mvc-servlet,`DispatcherServlet`>>. However, Spring's WebSocket
configuration of a <<mvc-servlet, `DispatcherServlet`>>. However, Spring's WebSocket
and SockJS support does not depend on Spring MVC. It is relatively simple to
integrate into other HTTP serving environments with the help of
{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].
@@ -1008,7 +1008,7 @@ made about HTTP versus raw TCP and how it lets Spring MVC and other web framewor
provide rich functionality. The following is a list of benefits:
* No need to invent a custom messaging protocol and message format.
* STOMP clients, including a <<websocket-stomp-client,Java client>>
* STOMP clients, including a <<websocket-stomp-client, Java client>>
in the Spring Framework, are available.
* You can (optionally) use message brokers (such as RabbitMQ, ActiveMQ, and others) to
manage subscriptions and broadcast messages.
@@ -1125,10 +1125,10 @@ Alternatively, if you connect through WebSocket (without SockJS), you can use th
----
====
Note that `stompClient` in the preceding example does not need to specify `login` and `passcode` headers.
Even if it did, they would be ignored (or, rather, overridden) on the server side. See
<<websocket-stomp-handle-broker-relay-configure>> and
<<websocket-stomp-authentication>> for more information on authentication.
Note that `stompClient` in the preceding example does not need to specify `login`
and `passcode` headers. Even if it did, they would be ignored (or, rather,
overridden) on the server side. See <<websocket-stomp-handle-broker-relay-configure>>
and <<websocket-stomp-authentication>> for more information on authentication.
For more example code see:
@@ -1255,7 +1255,6 @@ We can trace the flow through a simple example. Consider the following example,
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
@Controller
@@ -1265,9 +1264,7 @@ We can trace the flow through a simple example. Consider the following example,
public String handle(String greeting) {
return "[" + getTimestamp() + ": " + greeting;
}
}
----
====
@@ -1316,9 +1313,10 @@ level, `@MessageMapping` is used to express shared mappings across all methods i
controller.
By default, the mapping values are Ant-style path patterns (for example `/thing*`, `/thing/**`),
including support for template variables (for example, `/thing/{id}`). The values can be referenced through
`@DestinationVariable` method arguments. Applications can also switch to a dot-separated
destination convention for mappings, as explained in <<websocket-stomp-destination-separator>>.
including support for template variables (for example, `/thing/{id}`). The values can be
referenced through `@DestinationVariable` method arguments. Applications can also switch to
a dot-separated destination convention for mappings, as explained in
<<websocket-stomp-destination-separator>>.
===== Supported Method Arguments
@@ -1396,7 +1394,7 @@ See <<websocket-stomp-handle-send>>.
`@SubscribeMapping` is similar to `@MessageMapping` but narrows the mapping to
subscription messages only. It supports the same
<<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
@@ -1407,8 +1405,8 @@ application controllers are mapped to `/app`. In this setup, the broker stores a
subscriptions to `/topic` and `/queue` that are intended for repeated broadcasts, and
there is no need for the application to get involved. A client could also also subscribe to
some `/app` destination, and a controller could return a value in response to that
subscription without involving the broker
without storing or using the subscription again (effectively a one-time request-reply exchange). One use case for this is populating a UI
subscription without involving the broker without storing or using the subscription again
(effectively a one-time request-reply exchange). One use case for this is populating a UI
with initial data on startup.
When is this not useful? Do not try to map broker and controllers to the same destination
@@ -1440,7 +1438,7 @@ receipt if the server supports it (simple broker does not). For example, with th
----
====
A server side option is <<websocket-stomp-interceptors,to register>> an
A server side option is <<websocket-stomp-interceptors, to register>> an
`ExecutorChannelInterceptor` on the `brokerChannel` and implement the `afterMessageHandled`
method that is invoked after messages, including subscriptions, have been handled.
@@ -1471,13 +1469,15 @@ 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 <<websocket-stomp-message-mapping,`@MessageMapping`>> methods.
`@MessageExceptionHandler` methods support flexible method signatures and support
the same method argument types and return values as
<<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 more globally
(across controllers), you can declare them in a class marked with `@ControllerAdvice`.
This is comparable to <<web.adoc#mvc-ann-controller-advice,the similar support>> that is available in Spring MVC.
Typically, `@MessageExceptionHandler` methods apply within the `@Controller` class
(or class hierarchy) in which they are declared. If you want such methods to apply
more globally (across controllers), you can declare them in a class marked with
`@ControllerAdvice`. This is comparable to the
<<web.adoc#mvc-ann-controller-advice, similar support>> available in Spring MVC.
@@ -1634,10 +1634,10 @@ The following example shows the XML configuration equivalent of the preceding ex
The STOMP broker relay in the preceding configuration is a Spring
{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]
that handles messages by forwarding them to an external message broker.
To do so, it establishes TCP connections to the broker, forwards all
messages to it, and then forwards all messages received
from the broker to clients through their WebSocket sessions. Essentially,
it acts as a "`relay`" that forwards messages in both directions.
To do so, it establishes TCP connections to the broker, forwards all messages to it,
and then forwards all messages received from the broker to clients through their
WebSocket sessions. Essentially, it acts as a "`relay`" that forwards messages
in both directions.
NOTE: Add `io.projectreactor.netty:reactor-netty` and `io.netty:netty-all`
dependencies to your project for TCP connection management.
@@ -2231,7 +2231,8 @@ since that is also an implementation of `WebSocketClient`. The `SockJsClient` ca
use WebSocket or HTTP-based transport as a fallback. For more details, see
<<websocket-fallback-sockjs-client>>.
Next, you can establish a connection and provide a handler for the STOMP session, as the following example shows:
Next, you can establish a connection and provide a handler for the STOMP session,
as the following example shows:
====
[source,java,indent=0]