Consistent separation between chapters and after chapter titles

This commit is contained in:
Juergen Hoeller 2017-10-18 20:24:17 +02:00
parent 9df6f3e6b8
commit a3eeda99e0
27 changed files with 996 additions and 740 deletions

View File

@ -2,28 +2,33 @@
= Spring AOP APIs = Spring AOP APIs
[[aop-api-introduction]] [[aop-api-introduction]]
== Introduction == Introduction
The previous chapter described the Spring's support for AOP using The previous chapter described the Spring's support for AOP using
@AspectJ and schema-based aspect definitions. In this chapter we discuss the lower-level @AspectJ and schema-based aspect definitions. In this chapter we discuss the lower-level
Spring AOP APIs and the AOP support used in Spring 1.2 applications. For new Spring AOP APIs and the AOP support typically used in Spring 1.2 applications. For new
applications, we recommend the use of the Spring 2.0 and later AOP support described in applications, we recommend the use of the Spring 2.0 and later AOP support described in
the previous chapter, but when working with existing applications, or when reading books the previous chapter, but when working with existing applications, or when reading books
and articles, you may come across Spring 1.2 style examples. Spring 4.0 is backwards and articles, you may come across Spring 1.2 style examples. Spring 5 remains backwards
compatible with Spring 1.2 and everything described in this chapter is fully supported compatible with Spring 1.2 and everything described in this chapter is fully supported
in Spring 4.0. in Spring 5.
[[aop-api-pointcuts]] [[aop-api-pointcuts]]
== Pointcut API in Spring == Pointcut API in Spring
Let's look at how Spring handles the crucial pointcut concept. Let's look at how Spring handles the crucial pointcut concept.
[[aop-api-concepts]] [[aop-api-concepts]]
=== Concepts === Concepts
Spring's pointcut model enables pointcut reuse independent of advice types. It's Spring's pointcut model enables pointcut reuse independent of advice types. It's
possible to target different advice using the same pointcut. possible to target different advice using the same pointcut.
@ -88,7 +93,6 @@ In this case, the 3-argument matches method will never be invoked.
[TIP] [TIP]
==== ====
If possible, try to make pointcuts static, allowing the AOP framework to cache the If possible, try to make pointcuts static, allowing the AOP framework to cache the
results of pointcut evaluation when an AOP proxy is created. results of pointcut evaluation when an AOP proxy is created.
==== ====
@ -97,6 +101,7 @@ results of pointcut evaluation when an AOP proxy is created.
[[aop-api-pointcut-ops]] [[aop-api-pointcut-ops]]
=== Operations on pointcuts === Operations on pointcuts
Spring supports operations on pointcuts: notably, __union__ and __intersection__. Spring supports operations on pointcuts: notably, __union__ and __intersection__.
* Union means the methods that either pointcut matches. * Union means the methods that either pointcut matches.
@ -111,6 +116,7 @@ Spring supports operations on pointcuts: notably, __union__ and __intersection__
[[aop-api-pointcuts-aspectj]] [[aop-api-pointcuts-aspectj]]
=== AspectJ expression pointcuts === AspectJ expression pointcuts
Since 2.0, the most important type of pointcut used by Spring is Since 2.0, the most important type of pointcut used by Spring is
`org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that `org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that
uses an AspectJ supplied library to parse an AspectJ pointcut expression string. uses an AspectJ supplied library to parse an AspectJ pointcut expression string.
@ -121,12 +127,14 @@ See the previous chapter for a discussion of supported AspectJ pointcut primitiv
[[aop-api-pointcuts-impls]] [[aop-api-pointcuts-impls]]
=== Convenience pointcut implementations === Convenience pointcut implementations
Spring provides several convenient pointcut implementations. Some can be used out of the Spring provides several convenient pointcut implementations. Some can be used out of the
box; others are intended to be subclassed in application-specific pointcuts. box; others are intended to be subclassed in application-specific pointcuts.
[[aop-api-pointcuts-static]] [[aop-api-pointcuts-static]]
==== Static pointcuts ==== Static pointcuts
Static pointcuts are based on method and target class, and cannot take into account the Static pointcuts are based on method and target class, and cannot take into account the
method's arguments. Static pointcuts are sufficient - __and best__ - for most usages. method's arguments. Static pointcuts are sufficient - __and best__ - for most usages.
It's possible for Spring to evaluate a static pointcut only once, when a method is first It's possible for Spring to evaluate a static pointcut only once, when a method is first
@ -137,10 +145,11 @@ Let's consider some static pointcut implementations included with Spring.
[[aop-api-pointcuts-regex]] [[aop-api-pointcuts-regex]]
===== Regular expression pointcuts ===== Regular expression pointcuts
One obvious way to specify static pointcuts is regular expressions. Several AOP One obvious way to specify static pointcuts is regular expressions. Several AOP
frameworks besides Spring make this possible. frameworks besides Spring make this possible.
`org.springframework.aop.support.JdkRegexpMethodPointcut` is a generic regular `org.springframework.aop.support.JdkRegexpMethodPointcut` is a generic regular
expression pointcut, using the regular expression support in JDK 1.4+. expression pointcut, using the regular expression support in the JDK.
Using the `JdkRegexpMethodPointcut` class, you can provide a list of pattern Strings. If Using the `JdkRegexpMethodPointcut` class, you can provide a list of pattern Strings. If
any of these is a match, the pointcut will evaluate to true. (So the result is any of these is a match, the pointcut will evaluate to true. (So the result is
@ -189,12 +198,14 @@ __RegexpMethodPointcutAdvisor__ can be used with any Advice type.
[[aop-api-pointcuts-attribute-driven]] [[aop-api-pointcuts-attribute-driven]]
===== Attribute-driven pointcuts ===== Attribute-driven pointcuts
An important type of static pointcut is a __metadata-driven__ pointcut. This uses the An important type of static pointcut is a __metadata-driven__ pointcut. This uses the
values of metadata attributes: typically, source-level metadata. values of metadata attributes: typically, source-level metadata.
[[aop-api-pointcuts-dynamic]] [[aop-api-pointcuts-dynamic]]
==== Dynamic pointcuts ==== Dynamic pointcuts
Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account
method __arguments__, as well as static information. This means that they must be method __arguments__, as well as static information. This means that they must be
evaluated with every method invocation; the result cannot be cached, as arguments will evaluated with every method invocation; the result cannot be cached, as arguments will
@ -204,12 +215,14 @@ The main example is the `control flow` pointcut.
[[aop-api-pointcuts-cflow]] [[aop-api-pointcuts-cflow]]
===== Control flow pointcuts ===== Control flow pointcuts
Spring control flow pointcuts are conceptually similar to AspectJ __cflow__ pointcuts, Spring control flow pointcuts are conceptually similar to AspectJ __cflow__ pointcuts,
although less powerful. (There is currently no way to specify that a pointcut executes although less powerful. (There is currently no way to specify that a pointcut executes
below a join point matched by another pointcut.) A control flow pointcut matches the below a join point matched by another pointcut.) A control flow pointcut matches the
current call stack. For example, it might fire if the join point was invoked by a method current call stack. For example, it might fire if the join point was invoked by a method
in the `com.mycompany.web` package, or by the `SomeCaller` class. Control flow pointcuts in the `com.mycompany.web` package, or by the `SomeCaller` class. Control flow pointcuts
are specified using the `org.springframework.aop.support.ControlFlowPointcut` class. are specified using the `org.springframework.aop.support.ControlFlowPointcut` class.
[NOTE] [NOTE]
==== ====
Control flow pointcuts are significantly more expensive to evaluate at runtime than even Control flow pointcuts are significantly more expensive to evaluate at runtime than even
@ -221,6 +234,7 @@ pointcuts.
[[aop-api-pointcuts-superclasses]] [[aop-api-pointcuts-superclasses]]
=== Pointcut superclasses === Pointcut superclasses
Spring provides useful pointcut superclasses to help you to implement your own pointcuts. Spring provides useful pointcut superclasses to help you to implement your own pointcuts.
Because static pointcuts are most useful, you'll probably subclass Because static pointcuts are most useful, you'll probably subclass
@ -246,6 +260,7 @@ You can use custom pointcuts with any advice type in Spring 1.0 RC2 and above.
[[aop-api-pointcuts-custom]] [[aop-api-pointcuts-custom]]
=== Custom pointcuts === Custom pointcuts
Because pointcuts in Spring AOP are Java classes, rather than language features (as in Because pointcuts in Spring AOP are Java classes, rather than language features (as in
AspectJ) it's possible to declare custom pointcuts, whether static or dynamic. Custom AspectJ) it's possible to declare custom pointcuts, whether static or dynamic. Custom
pointcuts in Spring can be arbitrarily complex. However, using the AspectJ pointcut pointcuts in Spring can be arbitrarily complex. However, using the AspectJ pointcut
@ -262,12 +277,14 @@ for example, "all methods that change instance variables in the target object."
[[aop-api-advice]] [[aop-api-advice]]
== Advice API in Spring == Advice API in Spring
Let's now look at how Spring AOP handles advice. Let's now look at how Spring AOP handles advice.
[[aop-api-advice-lifecycle]] [[aop-api-advice-lifecycle]]
=== Advice lifecycles === Advice lifecycles
Each advice is a Spring bean. An advice instance can be shared across all advised Each advice is a Spring bean. An advice instance can be shared across all advised
objects, or unique to each advised object. This corresponds to __per-class__ or objects, or unique to each advised object. This corresponds to __per-class__ or
__per-instance__ advice. __per-instance__ advice.
@ -285,12 +302,14 @@ It's possible to use a mix of shared and per-instance advice in the same AOP pro
[[aop-api-advice-types]] [[aop-api-advice-types]]
=== Advice types in Spring === Advice types in Spring
Spring provides several advice types out of the box, and is extensible to support Spring provides several advice types out of the box, and is extensible to support
arbitrary advice types. Let us look at the basic concepts and standard advice types. arbitrary advice types. Let us look at the basic concepts and standard advice types.
[[aop-api-advice-around]] [[aop-api-advice-around]]
==== Interception around advice ==== Interception around advice
The most fundamental advice type in Spring is __interception around advice__. The most fundamental advice type in Spring is __interception around advice__.
Spring is compliant with the AOP Alliance interface for around advice using method Spring is compliant with the AOP Alliance interface for around advice using method
@ -347,6 +366,7 @@ currently define pointcut interfaces.
[[aop-api-advice-before]] [[aop-api-advice-before]]
==== Before advice ==== Before advice
A simpler advice type is a __before advice__. This does not need a `MethodInvocation` A simpler advice type is a __before advice__. This does not need a `MethodInvocation`
object, since it will only be called before entering the method. object, since it will only be called before entering the method.
@ -395,13 +415,13 @@ An example of a before advice in Spring, which counts all method invocations:
[TIP] [TIP]
==== ====
Before advice can be used with any pointcut. Before advice can be used with any pointcut.
==== ====
[[aop-api-advice-throws]] [[aop-api-advice-throws]]
==== Throws advice ==== Throws advice
__Throws advice__ is invoked after the return of the join point if the join point threw __Throws advice__ is invoked after the return of the join point if the join point threw
an exception. Spring offers typed throws advice. Note that this means that the an exception. Spring offers typed throws advice. Note that this means that the
`org.springframework.aop.ThrowsAdvice` interface does not contain any methods: It is a `org.springframework.aop.ThrowsAdvice` interface does not contain any methods: It is a
@ -478,13 +498,13 @@ exception that is incompatible with the target method's signature!__
[TIP] [TIP]
==== ====
Throws advice can be used with any pointcut. Throws advice can be used with any pointcut.
==== ====
[[aop-api-advice-after-returning]] [[aop-api-advice-after-returning]]
==== After Returning advice ==== After Returning advice
An after returning advice in Spring must implement the An after returning advice in Spring must implement the
__org.springframework.aop.AfterReturningAdvice__ interface, shown below: __org.springframework.aop.AfterReturningAdvice__ interface, shown below:
@ -527,13 +547,13 @@ thrown up the interceptor chain instead of the return value.
[TIP] [TIP]
==== ====
After returning advice can be used with any pointcut. After returning advice can be used with any pointcut.
==== ====
[[aop-api-advice-introduction]] [[aop-api-advice-introduction]]
==== Introduction advice ==== Introduction advice
Spring treats introduction advice as a special kind of interception advice. Spring treats introduction advice as a special kind of interception advice.
Introduction requires an `IntroductionAdvisor`, and an `IntroductionInterceptor`, Introduction requires an `IntroductionAdvisor`, and an `IntroductionInterceptor`,
@ -696,6 +716,7 @@ and stateful mixins.
[[aop-api-advisor]] [[aop-api-advisor]]
== Advisor API in Spring == Advisor API in Spring
In Spring, an Advisor is an aspect that contains just a single advice object associated In Spring, an Advisor is an aspect that contains just a single advice object associated
with a pointcut expression. with a pointcut expression.
@ -714,6 +735,7 @@ chain.
[[aop-pfb]] [[aop-pfb]]
== Using the ProxyFactoryBean to create AOP proxies == Using the ProxyFactoryBean to create AOP proxies
If you're using the Spring IoC container (an ApplicationContext or BeanFactory) for your If you're using the Spring IoC container (an ApplicationContext or BeanFactory) for your
business objects - and you should be! - you will want to use one of Spring's AOP business objects - and you should be! - you will want to use one of Spring's AOP
FactoryBeans. (Remember that a factory bean introduces a layer of indirection, enabling FactoryBeans. (Remember that a factory bean introduces a layer of indirection, enabling
@ -733,6 +755,7 @@ options that are preferable if you don't need such control.
[[aop-pfb-1]] [[aop-pfb-1]]
=== Basics === Basics
The `ProxyFactoryBean`, like other Spring `FactoryBean` implementations, introduces a The `ProxyFactoryBean`, like other Spring `FactoryBean` implementations, introduces a
level of indirection. If you define a `ProxyFactoryBean` with name `foo`, what objects level of indirection. If you define a `ProxyFactoryBean` with name `foo`, what objects
referencing `foo` see is not the `ProxyFactoryBean` instance itself, but an object referencing `foo` see is not the `ProxyFactoryBean` instance itself, but an object
@ -750,6 +773,7 @@ framework), benefiting from all the pluggability provided by Dependency Injectio
[[aop-pfb-2]] [[aop-pfb-2]]
=== JavaBean properties === JavaBean properties
In common with most `FactoryBean` implementations provided with Spring, the In common with most `FactoryBean` implementations provided with Spring, the
`ProxyFactoryBean` class is itself a JavaBean. Its properties are used to: `ProxyFactoryBean` class is itself a JavaBean. Its properties are used to:
@ -803,6 +827,7 @@ to be applied. An example of using this feature can be found in <<aop-global-adv
[[aop-pfb-proxy-types]] [[aop-pfb-proxy-types]]
=== JDK- and CGLIB-based proxies === JDK- and CGLIB-based proxies
This section serves as the definitive documentation on how the `ProxyFactoryBean` This section serves as the definitive documentation on how the `ProxyFactoryBean`
chooses to create one of either a JDK- and CGLIB-based proxy for a particular target chooses to create one of either a JDK- and CGLIB-based proxy for a particular target
object (that is to be proxied). object (that is to be proxied).
@ -855,6 +880,7 @@ it is significantly less work, and less prone to typos.
[[aop-api-proxying-intf]] [[aop-api-proxying-intf]]
=== Proxying interfaces === Proxying interfaces
Let's look at a simple example of `ProxyFactoryBean` in action. This example involves: Let's look at a simple example of `ProxyFactoryBean` in action. This example involves:
* A __target bean__ that will be proxied. This is the "personTarget" bean definition in * A __target bean__ that will be proxied. This is the "personTarget" bean definition in
@ -972,6 +998,7 @@ factory might actually be an __advantage__: for example, in certain test scenari
[[aop-api-proxying-class]] [[aop-api-proxying-class]]
=== Proxying classes === Proxying classes
What if you need to proxy a class, rather than one or more interfaces? What if you need to proxy a class, rather than one or more interfaces?
Imagine that in our example above, there was no `Person` interface: we needed to advise Imagine that in our example above, there was no `Person` interface: we needed to advise
@ -1006,6 +1033,7 @@ Performance should not be a decisive consideration in this case.
[[aop-global-advisors]] [[aop-global-advisors]]
=== Using 'global' advisors === Using 'global' advisors
By appending an asterisk to an interceptor name, all advisors with bean names matching By appending an asterisk to an interceptor name, all advisors with bean names matching
the part before the asterisk, will be added to the advisor chain. This can come in handy the part before the asterisk, will be added to the advisor chain. This can come in handy
if you need to add a standard set of 'global' advisors: if you need to add a standard set of 'global' advisors:
@ -1031,6 +1059,7 @@ if you need to add a standard set of 'global' advisors:
[[aop-concise-proxy]] [[aop-concise-proxy]]
== Concise proxy definitions == Concise proxy definitions
Especially when defining transactional proxies, you may end up with many similar proxy Especially when defining transactional proxies, you may end up with many similar proxy
definitions. The use of parent and child bean definitions, along with inner bean definitions. The use of parent and child bean definitions, along with inner bean
definitions, can result in much cleaner and more concise proxy definitions. definitions, can result in much cleaner and more concise proxy definitions.
@ -1103,6 +1132,7 @@ pre-instantiate it.
[[aop-prog]] [[aop-prog]]
== Creating AOP proxies programmatically with the ProxyFactory == Creating AOP proxies programmatically with the ProxyFactory
It's easy to create AOP proxies programmatically using Spring. This enables you to use It's easy to create AOP proxies programmatically using Spring. This enables you to use
Spring AOP without dependency on Spring IoC. Spring AOP without dependency on Spring IoC.
@ -1135,7 +1165,6 @@ AdvisedSupport is the superclass of both ProxyFactory and ProxyFactoryBean.
[TIP] [TIP]
==== ====
Integrating AOP proxy creation with the IoC framework is best practice in most Integrating AOP proxy creation with the IoC framework is best practice in most
applications. We recommend that you externalize configuration from Java code with AOP, applications. We recommend that you externalize configuration from Java code with AOP,
as in general. as in general.
@ -1146,6 +1175,7 @@ as in general.
[[aop-api-advised]] [[aop-api-advised]]
== Manipulating advised objects == Manipulating advised objects
However you create AOP proxies, you can manipulate them using the However you create AOP proxies, you can manipulate them using the
`org.springframework.aop.framework.Advised` interface. Any AOP proxy can be cast to this `org.springframework.aop.framework.Advised` interface. Any AOP proxy can be cast to this
interface, whichever other interfaces it implements. This interface includes the interface, whichever other interfaces it implements. This interface includes the
@ -1238,6 +1268,7 @@ required.
[[aop-autoproxy]] [[aop-autoproxy]]
== Using the "auto-proxy" facility == Using the "auto-proxy" facility
So far we've considered explicit creation of AOP proxies using a `ProxyFactoryBean` or So far we've considered explicit creation of AOP proxies using a `ProxyFactoryBean` or
similar factory bean. similar factory bean.
@ -1259,12 +1290,14 @@ There are two ways to do this:
[[aop-autoproxy-choices]] [[aop-autoproxy-choices]]
=== Autoproxy bean definitions === Autoproxy bean definitions
The `org.springframework.aop.framework.autoproxy` package provides the following The `org.springframework.aop.framework.autoproxy` package provides the following
standard auto-proxy creators. standard auto-proxy creators.
[[aop-api-autoproxy]] [[aop-api-autoproxy]]
==== BeanNameAutoProxyCreator ==== BeanNameAutoProxyCreator
The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates
AOP proxies for beans with names matching literal values or wildcards. AOP proxies for beans with names matching literal values or wildcards.
@ -1299,6 +1332,7 @@ the above example), the pointcuts may apply differently to different beans.
[[aop-api-autoproxy-default]] [[aop-api-autoproxy-default]]
==== DefaultAdvisorAutoProxyCreator ==== DefaultAdvisorAutoProxyCreator
A more general and extremely powerful auto proxy creator is A more general and extremely powerful auto proxy creator is
`DefaultAdvisorAutoProxyCreator`. This will automagically apply eligible advisors in the `DefaultAdvisorAutoProxyCreator`. This will automagically apply eligible advisors in the
current context, without the need to include specific bean names in the auto-proxy current context, without the need to include specific bean names in the auto-proxy
@ -1359,147 +1393,11 @@ correct ordering if this is an issue. The TransactionAttributeSourceAdvisor used
above example has a configurable order value; the default setting is unordered. above example has a configurable order value; the default setting is unordered.
[[aop-api-autoproxy-abstract]]
==== AbstractAdvisorAutoProxyCreator
This is the superclass of DefaultAdvisorAutoProxyCreator. You can create your own
auto-proxy creators by subclassing this class, in the unlikely event that advisor
definitions offer insufficient customization to the behavior of the framework
`DefaultAdvisorAutoProxyCreator`.
[[aop-autoproxy-metadata]]
=== Using metadata-driven auto-proxying
A particularly important type of auto-proxying is driven by metadata. This produces a
similar programming model to .NET `ServicedComponents`. Instead of defining metadata in
XML descriptors, configuration for transaction management and other enterprise services
is held in source-level attributes.
In this case, you use the `DefaultAdvisorAutoProxyCreator`, in combination with Advisors
that understand metadata attributes. The metadata specifics are held in the pointcut
part of the candidate advisors, rather than in the auto-proxy creation class itself.
This is really a special case of the `DefaultAdvisorAutoProxyCreator`, but deserves
consideration on its own. (The metadata-aware code is in the pointcuts contained in the
advisors, not the AOP framework itself.)
The `/attributes` directory of the JPetStore sample application shows the use of
attribute-driven auto-proxying. In this case, there's no need to use the
`TransactionProxyFactoryBean`. Simply defining transactional attributes on business
objects is sufficient, because of the use of metadata-aware pointcuts. The bean
definitions include the following code, in `/WEB-INF/declarativeServices.xml`. Note that
this is generic, and can be used outside the JPetStore:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource">
<property name="attributes" ref="attributes"/>
</bean>
</property>
</bean>
<bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/>
----
The `DefaultAdvisorAutoProxyCreator` bean definition (the name is not significant, hence
it can even be omitted) will pick up all eligible pointcuts in the current application
context. In this case, the "transactionAdvisor" bean definition, of type
`TransactionAttributeSourceAdvisor`, will apply to classes or methods carrying a
transaction attribute. The TransactionAttributeSourceAdvisor depends on a
TransactionInterceptor, via constructor dependency. The example resolves this via
autowiring. The `AttributesTransactionAttributeSource` depends on an implementation of
the `org.springframework.metadata.Attributes` interface. In this fragment, the
"attributes" bean satisfies this, using the Jakarta Commons Attributes API to obtain
attribute information. (The application code must have been compiled using the Commons
Attributes compilation task.)
The `/annotation` directory of the JPetStore sample application contains an analogous
example for auto-proxying driven by JDK 1.5+ annotations. The following configuration
enables automatic detection of Spring's `Transactional` annotation, leading to implicit
proxies for beans containing that annotation:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
----
The `TransactionInterceptor` defined here depends on a `PlatformTransactionManager`
definition, which is not included in this generic file (although it could be) because it
will be specific to the application's transaction requirements (typically JTA, as in
this example, or Hibernate or JDBC):
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"/>
----
[TIP]
====
If you require only declarative transaction management, using these generic XML
definitions will result in Spring automatically proxying all classes or methods with
transaction attributes. You won't need to work directly with AOP, and the programming
model is similar to that of .NET ServicedComponents.
====
This mechanism is extensible. It's possible to do auto-proxying based on custom
attributes. You need to:
* Define your custom attribute.
* Specify an Advisor with the necessary advice, including a pointcut that is triggered
by the presence of the custom attribute on a class or method. You may be able to use
an existing advice, merely implementing a static pointcut that picks up the custom
attribute.
It's possible for such advisors to be unique to each advised class (for example, mixins):
they simply need to be defined as prototype, rather than singleton, bean definitions.
For example, the `LockMixin` introduction interceptor from the Spring test suite,
shown above, could be used in conjunction with a generic `DefaultIntroductionAdvisor`:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="lockMixin" class="test.mixin.LockMixin" scope="prototype"/>
<bean id="lockableAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor"
scope="prototype">
<constructor-arg ref="lockMixin"/>
</bean>
----
Note that both `lockMixin` and `lockableAdvisor` are defined as prototypes.
[[aop-targetsource]] [[aop-targetsource]]
== Using TargetSources == Using TargetSources
Spring offers the concept of a __TargetSource__, expressed in the Spring offers the concept of a __TargetSource__, expressed in the
`org.springframework.aop.TargetSource` interface. This interface is responsible for `org.springframework.aop.TargetSource` interface. This interface is responsible for
returning the "target object" implementing the join point. The `TargetSource` returning the "target object" implementing the join point. The `TargetSource`
@ -1518,7 +1416,6 @@ Let's look at the standard target sources provided with Spring, and how you can
[TIP] [TIP]
==== ====
When using a custom target source, your target will usually need to be a prototype When using a custom target source, your target will usually need to be a prototype
rather than a singleton bean definition. This allows Spring to create a new target rather than a singleton bean definition. This allows Spring to create a new target
instance when required. instance when required.
@ -1528,6 +1425,7 @@ instance when required.
[[aop-ts-swap]] [[aop-ts-swap]]
=== Hot swappable target sources === Hot swappable target sources
The `org.springframework.aop.target.HotSwappableTargetSource` exists to allow the target The `org.springframework.aop.target.HotSwappableTargetSource` exists to allow the target
of an AOP proxy to be switched while allowing callers to keep their references to it. of an AOP proxy to be switched while allowing callers to keep their references to it.
@ -1571,6 +1469,7 @@ arbitrary advice.
[[aop-ts-pool]] [[aop-ts-pool]]
=== Pooling target sources === Pooling target sources
Using a pooling target source provides a similar programming model to stateless session Using a pooling target source provides a similar programming model to stateless session
EJBs, in which a pool of identical instances is maintained, with method invocations EJBs, in which a pool of identical instances is maintained, with method invocations
going to free objects in the pool. going to free objects in the pool.
@ -1665,6 +1564,7 @@ used by any auto-proxy creator.
[[aop-ts-prototype]] [[aop-ts-prototype]]
=== Prototype target sources === Prototype target sources
Setting up a "prototype" target source is similar to a pooling TargetSource. In this Setting up a "prototype" target source is similar to a pooling TargetSource. In this
case, a new instance of the target will be created on every method invocation. Although case, a new instance of the target will be created on every method invocation. Although
the cost of creating a new object isn't high in a modern JVM, the cost of wiring up the the cost of creating a new object isn't high in a modern JVM, the cost of wiring up the
@ -1736,15 +1636,3 @@ The only constraint on a custom `Advice` type is that it must implement the
Please refer to the `org.springframework.aop.framework.adapter` javadocs for further Please refer to the `org.springframework.aop.framework.adapter` javadocs for further
information. information.
[[aop-api-resources]]
== Further resources
Please refer to the Spring sample applications for further examples of Spring AOP:
* The JPetStore's default configuration illustrates the use of the
`TransactionProxyFactoryBean` for declarative transaction management.
* The `/attributes` directory of the JPetStore illustrates the use of attribute-driven
declarative transaction management.

View File

@ -2,8 +2,11 @@
= Aspect Oriented Programming with Spring = Aspect Oriented Programming with Spring
[[aop-introduction]] [[aop-introduction]]
== Introduction == Introduction
__Aspect-Oriented Programming__ (AOP) complements Object-Oriented Programming (OOP) by __Aspect-Oriented Programming__ (AOP) complements Object-Oriented Programming (OOP) by
providing another way of thinking about program structure. The key unit of modularity in providing another way of thinking about program structure. The key unit of modularity in
OOP is the class, whereas in AOP the unit of modularity is the __aspect__. Aspects OOP is the class, whereas in AOP the unit of modularity is the __aspect__. Aspects
@ -15,17 +18,16 @@ One of the key components of Spring is the __AOP framework__. While the Spring I
container does not depend on AOP, meaning you do not need to use AOP if you don't want container does not depend on AOP, meaning you do not need to use AOP if you don't want
to, AOP complements Spring IoC to provide a very capable middleware solution. to, AOP complements Spring IoC to provide a very capable middleware solution.
.Spring 2.0 AOP .Spring 2.0+ AOP
**** ****
Spring 2.0 introduces a simpler and more powerful way of writing custom aspects using Spring 2.0 introduced a simpler and more powerful way of writing custom aspects using
either a <<aop-schema,schema-based approach>> or the <<aop-ataspectj,@AspectJ annotation either a <<aop-schema,schema-based approach>> or the <<aop-ataspectj,@AspectJ annotation
style>>. Both of these styles offer fully typed advice and use of the AspectJ pointcut style>>. Both of these styles offer fully typed advice and use of the AspectJ pointcut
language, while still using Spring AOP for weaving. language, while still using Spring AOP for weaving.
The Spring 2.0 schema- and @AspectJ-based AOP support is discussed in this chapter. The Spring 2.0+ schema- and @AspectJ-based AOP support is discussed in this chapter.
Spring 2.0 AOP remains fully backwards compatible with Spring 1.2 AOP, and the The lower-level AOP support, as commonly exposed in Spring 1.2 applications, is
lower-level AOP support offered by the Spring 1.2 APIs is discussed in <<aop-api,the discussed in <<aop-api,the following chapter>>.
following chapter>>.
**** ****
AOP is used in the Spring Framework to... AOP is used in the Spring Framework to...
@ -46,6 +48,7 @@ Spring AOP, and can skip most of this chapter.
[[aop-introduction-defn]] [[aop-introduction-defn]]
=== AOP concepts === AOP concepts
Let us begin by defining some central AOP concepts and terminology. These terms are not Let us begin by defining some central AOP concepts and terminology. These terms are not
Spring-specific... unfortunately, AOP terminology is not particularly intuitive; Spring-specific... unfortunately, AOP terminology is not particularly intuitive;
however, it would be even more confusing if Spring used its own terminology. however, it would be even more confusing if Spring used its own terminology.
@ -123,6 +126,7 @@ multiple objects (such as all business operations in the service layer).
[[aop-introduction-spring-defn]] [[aop-introduction-spring-defn]]
=== Spring AOP capabilities and goals === Spring AOP capabilities and goals
Spring AOP is implemented in pure Java. There is no need for a special compilation Spring AOP is implemented in pure Java. There is no need for a special compilation
process. Spring AOP does not need to control the class loader hierarchy, and is thus process. Spring AOP does not need to control the class loader hierarchy, and is thus
suitable for use in a Servlet container or application server. suitable for use in a Servlet container or application server.
@ -182,6 +186,7 @@ style.
[[aop-introduction-proxies]] [[aop-introduction-proxies]]
=== AOP Proxies === AOP Proxies
Spring AOP defaults to using standard JDK __dynamic proxies__ for AOP proxies. This Spring AOP defaults to using standard JDK __dynamic proxies__ for AOP proxies. This
enables any interface (or set of interfaces) to be proxied. enables any interface (or set of interfaces) to be proxied.
@ -202,6 +207,7 @@ implementation detail actually means.
[[aop-ataspectj]] [[aop-ataspectj]]
== @AspectJ support == @AspectJ support
@AspectJ refers to a style of declaring aspects as regular Java classes annotated with @AspectJ refers to a style of declaring aspects as regular Java classes annotated with
annotations. The @AspectJ style was introduced by the annotations. The @AspectJ style was introduced by the
http://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring http://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring
@ -219,6 +225,7 @@ discussed in <<aop-using-aspectj>>.
[[aop-aspectj-support]] [[aop-aspectj-support]]
=== Enabling @AspectJ Support === Enabling @AspectJ Support
To use @AspectJ aspects in a Spring configuration you need to enable Spring support for To use @AspectJ aspects in a Spring configuration you need to enable Spring support for
configuring Spring AOP based on @AspectJ aspects, and __autoproxying__ beans based on configuring Spring AOP based on @AspectJ aspects, and __autoproxying__ beans based on
whether or not they are advised by those aspects. By autoproxying we mean that if Spring whether or not they are advised by those aspects. By autoproxying we mean that if Spring
@ -234,6 +241,7 @@ classpath of your application (version 1.6.8 or later). This library is availabl
[[aop-enable-aspectj-java]] [[aop-enable-aspectj-java]]
==== Enabling @AspectJ Support with Java configuration ==== Enabling @AspectJ Support with Java configuration
To enable @AspectJ support with Java `@Configuration` add the `@EnableAspectJAutoProxy` To enable @AspectJ support with Java `@Configuration` add the `@EnableAspectJAutoProxy`
annotation: annotation:
@ -250,6 +258,7 @@ annotation:
[[aop-enable-aspectj-xml]] [[aop-enable-aspectj-xml]]
==== Enabling @AspectJ Support with XML configuration ==== Enabling @AspectJ Support with XML configuration
To enable @AspectJ support with XML based configuration use the `aop:aspectj-autoproxy` To enable @AspectJ support with XML based configuration use the `aop:aspectj-autoproxy`
element: element:
@ -327,6 +336,7 @@ hence excludes it from auto-proxying.
[[aop-pointcuts]] [[aop-pointcuts]]
=== Declaring a pointcut === Declaring a pointcut
Recall that pointcuts determine join points of interest, and thus enable us to control Recall that pointcuts determine join points of interest, and thus enable us to control
when advice executes. __Spring AOP only supports method execution join points for Spring when advice executes. __Spring AOP only supports method execution join points for Spring
beans__, so you can think of a pointcut as matching the execution of methods on Spring beans__, so you can think of a pointcut as matching the execution of methods on Spring
@ -359,6 +369,7 @@ et. al. or "AspectJ in Action" by Ramnivas Laddad.
[[aop-pointcuts-designators]] [[aop-pointcuts-designators]]
==== Supported Pointcut Designators ==== Supported Pointcut Designators
Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut
expressions: expressions:
@ -456,6 +467,7 @@ it is natural and straightforward to identify specific beans by name.
[[aop-pointcuts-combining]] [[aop-pointcuts-combining]]
==== Combining pointcut expressions ==== Combining pointcut expressions
Pointcut expressions can be combined using '&&', '||' and '!'. It is also possible to Pointcut expressions can be combined using '&&', '||' and '!'. It is also possible to
refer to pointcut expressions by name. The following example shows three pointcut refer to pointcut expressions by name. The following example shows three pointcut
expressions: `anyPublicOperation` (which matches if a method execution join point expressions: `anyPublicOperation` (which matches if a method execution join point
@ -485,6 +497,7 @@ __matching__.
[[aop-common-pointcuts]] [[aop-common-pointcuts]]
==== Sharing common pointcut definitions ==== Sharing common pointcut definitions
When working with enterprise applications, you often want to refer to modules of the When working with enterprise applications, you often want to refer to modules of the
application and particular sets of operations from within several aspects. We recommend application and particular sets of operations from within several aspects. We recommend
defining a "SystemArchitecture" aspect that captures common pointcut expressions for defining a "SystemArchitecture" aspect that captures common pointcut expressions for
@ -579,6 +592,7 @@ transaction elements are discussed in <<data-access.adoc#transaction, Transactio
[[aop-pointcuts-examples]] [[aop-pointcuts-examples]]
==== Examples ==== Examples
Spring AOP users are likely to use the `execution` pointcut designator the most often. Spring AOP users are likely to use the `execution` pointcut designator the most often.
The format of an execution expression is: The format of an execution expression is:
@ -795,6 +809,7 @@ how to make the annotation object(s) available in the advice body.
[[writing-good-pointcuts]] [[writing-good-pointcuts]]
==== Writing good pointcuts ==== Writing good pointcuts
During compilation, AspectJ processes pointcuts in order to try and optimize matching During compilation, AspectJ processes pointcuts in order to try and optimize matching
performance. Examining code and determining if each join point matches (statically or performance. Examining code and determining if each join point matches (statically or
dynamically) a given pointcut is a costly process. (A dynamic match means the match dynamically) a given pointcut is a costly process. (A dynamic match means the match
@ -832,6 +847,7 @@ pointcut should always include one if possible.
[[aop-advice]] [[aop-advice]]
=== Declaring advice === Declaring advice
Advice is associated with a pointcut expression, and runs before, after, or around Advice is associated with a pointcut expression, and runs before, after, or around
method executions matched by the pointcut. The pointcut expression may be either a method executions matched by the pointcut. The pointcut expression may be either a
simple reference to a named pointcut, or a pointcut expression declared in place. simple reference to a named pointcut, or a pointcut expression declared in place.
@ -839,6 +855,7 @@ simple reference to a named pointcut, or a pointcut expression declared in place
[[aop-advice-before]] [[aop-advice-before]]
==== Before advice ==== Before advice
Before advice is declared in an aspect using the `@Before` annotation: Before advice is declared in an aspect using the `@Before` annotation:
[source,java,indent=0] [source,java,indent=0]
@ -880,6 +897,7 @@ If using an in-place pointcut expression we could rewrite the above example as:
[[aop-advice-after-returning]] [[aop-advice-after-returning]]
==== After returning advice ==== After returning advice
After returning advice runs when a matched method execution returns normally. It is After returning advice runs when a matched method execution returns normally. It is
declared using the `@AfterReturning` annotation: declared using the `@AfterReturning` annotation:
@ -941,6 +959,7 @@ using after-returning advice.
[[aop-advice-after-throwing]] [[aop-advice-after-throwing]]
==== After throwing advice ==== After throwing advice
After throwing advice runs when a matched method execution exits by throwing an After throwing advice runs when a matched method execution exits by throwing an
exception. It is declared using the `@AfterThrowing` annotation: exception. It is declared using the `@AfterThrowing` annotation:
@ -994,6 +1013,7 @@ of the specified type ( `DataAccessException` in this case).
[[aop-advice-after-finally]] [[aop-advice-after-finally]]
==== After (finally) advice ==== After (finally) advice
After (finally) advice runs however a matched method execution exits. It is declared After (finally) advice runs however a matched method execution exits. It is declared
using the `@After` annotation. After advice must be prepared to handle both normal and using the `@After` annotation. After advice must be prepared to handle both normal and
exception return conditions. It is typically used for releasing resources, etc. exception return conditions. It is typically used for releasing resources, etc.
@ -1018,6 +1038,7 @@ exception return conditions. It is typically used for releasing resources, etc.
[[aop-ataspectj-around-advice]] [[aop-ataspectj-around-advice]]
==== Around advice ==== Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes, execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all. and to determine when, how, and even if, the method actually gets to execute at all.
@ -1079,6 +1100,7 @@ legal.
[[aop-ataspectj-advice-params]] [[aop-ataspectj-advice-params]]
==== Advice parameters ==== Advice parameters
Spring offers fully typed advice - meaning that you declare the parameters you need Spring offers fully typed advice - meaning that you declare the parameters you need
in the advice signature (as we saw for the returning and throwing examples above) rather in the advice signature (as we saw for the returning and throwing examples above) rather
than work with `Object[]` arrays all the time. We'll see how to make argument and other than work with `Object[]` arrays all the time. We'll see how to make argument and other
@ -1100,6 +1122,7 @@ Please do consult the javadocs for full details.
[[aop-ataspectj-advice-params-passing]] [[aop-ataspectj-advice-params-passing]]
===== Passing parameters to advice ===== Passing parameters to advice
We've already seen how to bind the returned value or exception value (using after We've already seen how to bind the returned value or exception value (using after
returning and after throwing advice). To make argument values available to the advice returning and after throwing advice). To make argument values available to the advice
body, you can use the binding form of `args`. If a parameter name is used in place of a body, you can use the binding form of `args`. If a parameter name is used in place of a
@ -1174,6 +1197,7 @@ And then the advice that matches the execution of `@Auditable` methods:
[[aop-ataspectj-advice-params-generics]] [[aop-ataspectj-advice-params-generics]]
===== Advice parameters and generics ===== Advice parameters and generics
Spring AOP can handle generics used in class declarations and method parameters. Suppose Spring AOP can handle generics used in class declarations and method parameters. Suppose
you have a generic type like this: you have a generic type like this:
@ -1218,6 +1242,7 @@ check the type of the elements.
[[aop-ataspectj-advice-params-names]] [[aop-ataspectj-advice-params-names]]
===== Determining argument names ===== Determining argument names
The parameter binding in advice invocations relies on matching names used in pointcut The parameter binding in advice invocations relies on matching names used in pointcut
expressions to declared parameter names in (advice and pointcut) method signatures. expressions to declared parameter names in (advice and pointcut) method signatures.
Parameter names are __not__ available through Java reflection, so Spring AOP uses the Parameter names are __not__ available through Java reflection, so Spring AOP uses the
@ -1297,6 +1322,7 @@ will retain the needed information.
[[aop-ataspectj-advice-proceeding-with-the-call]] [[aop-ataspectj-advice-proceeding-with-the-call]]
===== Proceeding with arguments ===== Proceeding with arguments
We remarked earlier that we would describe how to write a proceed call __with We remarked earlier that we would describe how to write a proceed call __with
arguments__ that works consistently across Spring AOP and AspectJ. The solution is arguments__ that works consistently across Spring AOP and AspectJ. The solution is
simply to ensure that the advice signature binds each of the method parameters in order. simply to ensure that the advice signature binds each of the method parameters in order.
@ -1320,6 +1346,7 @@ In many cases you will be doing this binding anyway (as in the example above).
[[aop-ataspectj-advice-ordering]] [[aop-ataspectj-advice-ordering]]
==== Advice ordering ==== Advice ordering
What happens when multiple pieces of advice all want to run at the same join point? What happens when multiple pieces of advice all want to run at the same join point?
Spring AOP follows the same precedence rules as AspectJ to determine the order of advice Spring AOP follows the same precedence rules as AspectJ to determine the order of advice
execution. The highest precedence advice runs first "on the way in" (so given two pieces execution. The highest precedence advice runs first "on the way in" (so given two pieces
@ -1345,6 +1372,7 @@ pieces of advice into separate aspect classes - which can be ordered at the aspe
[[aop-introductions]] [[aop-introductions]]
=== Introductions === Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects. that interface on behalf of those objects.
@ -1389,6 +1417,7 @@ you would write the following:
[[aop-instantiation-models]] [[aop-instantiation-models]]
=== Aspect instantiation models === Aspect instantiation models
[NOTE] [NOTE]
==== ====
(This is an advanced topic, so if you are just starting out with AOP you can safely skip (This is an advanced topic, so if you are just starting out with AOP you can safely skip
@ -1437,6 +1466,7 @@ creates one aspect instance for each unique target object at matched join points
[[aop-ataspectj-example]] [[aop-ataspectj-example]]
=== Example === Example
Now that you have seen how all the constituent parts work, let's put them together to do Now that you have seen how all the constituent parts work, let's put them together to do
something useful! something useful!
@ -1546,6 +1576,7 @@ expression so that only `@Idempotent` operations match:
[[aop-schema]] [[aop-schema]]
== Schema-based AOP support == Schema-based AOP support
If you prefer an XML-based format, then Spring also offers support for defining aspects If you prefer an XML-based format, then Spring also offers support for defining aspects
using the new "aop" namespace tags. The exact same pointcut expressions and advice kinds using the new "aop" namespace tags. The exact same pointcut expressions and advice kinds
are supported as when using the @AspectJ style, hence in this section we will focus on are supported as when using the @AspectJ style, hence in this section we will focus on
@ -1577,6 +1608,7 @@ just the `<aop:config>` style, or just the `AutoProxyCreator` style.
[[aop-schema-declaring-an-aspect]] [[aop-schema-declaring-an-aspect]]
=== Declaring an aspect === Declaring an aspect
Using the schema support, an aspect is simply a regular Java object defined as a bean in Using the schema support, an aspect is simply a regular Java object defined as a bean in
your Spring application context. The state and behavior is captured in the fields and your Spring application context. The state and behavior is captured in the fields and
methods of the object, and the pointcut and advice information is captured in the XML. methods of the object, and the pointcut and advice information is captured in the XML.
@ -1605,6 +1637,7 @@ dependency injected just like any other Spring bean.
[[aop-schema-pointcuts]] [[aop-schema-pointcuts]]
=== Declaring a pointcut === Declaring a pointcut
A named pointcut can be declared inside an <aop:config> element, enabling the pointcut A named pointcut can be declared inside an <aop:config> element, enabling the pointcut
definition to be shared across several aspects and advisors. definition to be shared across several aspects and advisors.
@ -1724,12 +1757,14 @@ style.
[[aop-schema-advice]] [[aop-schema-advice]]
=== Declaring advice === Declaring advice
The same five advice kinds are supported as for the @AspectJ style, and they have The same five advice kinds are supported as for the @AspectJ style, and they have
exactly the same semantics. exactly the same semantics.
[[aop-schema-advice-before]] [[aop-schema-advice-before]]
==== Before advice ==== Before advice
Before advice runs before a matched method execution. It is declared inside an Before advice runs before a matched method execution. It is declared inside an
`<aop:aspect>` using the <aop:before> element. `<aop:aspect>` using the <aop:before> element.
@ -1777,6 +1812,7 @@ bean will be invoked.
[[aop-schema-advice-after-returning]] [[aop-schema-advice-after-returning]]
==== After returning advice ==== After returning advice
After returning advice runs when a matched method execution completes normally. It is After returning advice runs when a matched method execution completes normally. It is
declared inside an `<aop:aspect>` in the same way as before advice. For example: declared inside an `<aop:aspect>` in the same way as before advice. For example:
@ -1826,6 +1862,7 @@ example, the method signature may be declared as:
[[aop-schema-advice-after-throwing]] [[aop-schema-advice-after-throwing]]
==== After throwing advice ==== After throwing advice
After throwing advice executes when a matched method execution exits by throwing an After throwing advice executes when a matched method execution exits by throwing an
exception. It is declared inside an `<aop:aspect>` using the after-throwing element: exception. It is declared inside an `<aop:aspect>` using the after-throwing element:
@ -1875,6 +1912,7 @@ example, the method signature may be declared as:
[[aop-schema-advice-after-finally]] [[aop-schema-advice-after-finally]]
==== After (finally) advice ==== After (finally) advice
After (finally) advice runs however a matched method execution exits. It is declared After (finally) advice runs however a matched method execution exits. It is declared
using the `after` element: using the `after` element:
@ -1895,6 +1933,7 @@ using the `after` element:
[[aop-schema-advice-around]] [[aop-schema-advice-around]]
==== Around advice ==== Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes, execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all. and to determine when, how, and even if, the method actually gets to execute at all.
@ -1941,6 +1980,7 @@ The implementation of the `doBasicProfiling` advice would be exactly the same as
[[aop-schema-params]] [[aop-schema-params]]
==== Advice parameters ==== Advice parameters
The schema based declaration style supports fully typed advice in the same way as The schema based declaration style supports fully typed advice in the same way as
described for the @AspectJ support - by matching pointcut parameters by name against described for the @AspectJ support - by matching pointcut parameters by name against
advice method parameters. See <<aop-ataspectj-advice-params>> for details. If you wish advice method parameters. See <<aop-ataspectj-advice-params>> for details. If you wish
@ -2078,6 +2118,7 @@ ms % Task name
[[aop-ordering]] [[aop-ordering]]
==== Advice ordering ==== Advice ordering
When multiple advice needs to execute at the same join point (executing method) the When multiple advice needs to execute at the same join point (executing method) the
ordering rules are as described in <<aop-ataspectj-advice-ordering>>. The precedence ordering rules are as described in <<aop-ataspectj-advice-ordering>>. The precedence
between aspects is determined by either adding the `Order` annotation to the bean between aspects is determined by either adding the `Order` annotation to the bean
@ -2087,6 +2128,7 @@ backing the aspect or by having the bean implement the `Ordered` interface.
[[aop-schema-introductions]] [[aop-schema-introductions]]
=== Introductions === Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects. that interface on behalf of those objects.
@ -2143,6 +2185,7 @@ following:
[[aop-schema-instatiation-models]] [[aop-schema-instatiation-models]]
=== Aspect instantiation models === Aspect instantiation models
The only supported instantiation model for schema-defined aspects is the singleton The only supported instantiation model for schema-defined aspects is the singleton
model. Other instantiation models may be supported in future releases. model. Other instantiation models may be supported in future releases.
@ -2150,7 +2193,8 @@ model. Other instantiation models may be supported in future releases.
[[aop-schema-advisors]] [[aop-schema-advisors]]
=== Advisors === Advisors
The concept of "advisors" is brought forward from the AOP support defined in Spring 1.2
The concept of "advisors" is brought forward from the AOP support defined in Spring
and does not have a direct equivalent in AspectJ. An advisor is like a small and does not have a direct equivalent in AspectJ. An advisor is like a small
self-contained aspect that has a single piece of advice. The advice itself is self-contained aspect that has a single piece of advice. The advice itself is
represented by a bean, and must implement one of the advice interfaces described in represented by a bean, and must implement one of the advice interfaces described in
@ -2192,6 +2236,7 @@ use the `order` attribute to define the `Ordered` value of the advisor.
[[aop-schema-example]] [[aop-schema-example]]
=== Example === Example
Let's see how the concurrent locking failure retry example from Let's see how the concurrent locking failure retry example from
<<aop-ataspectj-example>> looks when rewritten using the schema support. <<aop-ataspectj-example>> looks when rewritten using the schema support.
@ -2318,6 +2363,7 @@ pointcut expression so that only `@Idempotent` operations match:
[[aop-choosing]] [[aop-choosing]]
== Choosing which AOP declaration style to use == Choosing which AOP declaration style to use
Once you have decided that an aspect is the best approach for implementing a given Once you have decided that an aspect is the best approach for implementing a given
requirement, how do you decide between using Spring AOP or AspectJ, and between the requirement, how do you decide between using Spring AOP or AspectJ, and between the
Aspect language (code) style, @AspectJ annotation style, or the Spring XML style? These Aspect language (code) style, @AspectJ annotation style, or the Spring XML style? These
@ -2328,6 +2374,7 @@ development tools, and team familiarity with AOP.
[[aop-spring-or-aspectj]] [[aop-spring-or-aspectj]]
=== Spring AOP or full AspectJ? === Spring AOP or full AspectJ?
Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as
there is no requirement to introduce the AspectJ compiler / weaver into your development there is no requirement to introduce the AspectJ compiler / weaver into your development
and build processes. If you only need to advise the execution of operations on Spring and build processes. If you only need to advise the execution of operations on Spring
@ -2351,6 +2398,7 @@ an aspect weaving phase to your build script.
[[aop-ataspectj-or-xml]] [[aop-ataspectj-or-xml]]
=== @AspectJ or XML for Spring AOP? === @AspectJ or XML for Spring AOP?
If you have chosen to use Spring AOP, then you have a choice of @AspectJ or XML style. If you have chosen to use Spring AOP, then you have a choice of @AspectJ or XML style.
There are various tradeoffs to consider. There are various tradeoffs to consider.
@ -2413,6 +2461,7 @@ that do more than simple "configuration" of enterprise services.
[[aop-mixing-styles]] [[aop-mixing-styles]]
== Mixing aspect types == Mixing aspect types
It is perfectly possible to mix @AspectJ style aspects using the autoproxying support, It is perfectly possible to mix @AspectJ style aspects using the autoproxying support,
schema-defined `<aop:aspect>` aspects, `<aop:advisor>` declared advisors and even schema-defined `<aop:aspect>` aspects, `<aop:advisor>` declared advisors and even
proxies and interceptors defined using the Spring 1.2 style in the same configuration. proxies and interceptors defined using the Spring 1.2 style in the same configuration.
@ -2424,6 +2473,7 @@ co-exist without any difficulty.
[[aop-proxying]] [[aop-proxying]]
== Proxying mechanisms == Proxying mechanisms
Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given
target object. (JDK dynamic proxies are preferred whenever you have a choice). target object. (JDK dynamic proxies are preferred whenever you have a choice).
@ -2483,6 +2533,7 @@ proxies __for all three of them__.
[[aop-understanding-aop-proxies]] [[aop-understanding-aop-proxies]]
=== Understanding AOP proxies === Understanding AOP proxies
Spring AOP is __proxy-based__. It is vitally important that you grasp the semantics of Spring AOP is __proxy-based__. It is vitally important that you grasp the semantics of
what that last statement actually means before you write your own aspects or use any of what that last statement actually means before you write your own aspects or use any of
the Spring AOP-based aspects supplied with the Spring Framework. the Spring AOP-based aspects supplied with the Spring Framework.
@ -2617,6 +2668,7 @@ it is not a proxy-based AOP framework.
[[aop-aspectj-programmatic]] [[aop-aspectj-programmatic]]
== Programmatic creation of @AspectJ Proxies == Programmatic creation of @AspectJ Proxies
In addition to declaring aspects in your configuration using either `<aop:config>` or In addition to declaring aspects in your configuration using either `<aop:config>` or
`<aop:aspectj-autoproxy>`, it is also possible programmatically to create proxies that `<aop:aspectj-autoproxy>`, it is also possible programmatically to create proxies that
advise target objects. For the full details of Spring's AOP API, see the next chapter. advise target objects. For the full details of Spring's AOP API, see the next chapter.
@ -2650,6 +2702,7 @@ full information.
[[aop-using-aspectj]] [[aop-using-aspectj]]
== Using AspectJ with Spring applications == Using AspectJ with Spring applications
Everything we've covered so far in this chapter is pure Spring AOP. In this section, Everything we've covered so far in this chapter is pure Spring AOP. In this section,
we're going to look at how you can use the AspectJ compiler/weaver instead of, or in we're going to look at how you can use the AspectJ compiler/weaver instead of, or in
addition to, Spring AOP if your needs go beyond the facilities offered by Spring AOP addition to, Spring AOP if your needs go beyond the facilities offered by Spring AOP
@ -2667,6 +2720,7 @@ using AspectJ.
[[aop-atconfigurable]] [[aop-atconfigurable]]
=== Using AspectJ to dependency inject domain objects with Spring === Using AspectJ to dependency inject domain objects with Spring
The Spring container instantiates and configures beans defined in your application The Spring container instantiates and configures beans defined in your application
context. It is also possible to ask a bean factory to configure a __pre-existing__ context. It is also possible to ask a bean factory to configure a __pre-existing__
object given the name of a bean definition containing the configuration to be applied. object given the name of a bean definition containing the configuration to be applied.
@ -2848,6 +2902,7 @@ that it has not been configured by Spring.
[[aop-configurable-container]] [[aop-configurable-container]]
==== Working with multiple application contexts ==== Working with multiple application contexts
The `AnnotationBeanConfigurerAspect` used to implement the `@Configurable` support is an The `AnnotationBeanConfigurerAspect` used to implement the `@Configurable` support is an
AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope of AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope of
`static` members, that is to say there is one aspect instance per classloader that `static` members, that is to say there is one aspect instance per classloader that
@ -2877,6 +2932,7 @@ not what you want.
[[aop-ajlib-other]] [[aop-ajlib-other]]
=== Other Spring aspects for AspectJ === Other Spring aspects for AspectJ
In addition to the `@Configurable` aspect, `spring-aspects.jar` contains an AspectJ In addition to the `@Configurable` aspect, `spring-aspects.jar` contains an AspectJ
aspect that can be used to drive Spring's transaction management for types and methods aspect that can be used to drive Spring's transaction management for types and methods
annotated with the `@Transactional` annotation. This is primarily intended for users who annotated with the `@Transactional` annotation. This is primarily intended for users who
@ -2934,6 +2990,7 @@ fully-qualified class names:
[[aop-aj-configure]] [[aop-aj-configure]]
=== Configuring AspectJ aspects using Spring IoC === Configuring AspectJ aspects using Spring IoC
When using AspectJ aspects with Spring applications, it is natural to both want and When using AspectJ aspects with Spring applications, it is natural to both want and
expect to be able to configure such aspects using Spring. The AspectJ runtime itself is expect to be able to configure such aspects using Spring. The AspectJ runtime itself is
responsible for aspect creation, and the means of configuring the AspectJ created responsible for aspect creation, and the means of configuring the AspectJ created
@ -2991,6 +3048,7 @@ declaration is just being used here, but the AspectJ runtime is __not__ involved
[[aop-aj-ltw]] [[aop-aj-ltw]]
=== Load-time weaving with AspectJ in the Spring Framework === Load-time weaving with AspectJ in the Spring Framework
Load-time weaving (LTW) refers to the process of weaving AspectJ aspects into an Load-time weaving (LTW) refers to the process of weaving AspectJ aspects into an
application's class files as they are being loaded into the Java virtual machine (JVM). application's class files as they are being loaded into the Java virtual machine (JVM).
The focus of this section is on configuring and using LTW in the specific context of the The focus of this section is on configuring and using LTW in the specific context of the
@ -3026,6 +3084,7 @@ https://github.com/spring-projects/spring-petclinic[Petclinic sample application
[[aop-aj-ltw-first-example]] [[aop-aj-ltw-first-example]]
==== A first example ==== A first example
Let us assume that you are an application developer who has been tasked with diagnosing Let us assume that you are an application developer who has been tasked with diagnosing
the cause of some performance problems in a system. Rather than break out a profiling the cause of some performance problems in a system. Rather than break out a profiling
tool, what we are going to do is switch on a simple profiling aspect that will enable us tool, what we are going to do is switch on a simple profiling aspect that will enable us
@ -3234,6 +3293,7 @@ into UAT or production.
[[aop-aj-ltw-the-aspects]] [[aop-aj-ltw-the-aspects]]
==== Aspects ==== Aspects
The aspects that you use in LTW have to be AspectJ aspects. They can be written in The aspects that you use in LTW have to be AspectJ aspects. They can be written in
either the AspectJ language itself or you can write your aspects in the @AspectJ-style. either the AspectJ language itself or you can write your aspects in the @AspectJ-style.
It means that your aspects are then both valid AspectJ __and__ Spring AOP aspects. It means that your aspects are then both valid AspectJ __and__ Spring AOP aspects.
@ -3258,6 +3318,7 @@ directing you there.)
[[aop-aj-ltw-libraries]] [[aop-aj-ltw-libraries]]
==== Required libraries (JARS) ==== Required libraries (JARS)
At a minimum you will need the following libraries to use the Spring Framework's support At a minimum you will need the following libraries to use the Spring Framework's support
for AspectJ LTW: for AspectJ LTW:
@ -3272,6 +3333,7 @@ instrumentation>>, you will also need:
[[aop-aj-ltw-spring]] [[aop-aj-ltw-spring]]
==== Spring configuration ==== Spring configuration
The key component in Spring's LTW support is the `LoadTimeWeaver` interface (in the The key component in Spring's LTW support is the `LoadTimeWeaver` interface (in the
`org.springframework.instrument.classloading` package), and the numerous implementations `org.springframework.instrument.classloading` package), and the numerous implementations
of it that ship with the Spring distribution. A `LoadTimeWeaver` is responsible for of it that ship with the Spring distribution. A `LoadTimeWeaver` is responsible for
@ -3281,7 +3343,6 @@ happens to be the LTW of aspects.
[TIP] [TIP]
==== ====
If you are unfamiliar with the idea of runtime class file transformation, you are If you are unfamiliar with the idea of runtime class file transformation, you are
encouraged to read the javadoc API documentation for the `java.lang.instrument` package encouraged to read the javadoc API documentation for the `java.lang.instrument` package
before continuing. This is not a huge chore because there is - rather annoyingly - before continuing. This is not a huge chore because there is - rather annoyingly -
@ -3447,12 +3508,14 @@ It accepts one of three possible values, summarized below, with the default valu
[[aop-aj-ltw-environments]] [[aop-aj-ltw-environments]]
==== Environment-specific configuration ==== Environment-specific configuration
This last section contains any additional settings and configuration that you will need This last section contains any additional settings and configuration that you will need
when using Spring's LTW support in environments such as application servers and web when using Spring's LTW support in environments such as application servers and web
containers. containers.
[[aop-aj-ltw-environment-tomcat]] [[aop-aj-ltw-environment-tomcat]]
===== Tomcat ===== Tomcat
Historically, http://tomcat.apache.org/[Apache Tomcat]'s default class loader did not Historically, http://tomcat.apache.org/[Apache Tomcat]'s default class loader did not
support class transformation which is why Spring provides an enhanced implementation support class transformation which is why Spring provides an enhanced implementation
that addresses this need. Named `TomcatInstrumentableClassLoader`, the loader works on that addresses this need. Named `TomcatInstrumentableClassLoader`, the loader works on
@ -3503,6 +3566,7 @@ deployed web applications, no matter what ClassLoader they happen to run on.
[[aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss]] [[aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss]]
===== WebLogic, WebSphere, Resin, GlassFish, JBoss ===== WebLogic, WebSphere, Resin, GlassFish, JBoss
Recent versions of WebLogic Server (version 10 and above), IBM WebSphere Application Recent versions of WebLogic Server (version 10 and above), IBM WebSphere Application
Server (version 7 and above), Resin (3.1 and above) and JBoss (6.x or above) provide a Server (version 7 and above), Resin (3.1 and above) and JBoss (6.x or above) provide a
ClassLoader that is capable of local instrumentation. Spring's native LTW leverages such ClassLoader that is capable of local instrumentation. Spring's native LTW leverages such
@ -3526,6 +3590,7 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co
[[aop-aj-ltw-environment-generic]] [[aop-aj-ltw-environment-generic]]
===== Generic Java applications ===== Generic Java applications
When class instrumentation is required in environments that do not support or are not When class instrumentation is required in environments that do not support or are not
supported by the existing `LoadTimeWeaver` implementations, a JDK agent can be the only supported by the existing `LoadTimeWeaver` implementations, a JDK agent can be the only
solution. For such cases, Spring provides `InstrumentationLoadTimeWeaver`, which solution. For such cases, Spring provides `InstrumentationLoadTimeWeaver`, which
@ -3554,6 +3619,7 @@ support) a dedicated LTW.
[[aop-resources]] [[aop-resources]]
== Further Resources == Further Resources
More information on AspectJ can be found on the http://www.eclipse.org/aspectj[AspectJ More information on AspectJ can be found on the http://www.eclipse.org/aspectj[AspectJ
website]. website].
@ -3563,4 +3629,3 @@ comprehensive introduction and reference for the AspectJ language.
The book __AspectJ in Action, Second Edition__ by Ramnivas Laddad (Manning, 2009) comes highly The book __AspectJ in Action, Second Edition__ by Ramnivas Laddad (Manning, 2009) comes highly
recommended; the focus of the book is on AspectJ, but a lot of general AOP themes are recommended; the focus of the book is on AspectJ, but a lot of general AOP themes are
explored (in some depth). explored (in some depth).

View File

@ -4,6 +4,8 @@
= Appendix = Appendix
[[xsd-schemas]] [[xsd-schemas]]
== XML Schemas == XML Schemas
@ -123,7 +125,7 @@ Injecting enum values into beans as either property or constructor arguments is
easy to do in Spring, in that you don't actually have to __do__ anything or know easy to do in Spring, in that you don't actually have to __do__ anything or know
anything about the Spring internals (or even about classes such as the anything about the Spring internals (or even about classes such as the
`FieldRetrievingFactoryBean`). Let's look at an example to see how easy injecting an `FieldRetrievingFactoryBean`). Let's look at an example to see how easy injecting an
enum value is; consider this JDK 5 enum: enum value is; consider this enum:
[source,java,indent=0] [source,java,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
@ -134,7 +136,6 @@ enum value is; consider this JDK 5 enum:
TRANSACTION, TRANSACTION,
EXTENDED EXTENDED
} }
---- ----
@ -152,7 +153,6 @@ Now consider a setter of type `PersistenceContextType`:
public void setPersistenceContextType(PersistenceContextType type) { public void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type; this.persistenceContextType = type;
} }
} }
---- ----
@ -162,14 +162,10 @@ Now consider a setter of type `PersistenceContextType`:
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
<bean class="example.Client"> <bean class="example.Client">
<property name="persistenceContextType" value="TRANSACTION" /> <property name="persistenceContextType" value="TRANSACTION"/>
</bean> </bean>
---- ----
This works for classic type-safe emulated enums (on JDK 1.4 and JDK 1.3) as well; Spring
will automatically attempt to match the string property value to a constant on the enum
class.
[[xsd-schemas-util-property-path]] [[xsd-schemas-util-property-path]]
==== <util:property-path/> ==== <util:property-path/>
@ -786,14 +782,14 @@ The `NamespaceHandler` interface is pretty simple in that it features just three
* `init()` - allows for initialization of the `NamespaceHandler` and will be called by * `init()` - allows for initialization of the `NamespaceHandler` and will be called by
Spring before the handler is used Spring before the handler is used
* `BeanDefinition parse(Element, ParserContext)` - called when Spring encounters a * `BeanDefinition parse(Element, ParserContext)` - called when Spring encounters a
top-level element (not nested inside a bean definition or a different namespace). This top-level element (not nested inside a bean definition or a different namespace).
method can register bean definitions itself and/or return a bean definition. This method can register bean definitions itself and/or return a bean definition.
* `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)` - called * `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)` - called
when Spring encounters an attribute or nested element of a different namespace. The when Spring encounters an attribute or nested element of a different namespace.
decoration of one or more bean definitions is used for example with The decoration of one or more bean definitions is used for example with the
the<<core.adoc#beans-factory-scopes,out-of-the-box scopes Spring 2.0 supports>>. We'll start by <<core.adoc#beans-factory-scopes,out-of-the-box scopes Spring supports>>.
highlighting a simple example, without using decoration, after which we will show We'll start by highlighting a simple example, without using decoration, after which
decoration in a somewhat more advanced example. we will show decoration in a somewhat more advanced example.
Although it is perfectly possible to code your own `NamespaceHandler` for the entire Although it is perfectly possible to code your own `NamespaceHandler` for the entire
namespace (and hence provide code that parses each and every element in the namespace), namespace (and hence provide code that parses each and every element in the namespace),
@ -1373,4 +1369,3 @@ http\://www.foo.com/schema/jcache=com.foo.JCacheNamespaceHandler
# in 'META-INF/spring.schemas' # in 'META-INF/spring.schemas'
http\://www.foo.com/schema/jcache/jcache.xsd=com/foo/jcache.xsd http\://www.foo.com/schema/jcache/jcache.xsd=com/foo/jcache.xsd
---- ----

View File

@ -2,6 +2,8 @@
= The IoC container = The IoC container
[[beans-introduction]] [[beans-introduction]]
== Introduction to the Spring IoC container and beans == Introduction to the Spring IoC container and beans
@ -400,6 +402,7 @@ a dependency on a specific bean through metadata (e.g. an autowiring annotation)
[[beans-definition]] [[beans-definition]]
== Bean overview == Bean overview
A Spring IoC container manages one or more __beans__. These beans are created with the A Spring IoC container manages one or more __beans__. These beans are created with the
configuration metadata that you supply to the container, for example, in the form of XML configuration metadata that you supply to the container, for example, in the form of XML
`<bean/>` definitions. `<bean/>` definitions.
@ -778,6 +781,7 @@ Spring container that will create objects through an
[[beans-dependencies]] [[beans-dependencies]]
== Dependencies == Dependencies
A typical enterprise application does not consist of a single object (or bean in the A typical enterprise application does not consist of a single object (or bean in the
Spring parlance). Even the simplest application has a few objects that work together to Spring parlance). Even the simplest application has a few objects that work together to
present what the end-user sees as a coherent application. This next section explains how present what the end-user sees as a coherent application. This next section explains how
@ -2380,6 +2384,7 @@ shortest string that will match an argument type.
[[beans-factory-scopes]] [[beans-factory-scopes]]
== Bean scopes == Bean scopes
When you create a bean definition, you create a __recipe__ for creating actual instances When you create a bean definition, you create a __recipe__ for creating actual instances
of the class defined by that bean definition. The idea that a bean definition is a of the class defined by that bean definition. The idea that a bean definition is a
recipe is important, because it means that, as with a class, you can create many object recipe is important, because it means that, as with a class, you can create many object
@ -3602,6 +3607,7 @@ beans that require programmatic access to the container.
[[beans-child-bean-definitions]] [[beans-child-bean-definitions]]
== Bean definition inheritance == Bean definition inheritance
A bean definition can contain a lot of configuration information, including constructor A bean definition can contain a lot of configuration information, including constructor
arguments, property values, and container-specific information such as initialization arguments, property values, and container-specific information such as initialization
method, static factory method name, and so on. A child bean definition inherits method, static factory method name, and so on. A child bean definition inherits
@ -3687,6 +3693,7 @@ context will actually (attempt to) pre-instantiate the `abstract` bean.
[[beans-factory-extension]] [[beans-factory-extension]]
== Container Extension Points == Container Extension Points
Typically, an application developer does not need to subclass `ApplicationContext` Typically, an application developer does not need to subclass `ApplicationContext`
implementation classes. Instead, the Spring IoC container can be extended by plugging in implementation classes. Instead, the Spring IoC container can be extended by plugging in
implementations of special integration interfaces. The next few sections describe these implementations of special integration interfaces. The next few sections describe these
@ -5173,6 +5180,7 @@ For details about the effects of combining various lifecycle mechanisms, see
[[beans-classpath-scanning]] [[beans-classpath-scanning]]
== Classpath scanning and managed components == Classpath scanning and managed components
Most examples in this chapter use XML to specify the configuration metadata that produces Most examples in this chapter use XML to specify the configuration metadata that produces
each `BeanDefinition` within the Spring container. The previous section each `BeanDefinition` within the Spring container. The previous section
(<<beans-annotation-config>>) demonstrates how to provide a lot of the configuration (<<beans-annotation-config>>) demonstrates how to provide a lot of the configuration
@ -5299,6 +5307,7 @@ https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Progr
wiki page. wiki page.
[[beans-scanning-autodetection]] [[beans-scanning-autodetection]]
=== Automatically detecting classes and registering bean definitions === Automatically detecting classes and registering bean definitions
@ -5839,6 +5848,7 @@ metadata is provided per-instance rather than per-class.
[[beans-scanning-index]] [[beans-scanning-index]]
=== Generating an index of candidate components === Generating an index of candidate components
While classpath scanning is very fast, it is possible to improve the startup performance While classpath scanning is very fast, it is possible to improve the startup performance
of large applications by creating a static list of candidates at compilation time. In this of large applications by creating a static list of candidates at compilation time. In this
mode, _all modules_ of the application must use this mechanism as, when the mode, _all modules_ of the application must use this mechanism as, when the
@ -5893,8 +5903,10 @@ classpath.
[[beans-standard-annotations]] [[beans-standard-annotations]]
== Using JSR 330 Standard Annotations == Using JSR 330 Standard Annotations
Starting with Spring 3.0, Spring offers support for JSR-330 standard annotations Starting with Spring 3.0, Spring offers support for JSR-330 standard annotations
(Dependency Injection). Those annotations are scanned in the same way as the Spring (Dependency Injection). Those annotations are scanned in the same way as the Spring
annotations. You just need to have the relevant jars in your classpath. annotations. You just need to have the relevant jars in your classpath.
@ -6742,6 +6754,7 @@ annotation can be used:
---- ----
[[beans-java-configuration-annotation]] [[beans-java-configuration-annotation]]
=== Using the @Configuration annotation === Using the @Configuration annotation
@ -7979,7 +7992,7 @@ AspectJ load-time weaving, see <<aop-aj-ltw>>.
[[context-introduction]] [[context-introduction]]
== Additional Capabilities of the ApplicationContext == Additional capabilities of the ApplicationContext
As was discussed in the chapter introduction, the `org.springframework.beans.factory` As was discussed in the chapter introduction, the `org.springframework.beans.factory`
package provides basic functionality for managing and manipulating beans, including in a package provides basic functionality for managing and manipulating beans, including in a
@ -8211,7 +8224,7 @@ out the `ReloadableResourceBundleMessageSource` javadocs for details.
[[context-functionality-events]] [[context-functionality-events]]
=== Standard and Custom Events === Standard and custom events
Event handling in the `ApplicationContext` is provided through the `ApplicationEvent` Event handling in the `ApplicationContext` is provided through the `ApplicationEvent`
class and `ApplicationListener` interface. If a bean that implements the class and `ApplicationListener` interface. If a bean that implements the
@ -8400,8 +8413,9 @@ http://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven
architectures that build upon the well-known Spring programming model. architectures that build upon the well-known Spring programming model.
==== ====
[[context-functionality-events-annotation]] [[context-functionality-events-annotation]]
==== Annotation-based Event Listeners ==== Annotation-based event listeners
As of Spring 4.2, an event listener can be registered on any public method of a managed As of Spring 4.2, an event listener can be registered on any public method of a managed
bean via the `EventListener` annotation. The `BlackListNotifier` can be rewritten as bean via the `EventListener` annotation. The `BlackListNotifier` can be rewritten as
@ -8508,6 +8522,7 @@ This new method will publish a new `ListUpdateEvent` for every `BlackListEvent`
by the method above. If you need to publish several events, just return a `Collection` of by the method above. If you need to publish several events, just return a `Collection` of
events instead. events instead.
[[context-functionality-events-async]] [[context-functionality-events-async]]
==== Asynchronous Listeners ==== Asynchronous Listeners
@ -8534,7 +8549,7 @@ Be aware of the following limitations when using asynchronous events:
[[context-functionality-events-order]] [[context-functionality-events-order]]
==== Ordering Listeners ==== Ordering listeners
If you need the listener to be invoked before another one, just add the `@Order` If you need the listener to be invoked before another one, just add the `@Order`
annotation to the method declaration: annotation to the method declaration:
@ -8549,8 +8564,9 @@ annotation to the method declaration:
} }
---- ----
[[context-functionality-events-generics]] [[context-functionality-events-generics]]
==== Generic Events ==== Generic events
You may also use generics to further define the structure of your event. Consider an You may also use generics to further define the structure of your event. Consider an
`EntityCreatedEvent<T>` where `T` is the type of the actual entity that got created. You `EntityCreatedEvent<T>` where `T` is the type of the actual entity that got created. You
@ -8716,14 +8732,15 @@ be used by other application modules on the same machine.
[[beans-beanfactory]] [[beans-beanfactory]]
== The BeanFactory == The BeanFactory
The `BeanFactory` provides the underlying basis for Spring's IoC functionality but it is The `BeanFactory` provides the underlying basis for Spring's IoC functionality but it is
only used directly in integration with other third-party frameworks and is now largely only used directly in integration with other third-party frameworks and is now largely
historical in nature for most users of Spring. The `BeanFactory` and related interfaces, historical in nature for most users of Spring. The `BeanFactory` and related interfaces,
such as `BeanFactoryAware`, `InitializingBean`, `DisposableBean`, are still present in such as `BeanFactoryAware`, `InitializingBean`, `DisposableBean`, are still present in
Spring for the purposes of backward compatibility with the large number of third-party Spring for the purposes of backward compatibility with the large number of third-party
frameworks that integrate with Spring. Often third-party components that can not use frameworks that integrate with Spring. Often third-party components that can not use
more modern equivalents such as `@PostConstruct` or `@PreDestroy` in order to remain more modern equivalents such as `@PostConstruct` or `@PreDestroy` in order to avoid a
compatible with JDK 1.4 or to avoid a dependency on JSR-250. dependency on JSR-250.
This section provides additional background into the differences between the This section provides additional background into the differences between the
`BeanFactory` and `ApplicationContext` and how one might access the IoC container `BeanFactory` and `ApplicationContext` and how one might access the IoC container

View File

@ -6,6 +6,7 @@
[[expressions-intro]] [[expressions-intro]]
== Introduction == Introduction
The Spring Expression Language (SpEL for short) is a powerful expression language that The Spring Expression Language (SpEL for short) is a powerful expression language that
supports querying and manipulating an object graph at runtime. The language syntax is supports querying and manipulating an object graph at runtime. The language syntax is
similar to Unified EL but offers additional features, most notably method invocation and similar to Unified EL but offers additional features, most notably method invocation and
@ -39,7 +40,8 @@ populate them are listed at the end of the chapter.
[[expressions-features]] [[expressions-features]]
== Feature Overview == Feature overview
The expression language supports the following functionality The expression language supports the following functionality
* Literal expressions * Literal expressions
@ -66,7 +68,8 @@ The expression language supports the following functionality
[[expressions-evaluation]] [[expressions-evaluation]]
== Expression Evaluation using Spring's Expression Interface == Expression evaluation using Spring's Expression interface
This section introduces the simple use of SpEL interfaces and its expression language. This section introduces the simple use of SpEL interfaces and its expression language.
The complete language reference can be found in the section The complete language reference can be found in the section
<<expressions-language-ref,Language Reference>>. <<expressions-language-ref,Language Reference>>.
@ -235,6 +238,7 @@ Inventor object in the previous example.
[[expressions-evaluation-context]] [[expressions-evaluation-context]]
=== The EvaluationContext interface === The EvaluationContext interface
The interface `EvaluationContext` is used when evaluating an expression to resolve The interface `EvaluationContext` is used when evaluating an expression to resolve
properties, methods, fields, and to help perform type conversion. The out-of-the-box properties, methods, fields, and to help perform type conversion. The out-of-the-box
implementation, `StandardEvaluationContext`, uses reflection to manipulate the object, implementation, `StandardEvaluationContext`, uses reflection to manipulate the object,
@ -253,7 +257,8 @@ evaluates expressions. Please refer to the javadoc of these classes for more det
[[expressions-type-conversion]] [[expressions-type-conversion]]
==== Type Conversion ==== Type conversion
By default SpEL uses the conversion service available in Spring core ( By default SpEL uses the conversion service available in Spring core (
`org.springframework.core.convert.ConversionService`). This conversion service comes `org.springframework.core.convert.ConversionService`). This conversion service comes
with many converters built in for common conversions but is also fully extensible so with many converters built in for common conversions but is also fully extensible so
@ -288,9 +293,12 @@ being placed in it. A simple example:
Boolean b = simple.booleanList.get(0); Boolean b = simple.booleanList.get(0);
---- ----
[[expressions-parser-configuration]] [[expressions-parser-configuration]]
=== Parser configuration === Parser configuration
It is possible to configure the SpEL expression parser using a parser configuration object
It is possible to configure the SpEL expression parser using a parser configuration object
(`org.springframework.expression.spel.SpelParserConfiguration`). The configuration (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration
object controls the behavior of some of the expression components. For example, if object controls the behavior of some of the expression components. For example, if
indexing into an array or collection and the element at the specified index is `null` indexing into an array or collection and the element at the specified index is `null`
@ -325,6 +333,8 @@ list it is possible to automatically grow the array or list to accommodate that
It is also possible to configure the behaviour of the SpEL expression compiler. It is also possible to configure the behaviour of the SpEL expression compiler.
[[expressions-spel-compilation]] [[expressions-spel-compilation]]
=== SpEL compilation === SpEL compilation
@ -356,6 +366,7 @@ gain can be very noticeable. In an example micro benchmark run of 50000 iteratio
taking 75ms to evaluate using only the interpreter and just 3ms using the compiled version taking 75ms to evaluate using only the interpreter and just 3ms using the compiled version
of the expression. of the expression.
[[expressions-compiler-configuration]] [[expressions-compiler-configuration]]
==== Compiler configuration ==== Compiler configuration
@ -415,6 +426,7 @@ In these cases it is possible to use a system property. The property
`spring.expression.compiler.mode` can be set to one of the `SpelCompilerMode` `spring.expression.compiler.mode` can be set to one of the `SpelCompilerMode`
enum values (`off`, `immediate`, or `mixed`). enum values (`off`, `immediate`, or `mixed`).
[[expressions-compiler-limitations]] [[expressions-compiler-limitations]]
==== Compiler limitations ==== Compiler limitations
@ -430,8 +442,12 @@ at the moment:
More and more types of expression will be compilable in the future. More and more types of expression will be compilable in the future.
[[expressions-beandef]] [[expressions-beandef]]
== Expression support for defining bean definitions == Expression support for defining bean definitions
SpEL expressions can be used with XML or annotation-based configuration metadata for SpEL expressions can be used with XML or annotation-based configuration metadata for
defining ``BeanDefinition``s. In both cases the syntax to define the expression is of the defining ``BeanDefinition``s. In both cases the syntax to define the expression is of the
form `#{ <expression string> }`. form `#{ <expression string> }`.
@ -440,6 +456,7 @@ form `#{ <expression string> }`.
[[expressions-beandef-xml-based]] [[expressions-beandef-xml-based]]
=== XML based configuration === XML based configuration
A property or constructor-arg value can be set using expressions as shown below. A property or constructor-arg value can be set using expressions as shown below.
[source,xml,indent=0] [source,xml,indent=0]
@ -488,6 +505,7 @@ You can also refer to other bean properties by name, for example.
[[expressions-beandef-annotation-based]] [[expressions-beandef-annotation-based]]
=== Annotation-based configuration === Annotation-based configuration
The `@Value` annotation can be placed on fields, methods and method/constructor The `@Value` annotation can be placed on fields, methods and method/constructor
parameters to specify a default value. parameters to specify a default value.
@ -584,6 +602,7 @@ Autowired methods and constructors can also use the `@Value` annotation.
[[expressions-ref-literal]] [[expressions-ref-literal]]
=== Literal expressions === Literal expressions
The types of literal expressions supported are strings, numeric values (int, real, hex), The types of literal expressions supported are strings, numeric values (int, real, hex),
boolean and null. Strings are delimited by single quotes. To put a single quote itself boolean and null. Strings are delimited by single quotes. To put a single quote itself
in a string, use two single quote characters. in a string, use two single quote characters.
@ -617,6 +636,7 @@ By default real numbers are parsed using Double.parseDouble().
[[expressions-properties-arrays]] [[expressions-properties-arrays]]
=== Properties, Arrays, Lists, Maps, Indexers === Properties, Arrays, Lists, Maps, Indexers
Navigating with property references is easy: just use a period to indicate a nested Navigating with property references is easy: just use a period to indicate a nested
property value. The instances of the `Inventor` class, pupin, and tesla, were populated with property value. The instances of the `Inventor` class, pupin, and tesla, were populated with
data listed in the section <<expressions-example-classes,Classes used in the examples>>. data listed in the section <<expressions-example-classes,Classes used in the examples>>.
@ -685,6 +705,7 @@ string literals.
[[expressions-inline-lists]] [[expressions-inline-lists]]
=== Inline lists === Inline lists
Lists can be expressed directly in an expression using `{}` notation. Lists can be expressed directly in an expression using `{}` notation.
[source,java,indent=0] [source,java,indent=0]
@ -700,8 +721,11 @@ Lists can be expressed directly in an expression using `{}` notation.
entirely composed of fixed literals then a constant list is created to represent the entirely composed of fixed literals then a constant list is created to represent the
expression, rather than building a new list on each evaluation. expression, rather than building a new list on each evaluation.
[[expressions-inline-maps]] [[expressions-inline-maps]]
=== Inline Maps === Inline Maps
Maps can also be expressed directly in an expression using `{key:value}` notation. Maps can also be expressed directly in an expression using `{key:value}` notation.
[source,java,indent=0] [source,java,indent=0]
@ -717,8 +741,11 @@ of fixed literals or other nested constant structures (lists or maps) then a con
to represent the expression, rather than building a new map on each evaluation. Quoting of the map keys to represent the expression, rather than building a new map on each evaluation. Quoting of the map keys
is optional, the examples above are not using quoted keys. is optional, the examples above are not using quoted keys.
[[expressions-array-construction]] [[expressions-array-construction]]
=== Array construction === Array construction
Arrays can be built using the familiar Java syntax, optionally supplying an initializer Arrays can be built using the familiar Java syntax, optionally supplying an initializer
to have the array populated at construction time. to have the array populated at construction time.
@ -741,6 +768,7 @@ multi-dimensional array.
[[expressions-methods]] [[expressions-methods]]
=== Methods === Methods
Methods are invoked using typical Java programming syntax. You may also invoke methods Methods are invoked using typical Java programming syntax. You may also invoke methods
on literals. Varargs are also supported. on literals. Varargs are also supported.
@ -763,6 +791,7 @@ on literals. Varargs are also supported.
[[expressions-operators-relational]] [[expressions-operators-relational]]
==== Relational operators ==== Relational operators
The relational operators; equal, not equal, less than, less than or equal, greater than, The relational operators; equal, not equal, less than, less than or equal, greater than,
and greater than or equal are supported using standard operator notation. and greater than or equal are supported using standard operator notation.
@ -825,6 +854,7 @@ shown here: `lt` (`<`), `gt` (`>`), `le` (`<=`), `ge` (`>=`), `eq` (`==`),
[[expressions-operators-logical]] [[expressions-operators-logical]]
==== Logical operators ==== Logical operators
The logical operators that are supported are and, or, and not. Their use is demonstrated The logical operators that are supported are and, or, and not. Their use is demonstrated
below. below.
@ -862,6 +892,7 @@ below.
[[expressions-operators-mathematical]] [[expressions-operators-mathematical]]
==== Mathematical operators ==== Mathematical operators
The addition operator can be used on both numbers and strings. Subtraction, multiplication The addition operator can be used on both numbers and strings. Subtraction, multiplication
and division can be used only on numbers. Other mathematical operators supported are and division can be used only on numbers. Other mathematical operators supported are
modulus (%) and exponential power (^). Standard operator precedence is enforced. These modulus (%) and exponential power (^). Standard operator precedence is enforced. These
@ -904,6 +935,7 @@ operators are demonstrated below.
[[expressions-assignment]] [[expressions-assignment]]
=== Assignment === Assignment
Setting of a property is done by using the assignment operator. This would typically be Setting of a property is done by using the assignment operator. This would typically be
done within a call to `setValue` but can also be done inside a call to `getValue`. done within a call to `setValue` but can also be done inside a call to `getValue`.
@ -925,6 +957,7 @@ done within a call to `setValue` but can also be done inside a call to `getValue
[[expressions-types]] [[expressions-types]]
=== Types === Types
The special `T` operator can be used to specify an instance of java.lang.Class (the The special `T` operator can be used to specify an instance of java.lang.Class (the
_type_). Static methods are invoked using this operator as well. The _type_). Static methods are invoked using this operator as well. The
`StandardEvaluationContext` uses a `TypeLocator` to find types and the `StandardEvaluationContext` uses a `TypeLocator` to find types and the
@ -948,6 +981,7 @@ fully qualified, but all other type references must be.
[[expressions-constructors]] [[expressions-constructors]]
=== Constructors === Constructors
Constructors can be invoked using the new operator. The fully qualified class name Constructors can be invoked using the new operator. The fully qualified class name
should be used for all but the primitive type and String (where int, float, etc, can be should be used for all but the primitive type and String (where int, float, etc, can be
used). used).
@ -969,6 +1003,7 @@ used).
[[expressions-ref-variables]] [[expressions-ref-variables]]
=== Variables === Variables
Variables can be referenced in the expression using the syntax `#variableName`. Variables Variables can be referenced in the expression using the syntax `#variableName`. Variables
are set using the method setVariable on the `StandardEvaluationContext`. are set using the method setVariable on the `StandardEvaluationContext`.
@ -987,6 +1022,7 @@ are set using the method setVariable on the `StandardEvaluationContext`.
[[expressions-this-root]] [[expressions-this-root]]
==== The #this and #root variables ==== The #this and #root variables
The variable #this is always defined and refers to the current evaluation object The variable #this is always defined and refers to the current evaluation object
(against which unqualified references are resolved). The variable #root is always (against which unqualified references are resolved). The variable #root is always
defined and refers to the root context object. Although #this may vary as components of defined and refers to the root context object. Although #this may vary as components of
@ -1014,6 +1050,7 @@ an expression are evaluated, #root always refers to the root.
[[expressions-ref-functions]] [[expressions-ref-functions]]
=== Functions === Functions
You can extend SpEL by registering user defined functions that can be called within the You can extend SpEL by registering user defined functions that can be called within the
expression string. The function is registered with the `StandardEvaluationContext` using expression string. The function is registered with the `StandardEvaluationContext` using
the method. the method.
@ -1062,6 +1099,7 @@ expression string.
[[expressions-bean-references]] [[expressions-bean-references]]
=== Bean references === Bean references
If the evaluation context has been configured with a bean resolver it is possible to If the evaluation context has been configured with a bean resolver it is possible to
lookup beans from an expression using the (@) symbol. lookup beans from an expression using the (@) symbol.
@ -1092,6 +1130,7 @@ To access a factory bean itself, the bean name should instead be prefixed with a
[[expressions-operator-ternary]] [[expressions-operator-ternary]]
=== Ternary Operator (If-Then-Else) === Ternary Operator (If-Then-Else)
You can use the ternary operator for performing if-then-else conditional logic inside You can use the ternary operator for performing if-then-else conditional logic inside
the expression. A minimal example is: the expression. A minimal example is:
@ -1126,6 +1165,7 @@ ternary operator.
[[expressions-operator-elvis]] [[expressions-operator-elvis]]
=== The Elvis Operator === The Elvis Operator
The Elvis operator is a shortening of the ternary operator syntax and is used in the The Elvis operator is a shortening of the ternary operator syntax and is used in the
http://www.groovy-lang.org/operators.html#_elvis_operator[Groovy] language. http://www.groovy-lang.org/operators.html#_elvis_operator[Groovy] language.
With the ternary operator syntax you usually have to repeat a variable twice, for With the ternary operator syntax you usually have to repeat a variable twice, for
@ -1175,6 +1215,7 @@ Here is a more complex example.
[[expressions-operator-safe-navigation]] [[expressions-operator-safe-navigation]]
=== Safe Navigation operator === Safe Navigation operator
The Safe Navigation operator is used to avoid a `NullPointerException` and comes from The Safe Navigation operator is used to avoid a `NullPointerException` and comes from
the http://www.groovy-lang.org/operators.html#_safe_navigation_operator[Groovy] the http://www.groovy-lang.org/operators.html#_safe_navigation_operator[Groovy]
language. Typically when you have a reference to an object you might need to verify that language. Typically when you have a reference to an object you might need to verify that
@ -1219,6 +1260,7 @@ This will inject a system property `pop3.port` if it is defined or 25 if not.
[[expressions-collection-selection]] [[expressions-collection-selection]]
=== Collection Selection === Collection Selection
Selection is a powerful expression language feature that allows you to transform some Selection is a powerful expression language feature that allows you to transform some
source collection into another by selecting from its entries. source collection into another by selecting from its entries.
@ -1256,6 +1298,7 @@ first or the last value. To obtain the first entry matching the selection the sy
[[expressions-collection-projection]] [[expressions-collection-projection]]
=== Collection Projection === Collection Projection
Projection allows a collection to drive the evaluation of a sub-expression and the Projection allows a collection to drive the evaluation of a sub-expression and the
result is a new collection. The syntax for projection is `![projectionExpression]`. Most result is a new collection. The syntax for projection is `![projectionExpression]`. Most
easily understood by example, suppose we have a list of inventors but want the list of easily understood by example, suppose we have a list of inventors but want the list of
@ -1278,6 +1321,7 @@ expression against each map entry.
[[expressions-templating]] [[expressions-templating]]
=== Expression templating === Expression templating
Expression templates allow a mixing of literal text with one or more evaluation blocks. Expression templates allow a mixing of literal text with one or more evaluation blocks.
Each evaluation block is delimited with prefix and suffix characters that you can Each evaluation block is delimited with prefix and suffix characters that you can
define, a common choice is to use `#{ }` as the delimiters. For example, define, a common choice is to use `#{ }` as the delimiters. For example,
@ -1323,6 +1367,7 @@ The definition of `TemplateParserContext` is shown below.
[[expressions-example-classes]] [[expressions-example-classes]]
== Classes used in the examples == Classes used in the examples
Inventor.java Inventor.java
[source,java,indent=0] [source,java,indent=0]

View File

@ -28,6 +28,9 @@ scope of this feature.
Libraries like Reactor or Spring Data provide null-safe APIs leveraging this feature. Libraries like Reactor or Spring Data provide null-safe APIs leveraging this feature.
==== ====
== Use cases == Use cases
In addition to providing an explicit declaration for Spring Framework API nullability, In addition to providing an explicit declaration for Spring Framework API nullability,

View File

@ -1,10 +1,12 @@
[[resources]] [[resources]]
= Resources = Resources
[[resources-introduction]] [[resources-introduction]]
== Introduction == Introduction
Java's standard `java.net.URL` class and standard handlers for various URL prefixes Java's standard `java.net.URL` class and standard handlers for various URL prefixes
unfortunately are not quite adequate enough for all access to low-level resources. For unfortunately are not quite adequate enough for all access to low-level resources. For
example, there is no standardized `URL` implementation that may be used to access a example, there is no standardized `URL` implementation that may be used to access a
@ -15,6 +17,8 @@ quite complicated, and the `URL` interface still lacks some desirable functional
such as a method to check for the existence of the resource being pointed to. such as a method to check for the existence of the resource being pointed to.
[[resources-resource]] [[resources-resource]]
== The Resource interface == The Resource interface
@ -378,6 +382,7 @@ used. The following two examples show how to force a `ClassPathResource` and a
[[resources-app-ctx-construction]] [[resources-app-ctx-construction]]
=== Constructing application contexts === Constructing application contexts
An application context constructor (for a specific application context type) generally An application context constructor (for a specific application context type) generally
takes a string or array of strings as the location path(s) of the resource(s) such as takes a string or array of strings as the location path(s) of the resource(s) such as
XML files that make up the definition of the context. XML files that make up the definition of the context.
@ -461,6 +466,7 @@ on the various constructors.
[[resources-app-ctx-wildcards-in-resource-paths]] [[resources-app-ctx-wildcards-in-resource-paths]]
=== Wildcards in application context constructor resource paths === Wildcards in application context constructor resource paths
The resource paths in application context constructor values may be a simple path (as The resource paths in application context constructor values may be a simple path (as
shown above) which has a one-to-one mapping to a target Resource, or alternately may shown above) which has a one-to-one mapping to a target Resource, or alternately may
contain the special "classpath*:" prefix and/or internal Ant-style regular expressions contain the special "classpath*:" prefix and/or internal Ant-style regular expressions
@ -481,6 +487,7 @@ a resource points to just one resource at a time.
[[resources-app-ctx-ant-patterns-in-paths]] [[resources-app-ctx-ant-patterns-in-paths]]
==== Ant-style Patterns ==== Ant-style Patterns
When the path location contains an Ant-style pattern, for example: When the path location contains an Ant-style pattern, for example:
[literal] [literal]
@ -503,6 +510,7 @@ the wildcards.
[[resources-app-ctx-portability]] [[resources-app-ctx-portability]]
===== Implications on portability ===== Implications on portability
If the specified path is already a file URL (either explicitly, or implicitly because If the specified path is already a file URL (either explicitly, or implicitly because
the base `ResourceLoader` is a filesystem one, then wildcarding is guaranteed to work in the base `ResourceLoader` is a filesystem one, then wildcarding is guaranteed to work in
a completely portable fashion. a completely portable fashion.
@ -525,7 +533,7 @@ environment before you rely on it.
[[resources-classpath-wildcards]] [[resources-classpath-wildcards]]
==== The Classpath*: portability classpath*: prefix ==== The classpath*: prefix
When constructing an XML-based application context, a location string may use the When constructing an XML-based application context, a location string may use the
special `classpath*:` prefix: special `classpath*:` prefix:
@ -565,6 +573,7 @@ strategy described above is used for the wildcard subpath.
[[resources-wildcards-in-path-other-stuff]] [[resources-wildcards-in-path-other-stuff]]
==== Other notes relating to wildcards ==== Other notes relating to wildcards
Please note that `classpath*:` when combined with Ant-style patterns will only work Please note that `classpath*:` when combined with Ant-style patterns will only work
reliably with at least one root directory before the pattern starts, unless the actual reliably with at least one root directory before the pattern starts, unless the actual
target files reside in the file system. This means that a pattern like target files reside in the file system. This means that a pattern like
@ -681,4 +690,3 @@ just force the use of a `UrlResource`, by using the `file:` URL prefix.
ApplicationContext ctx = ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml"); new FileSystemXmlApplicationContext("file:///conf/context.xml");
---- ----

View File

@ -2,6 +2,8 @@
= Validation, Data Binding, and Type Conversion = Validation, Data Binding, and Type Conversion
[[validation-introduction]] [[validation-introduction]]
== Introduction == Introduction
@ -169,6 +171,7 @@ methods it offers can be found in the javadocs.
[[validation-conversion]] [[validation-conversion]]
== Resolving codes to error messages == Resolving codes to error messages
We've talked about databinding and validation. Outputting messages corresponding to We've talked about databinding and validation. Outputting messages corresponding to
validation errors is the last thing we need to discuss. In the example we've shown validation errors is the last thing we need to discuss. In the example we've shown
above, we rejected the `name` and the `age` field. If we're going to output the error above, we rejected the `name` and the `age` field. If we're going to output the error
@ -225,6 +228,7 @@ perform actions on that bean, like setting and retrieving properties.
[[beans-beans-conventions]] [[beans-beans-conventions]]
=== Setting and getting basic and nested properties === Setting and getting basic and nested properties
Setting and getting properties is done using the `setPropertyValue(s)` and Setting and getting properties is done using the `setPropertyValue(s)` and
`getPropertyValue(s)` methods that both come with a couple of overloaded variants. `getPropertyValue(s)` methods that both come with a couple of overloaded variants.
They're all described in more detail in the javadocs Spring comes with. What's important They're all described in more detail in the javadocs Spring comes with. What's important
@ -698,6 +702,7 @@ registration code to be encapsulated in a class and then shared amongst as many
[[core-convert]] [[core-convert]]
== Spring Type Conversion == Spring Type Conversion
Spring 3 introduces a `core.convert` package that provides a general type conversion Spring 3 introduces a `core.convert` package that provides a general type conversion
system. The system defines an SPI to implement type conversion logic, as well as an API system. The system defines an SPI to implement type conversion logic, as well as an API
to execute type conversions at runtime. Within a Spring container, this system can be to execute type conversions at runtime. Within a Spring container, this system can be
@ -709,6 +714,7 @@ application where type conversion is needed.
[[core-convert-Converter-API]] [[core-convert-Converter-API]]
=== Converter SPI === Converter SPI
The SPI to implement type conversion logic is simple and strongly typed: The SPI to implement type conversion logic is simple and strongly typed:
[source,java,indent=0] [source,java,indent=0]
@ -756,6 +762,7 @@ Consider `StringToInteger` as an example for a typical `Converter` implementatio
[[core-convert-ConverterFactory-SPI]] [[core-convert-ConverterFactory-SPI]]
=== ConverterFactory === ConverterFactory
When you need to centralize the conversion logic for an entire class hierarchy, for When you need to centralize the conversion logic for an entire class hierarchy, for
example, when converting from String to java.lang.Enum objects, implement example, when converting from String to java.lang.Enum objects, implement
`ConverterFactory`: `ConverterFactory`:
@ -808,6 +815,7 @@ Consider the `StringToEnum` ConverterFactory as an example:
[[core-convert-GenericConverter-SPI]] [[core-convert-GenericConverter-SPI]]
=== GenericConverter === GenericConverter
When you require a sophisticated Converter implementation, consider the GenericConverter When you require a sophisticated Converter implementation, consider the GenericConverter
interface. With a more flexible but less strongly typed signature, a GenericConverter interface. With a more flexible but less strongly typed signature, a GenericConverter
supports converting between multiple source and target types. In addition, a supports converting between multiple source and target types. In addition, a
@ -850,6 +858,7 @@ Favor Converter or ConverterFactory for basic type conversion needs.
[[core-convert-ConditionalGenericConverter-SPI]] [[core-convert-ConditionalGenericConverter-SPI]]
==== ConditionalGenericConverter ==== ConditionalGenericConverter
Sometimes you only want a `Converter` to execute if a specific condition holds true. For Sometimes you only want a `Converter` to execute if a specific condition holds true. For
example, you might only want to execute a `Converter` if a specific annotation is present example, you might only want to execute a `Converter` if a specific annotation is present
on the target field. Or you might only want to execute a `Converter` if a specific method, on the target field. Or you might only want to execute a `Converter` if a specific method,
@ -882,6 +891,7 @@ might only match if the target entity type declares a static finder method e.g.
[[core-convert-ConversionService-API]] [[core-convert-ConversionService-API]]
=== ConversionService API === ConversionService API
The ConversionService defines a unified API for executing type conversion logic at The ConversionService defines a unified API for executing type conversion logic at
runtime. Converters are often executed behind this facade interface: runtime. Converters are often executed behind this facade interface:
@ -916,6 +926,7 @@ creating common ConversionService configurations.
[[core-convert-Spring-config]] [[core-convert-Spring-config]]
=== Configuring a ConversionService === Configuring a ConversionService
A ConversionService is a stateless object designed to be instantiated at application A ConversionService is a stateless object designed to be instantiated at application
startup, then shared between multiple threads. In a Spring application, you typically startup, then shared between multiple threads. In a Spring application, you typically
configure a ConversionService instance per Spring container (or ApplicationContext). configure a ConversionService instance per Spring container (or ApplicationContext).
@ -968,6 +979,7 @@ In certain situations you may wish to apply formatting during conversion. See
[[core-convert-programmatic-usage]] [[core-convert-programmatic-usage]]
=== Using a ConversionService programmatically === Using a ConversionService programmatically
To work with a ConversionService instance programmatically, simply inject a reference to To work with a ConversionService instance programmatically, simply inject a reference to
it like you would for any other bean: it like you would for any other bean:
@ -1021,6 +1033,7 @@ no need to create a specific converter to convert from a `Collection` of `S` to
[[format]] [[format]]
== Spring Field Formatting == Spring Field Formatting
As discussed in the previous section, <<core-convert, `core.convert`>> is a As discussed in the previous section, <<core-convert, `core.convert`>> is a
general-purpose type conversion system. It provides a unified ConversionService API as general-purpose type conversion system. It provides a unified ConversionService API as
well as a strongly-typed Converter SPI for implementing conversion logic from one type well as a strongly-typed Converter SPI for implementing conversion logic from one type
@ -1048,6 +1061,7 @@ ConversionService provides a unified type conversion API for both SPIs.
[[format-Formatter-SPI]] [[format-Formatter-SPI]]
=== Formatter SPI === Formatter SPI
The Formatter SPI to implement field formatting logic is simple and strongly typed: The Formatter SPI to implement field formatting logic is simple and strongly typed:
[source,java,indent=0] [source,java,indent=0]
@ -1139,6 +1153,7 @@ https://jira.spring.io/browse/SPR[jira.spring.io] to contribute.
[[format-CustomFormatAnnotations]] [[format-CustomFormatAnnotations]]
=== Annotation-driven Formatting === Annotation-driven Formatting
As you will see, field formatting can be configured by field type or annotation. To bind As you will see, field formatting can be configured by field type or annotation. To bind
an Annotation to a formatter, implement AnnotationFormatterFactory: an Annotation to a formatter, implement AnnotationFormatterFactory:
@ -1222,6 +1237,7 @@ To trigger formatting, simply annotate fields with @NumberFormat:
[[format-annotations-api]] [[format-annotations-api]]
==== Format Annotation API ==== Format Annotation API
A portable format annotation API exists in the `org.springframework.format.annotation` A portable format annotation API exists in the `org.springframework.format.annotation`
package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to
format java.util.Date, java.util.Calendar, java.util.Long, or Joda Time fields. format java.util.Date, java.util.Calendar, java.util.Long, or Joda Time fields.
@ -1244,6 +1260,7 @@ The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date
[[format-FormatterRegistry-SPI]] [[format-FormatterRegistry-SPI]]
=== FormatterRegistry SPI === FormatterRegistry SPI
The FormatterRegistry is an SPI for registering formatters and converters. The FormatterRegistry is an SPI for registering formatters and converters.
`FormattingConversionService` is an implementation of FormatterRegistry suitable for `FormattingConversionService` is an implementation of FormatterRegistry suitable for
most environments. This implementation may be configured programmatically or most environments. This implementation may be configured programmatically or
@ -1283,6 +1300,7 @@ these rules once and they are applied whenever formatting is needed.
[[format-FormatterRegistrar-SPI]] [[format-FormatterRegistrar-SPI]]
=== FormatterRegistrar SPI === FormatterRegistrar SPI
The FormatterRegistrar is an SPI for registering formatters and converters through the The FormatterRegistrar is an SPI for registering formatters and converters through the
FormatterRegistry: FormatterRegistry:
@ -1317,6 +1335,7 @@ See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> in the Spring
[[format-configuring-formatting-globaldatetimeformat]] [[format-configuring-formatting-globaldatetimeformat]]
== Configuring a global date & time format == Configuring a global date & time format
By default, date and time fields that are not annotated with `@DateTimeFormat` are By default, date and time fields that are not annotated with `@DateTimeFormat` are
converted from strings using the `DateFormat.SHORT` style. If you prefer, you can converted from strings using the `DateFormat.SHORT` style. If you prefer, you can
change this by defining your own global format. change this by defining your own global format.
@ -1411,6 +1430,7 @@ See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> for details.
[[validation-beanvalidation]] [[validation-beanvalidation]]
== Spring Validation == Spring Validation
Spring 3 introduces several enhancements to its validation support. First, the JSR-303 Spring 3 introduces several enhancements to its validation support. First, the JSR-303
Bean Validation API is now fully supported. Second, when used programmatically, Spring's Bean Validation API is now fully supported. Second, when used programmatically, Spring's
DataBinder can now validate objects as well as bind to them. Third, Spring MVC now has DataBinder can now validate objects as well as bind to them. Third, Spring MVC now has
@ -1420,6 +1440,7 @@ support for declaratively validating `@Controller` inputs.
[[validation-beanvalidation-overview]] [[validation-beanvalidation-overview]]
=== Overview of the JSR-303 Bean Validation API === Overview of the JSR-303 Bean Validation API
JSR-303 standardizes validation constraint declaration and metadata for the Java JSR-303 standardizes validation constraint declaration and metadata for the Java
platform. Using this API, you annotate domain model properties with declarative platform. Using this API, you annotate domain model properties with declarative
validation constraints and the runtime enforces them. There are a number of built-in validation constraints and the runtime enforces them. There are a number of built-in
@ -1466,6 +1487,7 @@ bean, keep reading.
[[validation-beanvalidation-spring]] [[validation-beanvalidation-spring]]
=== Configuring a Bean Validation Provider === Configuring a Bean Validation Provider
Spring provides full support for the Bean Validation API. This includes convenient Spring provides full support for the Bean Validation API. This includes convenient
support for bootstrapping a JSR-303/JSR-349 Bean Validation provider as a Spring bean. support for bootstrapping a JSR-303/JSR-349 Bean Validation provider as a Spring bean.
This allows for a `javax.validation.ValidatorFactory` or `javax.validation.Validator` to This allows for a `javax.validation.ValidatorFactory` or `javax.validation.Validator` to
@ -1487,6 +1509,7 @@ is expected to be present in the classpath and will be detected automatically.
[[validation-beanvalidation-spring-inject]] [[validation-beanvalidation-spring-inject]]
==== Injecting a Validator ==== Injecting a Validator
`LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and `LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and
`javax.validation.Validator`, as well as Spring's `javax.validation.Validator`, as well as Spring's
`org.springframework.validation.Validator`. You may inject a reference to either of `org.springframework.validation.Validator`. You may inject a reference to either of
@ -1527,6 +1550,7 @@ the Spring Validation API:
[[validation-beanvalidation-spring-constraints]] [[validation-beanvalidation-spring-constraints]]
==== Configuring Custom Constraints ==== Configuring Custom Constraints
Each Bean Validation constraint consists of two parts. First, a `@Constraint` annotation Each Bean Validation constraint consists of two parts. First, a `@Constraint` annotation
that declares the constraint and its configurable properties. Second, an implementation that declares the constraint and its configurable properties. Second, an implementation
of the `javax.validation.ConstraintValidator` interface that implements the constraint's of the `javax.validation.ConstraintValidator` interface that implements the constraint's
@ -1572,6 +1596,7 @@ As you can see, a ConstraintValidator implementation may have its dependencies
[[validation-beanvalidation-spring-method]] [[validation-beanvalidation-spring-method]]
==== Spring-driven Method Validation ==== Spring-driven Method Validation
The method validation feature supported by Bean Validation 1.1, and as a custom The method validation feature supported by Bean Validation 1.1, and as a custom
extension also by Hibernate Validator 4.3, can be integrated into a Spring context extension also by Hibernate Validator 4.3, can be integrated into a Spring context
through a `MethodValidationPostProcessor` bean definition: through a `MethodValidationPostProcessor` bean definition:
@ -1590,6 +1615,7 @@ for setup details with Hibernate Validator and Bean Validation 1.1 providers.
[[validation-beanvalidation-spring-other]] [[validation-beanvalidation-spring-other]]
==== Additional Configuration Options ==== Additional Configuration Options
The default `LocalValidatorFactoryBean` configuration should prove sufficient for most The default `LocalValidatorFactoryBean` configuration should prove sufficient for most
cases. There are a number of configuration options for various Bean Validation cases. There are a number of configuration options for various Bean Validation
constructs, from message interpolation to traversal resolution. See the constructs, from message interpolation to traversal resolution. See the
@ -1599,6 +1625,7 @@ constructs, from message interpolation to traversal resolution. See the
[[validation-binder]] [[validation-binder]]
=== Configuring a DataBinder === Configuring a DataBinder
Since Spring 3, a DataBinder instance can be configured with a Validator. Once Since Spring 3, a DataBinder instance can be configured with a Validator. Once
configured, the Validator may be invoked by calling `binder.validate()`. Any validation configured, the Validator may be invoked by calling `binder.validate()`. Any validation
Errors are automatically added to the binder's BindingResult. Errors are automatically added to the binder's BindingResult.
@ -1634,4 +1661,3 @@ locally on a DataBinder instance. See <<validation-mvc-configuring>>.
=== Spring MVC 3 Validation === Spring MVC 3 Validation
See <<web.adoc#mvc-config-validation, Validation>> in the Spring MVC chapter. See <<web.adoc#mvc-config-validation, Validation>> in the Spring MVC chapter.

View File

@ -1,11 +1,14 @@
= Appendix = Appendix
[[xsd-schemas]] [[xsd-schemas]]
== XML Schemas == XML Schemas
This part of the appendix lists XML schemas for data access. This part of the appendix lists XML schemas for data access.
[[xsd-schemas-tx]] [[xsd-schemas-tx]]
=== The `tx` schema === The `tx` schema

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,15 @@
= Appendix = Appendix
[[xsd-schemas]] [[xsd-schemas]]
== XML Schemas == XML Schemas
This part of the appendix lists XML schemas related to integration technologies. This part of the appendix lists XML schemas related to integration technologies.
[[xsd-schemas-jee]] [[xsd-schemas-jee]]
=== The jee schema === The jee schema

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,9 @@
:toclevels: 4 :toclevels: 4
:docinfo1: :docinfo1:
[[introduction]] [[introduction]]
== Introduction == Introduction
@ -17,8 +20,11 @@ existing libraries written in Java.
Spring Framework 5 introduces first-class support for Kotlin and allows developers to write Spring Framework 5 introduces first-class support for Kotlin and allows developers to write
Spring + Kotlin applications almost as if the Spring Framework was a native Kotlin framework. Spring + Kotlin applications almost as if the Spring Framework was a native Kotlin framework.
[[requirements]] [[requirements]]
== Requirements == == Requirements
Spring Framework supports Kotlin 1.1+ and requires Spring Framework supports Kotlin 1.1+ and requires
https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`] https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`]
@ -28,6 +34,9 @@ and https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-reflect[`k
to be present on the classpath. They are provided by default if one bootstraps a Kotlin project on to be present on the classpath. They are provided by default if one bootstraps a Kotlin project on
https://start.spring.io/#!language=kotlin[start.spring.io]. https://start.spring.io/#!language=kotlin[start.spring.io].
[[extensions]] [[extensions]]
== Extensions == Extensions
@ -77,6 +86,9 @@ val users : Flux<User> = client.get().retrieve().bodyToFlux()
As in Java, `users` in Kotlin is strongly typed, but Kotlin's clever type inference allows As in Java, `users` in Kotlin is strongly typed, but Kotlin's clever type inference allows
for shorter syntax. for shorter syntax.
[[null-safety]] [[null-safety]]
== Null-safety == Null-safety
@ -117,6 +129,9 @@ but should be in an upcoming release, see https://github.com/Kotlin/KEEP/issues/
for up-to-date information. for up-to-date information.
==== ====
[[classes-interfaces]] [[classes-interfaces]]
== Classes & Interfaces == Classes & Interfaces
@ -138,6 +153,9 @@ detected without the Jackson Kotlin module present.
As of Spring Boot 2.0, Jackson Kotlin module is automatically provided via the JSON starter. As of Spring Boot 2.0, Jackson Kotlin module is automatically provided via the JSON starter.
==== ====
[[annotations]] [[annotations]]
== Annotations == Annotations
@ -152,6 +170,9 @@ to determine if a bean is required or not. `@Autowired lateinit var foo: Foo` im
of type `Foo` must be registered in the application context while `@Autowired lateinit var foo: Foo?` of type `Foo` must be registered in the application context while `@Autowired lateinit var foo: Foo?`
wont raise an error if such bean does not exist. wont raise an error if such bean does not exist.
[[bean-definition-dsl]] [[bean-definition-dsl]]
== Bean definition DSL == Bean definition DSL
@ -251,9 +272,14 @@ see https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-defi
for more details and up-to-date information. for more details and up-to-date information.
==== ====
[[web]] [[web]]
== Web == Web
=== WebFlux Functional DSL === WebFlux Functional DSL
Spring Framework now comes with a Spring Framework now comes with a
@ -291,6 +317,8 @@ depending on dynamic data (for example, from a database).
See https://github.com/mixitconf/mixit/tree/bad6b92bce6193f9b3f696af9d416c276501dbf1/src/main/kotlin/mixit/web/routes[MiXiT project routes] See https://github.com/mixitconf/mixit/tree/bad6b92bce6193f9b3f696af9d416c276501dbf1/src/main/kotlin/mixit/web/routes[MiXiT project routes]
for a concrete example. for a concrete example.
=== Kotlin Script templates === Kotlin Script templates
As of version 4.3, Spring Framework provides a As of version 4.3, Spring Framework provides a
@ -326,12 +354,17 @@ ${include("footer")}
See https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example See https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example
project for more details. project for more details.
[[spring-projects-in-kotlin]] [[spring-projects-in-kotlin]]
== Spring projects in Kotlin == Spring projects in Kotlin
This section provides focus on some specific hints and recommendations worth This section provides focus on some specific hints and recommendations worth
knowing when developing Spring projects in Kotlin. knowing when developing Spring projects in Kotlin.
=== Final by default === Final by default
By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`]. By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`].
@ -365,6 +398,8 @@ annotations are meta-annotated with `@Component`.
http://start.spring.io/#!language=kotlin[start.spring.io] enables it by default, so in practice http://start.spring.io/#!language=kotlin[start.spring.io] enables it by default, so in practice
you will be able to write your Kotlin beans without any additional `open` keyword, like in Java. you will be able to write your Kotlin beans without any additional `open` keyword, like in Java.
=== Using immutable class instances for persistence === Using immutable class instances for persistence
In Kotlin, it is very convenient and considered best practice to declare In Kotlin, it is very convenient and considered best practice to declare
@ -414,6 +449,8 @@ and should not require `kotlin-noarg` plugin if the module leverages Spring Data
mapping (like with MongoDB, Redis, Cassandra, etc.). mapping (like with MongoDB, Redis, Cassandra, etc.).
==== ====
=== Injecting dependencies === Injecting dependencies
Our recommendation is to try and favor constructor injection with `val` read-only (and non-nullable when possible) Our recommendation is to try and favor constructor injection with `val` read-only (and non-nullable when possible)
@ -451,6 +488,8 @@ class YourBean {
} }
---- ----
=== Injecting configuration properties === Injecting configuration properties
In Java, one can inject configuration properties using annotations like `@Value("${property}")`, In Java, one can inject configuration properties using annotations like `@Value("${property}")`,
@ -498,6 +537,8 @@ and https://github.com/spring-projects/spring-boot/issues/1254[`@ConfigurationPr
for more details. for more details.
==== ====
=== Annotation array attributes === Annotation array attributes
Kotlin annotations are mostly similar to Java ones, but array attributes - which are Kotlin annotations are mostly similar to Java ones, but array attributes - which are
@ -548,8 +589,11 @@ not only the `GET` methods.
Improving the syntax and consistency of Kotlin annotation array attributes is discussed in Improving the syntax and consistency of Kotlin annotation array attributes is discussed in
https://youtrack.jetbrains.com/issue/KT-11235[this Kotlin language design issue]. https://youtrack.jetbrains.com/issue/KT-11235[this Kotlin language design issue].
=== Testing === Testing
==== Per class lifecycle ==== Per class lifecycle
Kotlin allows one to specify meaningful test function names between backticks, Kotlin allows one to specify meaningful test function names between backticks,
@ -591,6 +635,7 @@ class IntegrationTests {
} }
---- ----
==== Specification-like tests ==== Specification-like tests
It is possible to create specification-like tests with JUnit 5 and Kotlin. It is possible to create specification-like tests with JUnit 5 and Kotlin.
@ -620,9 +665,13 @@ class SpecificationLikeTests {
---- ----
[[getting-started]] [[getting-started]]
== Getting started == Getting started
=== start.spring.io === start.spring.io
The easiest way to start a new Spring Framework 5 project in Kotlin is to create a new Spring The easiest way to start a new Spring Framework 5 project in Kotlin is to create a new Spring
@ -631,6 +680,8 @@ Boot 2 project on https://start.spring.io/#!language=kotlin[start.spring.io].
It is also possible to create a standalone WebFlux project as described in It is also possible to create a standalone WebFlux project as described in
https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[this blog post]. https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[this blog post].
=== Choosing the web flavor === Choosing the web flavor
Spring Framework now comes with 2 different web stacks: <<web#mvc,Spring MVC>> and Spring Framework now comes with 2 different web stacks: <<web#mvc,Spring MVC>> and
@ -643,6 +694,9 @@ Kotlin DSL.
For other use cases, especially if you are using blocking technologies like JPA, Spring For other use cases, especially if you are using blocking technologies like JPA, Spring
MVC and its annotation-based programming model is a perfectly valid and fully supported choice. MVC and its annotation-based programming model is a perfectly valid and fully supported choice.
[[resources-started]] [[resources-started]]
== Resources == Resources
@ -652,6 +706,8 @@ MVC and its annotation-based programming model is a perfectly valid and fully su
* https://blog.jetbrains.com/kotlin/[Kotlin blog] * https://blog.jetbrains.com/kotlin/[Kotlin blog]
* https://kotlin.link/[Awesome Kotlin] * https://kotlin.link/[Awesome Kotlin]
=== Blog posts === Blog posts
* https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin] * https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin]
@ -659,6 +715,8 @@ MVC and its annotation-based programming model is a perfectly valid and fully su
* https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0] * https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0]
* https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way] * https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way]
=== Examples === Examples
* https://github.com/sdeleuze/spring-boot-kotlin-demo[spring-boot-kotlin-demo]: regular Spring Boot + Spring Data JPA project * https://github.com/sdeleuze/spring-boot-kotlin-demo[spring-boot-kotlin-demo]: regular Spring Boot + Spring Data JPA project
@ -667,18 +725,24 @@ MVC and its annotation-based programming model is a perfectly valid and fully su
* https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript * https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript
* https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application * https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application
=== Tutorials === Tutorials
* https://kotlinlang.org/docs/tutorials/spring-boot-restful.html[Creating a RESTful Web Service with Spring Boot] * https://kotlinlang.org/docs/tutorials/spring-boot-restful.html[Creating a RESTful Web Service with Spring Boot]
=== Issues === Issues
Here is a list of pending issues related to Spring + Kotlin support. Here is a list of pending issues related to Spring + Kotlin support.
==== Spring Framework ==== Spring Framework
* https://jira.spring.io/browse/SPR-15413[Add support for Kotlin coroutines] * https://jira.spring.io/browse/SPR-15413[Add support for Kotlin coroutines]
==== Spring Boot ==== Spring Boot
* https://github.com/spring-projects/spring-boot/issues/5537[Improve Kotlin support] * https://github.com/spring-projects/spring-boot/issues/5537[Improve Kotlin support]
@ -687,6 +751,7 @@ Here is a list of pending issues related to Spring + Kotlin support.
* https://github.com/spring-projects/spring-boot/issues/8511[Provide support for Kotlin KClass parameter in `SpringApplication.run()`] * https://github.com/spring-projects/spring-boot/issues/8511[Provide support for Kotlin KClass parameter in `SpringApplication.run()`]
* https://github.com/spring-projects/spring-boot/issues/8115[Expose the functional bean registration API via `SpringApplication`] * https://github.com/spring-projects/spring-boot/issues/8115[Expose the functional bean registration API via `SpringApplication`]
==== Kotlin ==== Kotlin
* https://github.com/Kotlin/KEEP/issues/79[Better generics null-safety support] * https://github.com/Kotlin/KEEP/issues/79[Better generics null-safety support]

View File

@ -21,6 +21,9 @@ Spring is open source. It has a large and active community that provides continu
based on a diverse range of real-world use cases. This has helped Spring to successfully based on a diverse range of real-world use cases. This has helped Spring to successfully
evolve over a very long time. evolve over a very long time.
[[overview-spring]] [[overview-spring]]
== What We Mean by "Spring" == What We Mean by "Spring"
@ -44,6 +47,9 @@ A note about modules: Spring's framework jars allow for deployment to JDK 9's mo
the same naming pattern with "-" instead of ".", e.g. "spring-core" and "spring-context"). 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.
[[overview-history]] [[overview-history]]
== History of Spring and the Spring Framework == History of Spring and the Spring Framework
@ -85,6 +91,9 @@ among others. Its important to remember that each project has its own source
issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for
the complete list of Spring projects. the complete list of Spring projects.
[[overview-philosophy]] [[overview-philosophy]]
== Design Philosophy == Design Philosophy
@ -108,6 +117,9 @@ that are intuitive and that hold up across many versions and many years.
meaningful, current, and accurate Javadoc. It is one of very few projects that can claim meaningful, current, and accurate Javadoc. It is one of very few projects that can claim
clean code structure with no circular dependencies between packages. clean code structure with no circular dependencies between packages.
[[overview-feedback]] [[overview-feedback]]
== Feedback and Contributions == Feedback and Contributions
@ -128,6 +140,9 @@ information that is not specific to any one version. For example, it has migrati
notes from earlier versions, comprehensive information on what's new across multiple notes from earlier versions, comprehensive information on what's new across multiple
versions, contributor guidelines, the Spring Framework code style, and other information. versions, contributor guidelines, the Spring Framework code style, and other information.
[[overview-getting-started]] [[overview-getting-started]]
== Getting Started == Getting Started

View File

@ -10,6 +10,7 @@ without the need for an HTTP server.
[[webtestclient-setup]] [[webtestclient-setup]]
== Setup == Setup
@ -18,6 +19,7 @@ Effectively you either configure a WebFlux application to bind to, or use absolu
to connect to a running server. to connect to a running server.
[[webtestclient-controller-config]] [[webtestclient-controller-config]]
=== Bind to controller === Bind to controller
@ -35,6 +37,7 @@ without an HTTP server using mock request and response objects. There are more m
on the builder to customize the default WebFlux Java config. on the builder to customize the default WebFlux Java config.
[[webtestclient-fn-config]] [[webtestclient-fn-config]]
=== Bind to RouterFunction === Bind to RouterFunction
@ -53,6 +56,7 @@ The resulting WebFlux application will be tested without an HTTP server using mo
request and response objects. request and response objects.
[[webtestclient-context-config]] [[webtestclient-context-config]]
=== Bind to ApplicationContext === Bind to ApplicationContext
@ -90,6 +94,7 @@ resulting WebFlux application will be tested without an HTTP server using mock r
and response objects. and response objects.
[[webtestclient-server-config]] [[webtestclient-server-config]]
=== Bind to server === Bind to server
@ -284,6 +289,3 @@ from the `reactor-test` module to do that, for example:
.thenCancel() .thenCancel()
.verify(); .verify();
---- ----

View File

@ -17,8 +17,11 @@ set up service locator registries and suchlike)... the chapter dedicated solely
testing will hopefully convince you of this as well. testing will hopefully convince you of this as well.
[[testing-introduction]] [[testing-introduction]]
== Introduction to Spring Testing == Introduction to Spring Testing
Testing is an integral part of enterprise software development. This chapter focuses on Testing is an integral part of enterprise software development. This chapter focuses on
the value-add of the IoC principle to <<unit-testing,unit testing>> and on the benefits the value-add of the IoC principle to <<unit-testing,unit testing>> and on the benefits
of the Spring Framework's support for <<integration-testing,integration testing>>. __(A of the Spring Framework's support for <<integration-testing,integration testing>>. __(A
@ -26,8 +29,11 @@ thorough treatment of testing in the enterprise is beyond the scope of this refe
manual.)__ manual.)__
[[unit-testing]] [[unit-testing]]
== Unit Testing == Unit Testing
Dependency Injection should make your code less dependent on the container than it would 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 with traditional Java EE development. The POJOs that make up your application should
be testable in JUnit or TestNG tests, with objects simply instantiated using the `new` be testable in JUnit or TestNG tests, with objects simply instantiated using the `new`
@ -54,6 +60,7 @@ support classes.
[[mock-objects-env]] [[mock-objects-env]]
==== Environment ==== Environment
The `org.springframework.mock.env` package contains mock implementations of the The `org.springframework.mock.env` package contains mock implementations of the
`Environment` and `PropertySource` abstractions (see `Environment` and `PropertySource` abstractions (see
<<core.adoc#beans-definition-profiles, Bean definition profiles>> <<core.adoc#beans-definition-profiles, Bean definition profiles>>
@ -64,6 +71,7 @@ __out-of-container__ tests for code that depends on environment-specific propert
[[mock-objects-jndi]] [[mock-objects-jndi]]
==== JNDI ==== JNDI
The `org.springframework.mock.jndi` package contains an implementation of the JNDI SPI, The `org.springframework.mock.jndi` package contains an implementation of the JNDI SPI,
which you can use to set up a simple JNDI environment for test suites or stand-alone which you can use to set up a simple JNDI environment for test suites or stand-alone
applications. If, for example, JDBC ``DataSource``s get bound to the same JNDI names in applications. If, for example, JDBC ``DataSource``s get bound to the same JNDI names in
@ -73,6 +81,7 @@ configuration in testing scenarios without modification.
[[mock-objects-servlet]] [[mock-objects-servlet]]
==== Servlet API ==== Servlet API
The `org.springframework.mock.web` package contains a comprehensive set of Servlet API The `org.springframework.mock.web` package contains a comprehensive set of Servlet API
mock objects that are useful for testing web contexts, controllers, and filters. These mock objects that are useful for testing web contexts, controllers, and filters. These
mock objects are targeted at usage with Spring's Web MVC framework and are generally more mock objects are targeted at usage with Spring's Web MVC framework and are generally more
@ -92,6 +101,7 @@ integration testing framework for Spring MVC. See
[[mock-objects-web-reactive]] [[mock-objects-web-reactive]]
==== Spring Web Reactive ==== Spring Web Reactive
The package `org.springframework.mock.http.server.reactive` contains mock The package `org.springframework.mock.http.server.reactive` contains mock
implementations of `ServerHttpRequest` and `ServerHttpResponse` for use in WebFlux implementations of `ServerHttpRequest` and `ServerHttpResponse` for use in WebFlux
applications. The package `org.springframework.mock.web.server` applications. The package `org.springframework.mock.web.server`
@ -114,12 +124,14 @@ testing WebFlux applications without an HTTP server. The client can also be used
end-to-end tests with a running server. end-to-end tests with a running server.
[[unit-testing-support-classes]] [[unit-testing-support-classes]]
=== Unit Testing support Classes === Unit Testing support Classes
[[unit-testing-utilities]] [[unit-testing-utilities]]
==== General testing utilities ==== General testing utilities
The `org.springframework.test.util` package contains several general purpose utilities The `org.springframework.test.util` package contains several general purpose utilities
for use in unit and integration testing. for use in unit and integration testing.
@ -145,9 +157,9 @@ access to the underlying mock in order to configure expectations on it and perfo
verifications. For Spring's core AOP utilities, see `AopUtils` and `AopProxyUtils`. verifications. For Spring's core AOP utilities, see `AopUtils` and `AopProxyUtils`.
[[unit-testing-spring-mvc]] [[unit-testing-spring-mvc]]
==== Spring MVC ==== Spring MVC
The `org.springframework.test.web` package contains `ModelAndViewAssert`, which you can The `org.springframework.test.web` package contains `ModelAndViewAssert`, which you can
use in combination with JUnit, TestNG, or any other testing framework for unit tests use in combination with JUnit, TestNG, or any other testing framework for unit tests
dealing with Spring MVC `ModelAndView` objects. dealing with Spring MVC `ModelAndView` objects.
@ -173,6 +185,7 @@ Framework_>> instead.
[[integration-testing-overview]] [[integration-testing-overview]]
=== Overview === Overview
It is important to be able to perform some integration testing without requiring It is important to be able to perform some integration testing without requiring
deployment to your application server or connecting to other enterprise infrastructure. deployment to your application server or connecting to other enterprise infrastructure.
This will enable you to test things such as: This will enable you to test things such as:
@ -200,6 +213,7 @@ instrumentation of tests in various environments including JUnit, TestNG, and so
[[integration-testing-goals]] [[integration-testing-goals]]
=== Goals of Integration Testing === Goals of Integration Testing
Spring's integration testing support has the following primary goals: Spring's integration testing support has the following primary goals:
* To manage <<testing-ctx-management,Spring IoC container caching>> between test * To manage <<testing-ctx-management,Spring IoC container caching>> between test
@ -215,6 +229,7 @@ configuration details.
[[testing-ctx-management]] [[testing-ctx-management]]
==== Context management and caching ==== Context management and caching
The Spring TestContext Framework provides consistent loading of Spring The Spring TestContext Framework provides consistent loading of Spring
``ApplicationContext``s and ``WebApplicationContext``s as well as caching of those ``ApplicationContext``s and ``WebApplicationContext``s as well as caching of those
contexts. Support for the caching of loaded contexts is important, because startup time contexts. Support for the caching of loaded contexts is important, because startup time
@ -245,6 +260,7 @@ TestContext framework.
[[testing-fixture-di]] [[testing-fixture-di]]
==== Dependency Injection of test fixtures ==== Dependency Injection of test fixtures
When the TestContext framework loads your application context, it can optionally When the TestContext framework loads your application context, it can optionally
configure instances of your test classes via Dependency Injection. This provides a configure instances of your test classes via Dependency Injection. This provides a
convenient mechanism for setting up test fixtures using preconfigured beans from your convenient mechanism for setting up test fixtures using preconfigured beans from your
@ -270,6 +286,7 @@ framework>>.
[[testing-tx]] [[testing-tx]]
==== Transaction management ==== Transaction management
One common issue in tests that access a real database is their effect on the state of One common issue in tests that access a real database is their effect on the state of
the persistence store. Even when you're using a development database, changes to the the persistence store. Even when you're using a development database, changes to the
state may affect future tests. Also, many operations -- such as inserting or modifying state may affect future tests. Also, many operations -- such as inserting or modifying
@ -295,6 +312,7 @@ See transaction management with the <<testcontext-tx,TestContext framework>>.
[[testing-support-classes]] [[testing-support-classes]]
==== Support classes for integration testing ==== Support classes for integration testing
The Spring TestContext Framework provides several `abstract` support classes that The Spring TestContext Framework provides several `abstract` support classes that
simplify the writing of integration tests. These base test classes provide well-defined simplify the writing of integration tests. These base test classes provide well-defined
hooks into the testing framework as well as convenient instance variables and methods, hooks into the testing framework as well as convenient instance variables and methods,
@ -317,6 +335,7 @@ See support classes for the <<testcontext-support-classes,TestContext framework>
[[integration-testing-support-jdbc]] [[integration-testing-support-jdbc]]
=== JDBC Testing Support === JDBC Testing Support
The `org.springframework.test.jdbc` package contains `JdbcTestUtils`, which is a The `org.springframework.test.jdbc` package contains `JdbcTestUtils`, which is a
collection of JDBC related utility functions intended to simplify standard database collection of JDBC related utility functions intended to simplify standard database
testing scenarios. Specifically, `JdbcTestUtils` provides the following static utility testing scenarios. Specifically, `JdbcTestUtils` provides the following static utility
@ -348,20 +367,24 @@ with an embedded database>>.
=== Annotations === Annotations
[[integration-testing-annotations-spring]] [[integration-testing-annotations-spring]]
==== Spring Testing Annotations ==== Spring Testing Annotations
The Spring Framework provides the following set of __Spring-specific__ annotations that The Spring Framework provides the following set of __Spring-specific__ annotations that
you can use in your unit and integration tests in conjunction with the TestContext you can use in your unit and integration tests in conjunction with the TestContext
framework. Refer to the corresponding javadocs for further information, including framework. Refer to the corresponding javadocs for further information, including
default attribute values, attribute aliases, and so on. default attribute values, attribute aliases, and so on.
===== @BootstrapWith ===== @BootstrapWith
`@BootstrapWith` is a class-level annotation that is used to configure how the _Spring `@BootstrapWith` is a class-level annotation that is used to configure how the _Spring
TestContext Framework_ is bootstrapped. Specifically, `@BootstrapWith` is used to specify TestContext Framework_ is bootstrapped. Specifically, `@BootstrapWith` is used to specify
a custom `TestContextBootstrapper`. Consult the <<testcontext-bootstrapping,Bootstrapping a custom `TestContextBootstrapper`. Consult the <<testcontext-bootstrapping,Bootstrapping
the TestContext framework>> section for further details. the TestContext framework>> section for further details.
===== @ContextConfiguration ===== @ContextConfiguration
`@ContextConfiguration` defines class-level metadata that is used to determine how to `@ContextConfiguration` defines class-level metadata that is used to determine how to
load and configure an `ApplicationContext` for integration tests. Specifically, load and configure an `ApplicationContext` for integration tests. Specifically,
`@ContextConfiguration` declares the application context resource `locations` or the `@ContextConfiguration` declares the application context resource `locations` or the
@ -427,6 +450,7 @@ See <<testcontext-ctx-management>> and the `@ContextConfiguration` javadocs for
further details. further details.
===== @WebAppConfiguration ===== @WebAppConfiguration
`@WebAppConfiguration` is a class-level annotation that is used to declare that the `@WebAppConfiguration` is a class-level annotation that is used to declare that the
`ApplicationContext` loaded for an integration test should be a `WebApplicationContext`. `ApplicationContext` loaded for an integration test should be a `WebApplicationContext`.
The mere presence of `@WebAppConfiguration` on a test class ensures that a The mere presence of `@WebAppConfiguration` on a test class ensures that a
@ -465,6 +489,7 @@ Note that `@WebAppConfiguration` must be used in conjunction with
hierarchy. See the `@WebAppConfiguration` javadocs for further details. hierarchy. See the `@WebAppConfiguration` javadocs for further details.
===== @ContextHierarchy ===== @ContextHierarchy
`@ContextHierarchy` is a class-level annotation that is used to define a hierarchy of `@ContextHierarchy` is a class-level annotation that is used to define a hierarchy of
``ApplicationContext``s for integration tests. `@ContextHierarchy` should be declared ``ApplicationContext``s for integration tests. `@ContextHierarchy` should be declared
with a list of one or more `@ContextConfiguration` instances, each of which defines a with a list of one or more `@ContextConfiguration` instances, each of which defines a
@ -505,6 +530,7 @@ corresponding level in the class hierarchy. See
for further examples. for further examples.
===== @ActiveProfiles ===== @ActiveProfiles
`@ActiveProfiles` is a class-level annotation that is used to declare which __bean `@ActiveProfiles` is a class-level annotation that is used to declare which __bean
definition profiles__ should be active when loading an `ApplicationContext` for an definition profiles__ should be active when loading an `ApplicationContext` for an
integration test. integration test.
@ -542,6 +568,7 @@ See <<testcontext-ctx-management-env-profiles>> and the `@ActiveProfiles` javado
for examples and further details. for examples and further details.
===== @TestPropertySource ===== @TestPropertySource
`@TestPropertySource` is a class-level annotation that is used to configure the locations `@TestPropertySource` is a class-level annotation that is used to configure the locations
of properties files and inlined properties to be added to the set of `PropertySources` in of properties files and inlined properties to be added to the set of `PropertySources` in
the `Environment` for an `ApplicationContext` loaded for an integration test. the `Environment` for an `ApplicationContext` loaded for an integration test.
@ -578,6 +605,7 @@ The following example demonstrates how to declare _inlined_ properties.
---- ----
===== @DirtiesContext ===== @DirtiesContext
`@DirtiesContext` indicates that the underlying Spring `ApplicationContext` has been `@DirtiesContext` indicates that the underlying Spring `ApplicationContext` has been
__dirtied__ during the execution of a test (i.e., modified or corrupted in some manner -- __dirtied__ during the execution of a test (i.e., modified or corrupted in some manner --
for example, by changing the state of a singleton bean) and should be closed. When an for example, by changing the state of a singleton bean) and should be closed. When an
@ -724,6 +752,7 @@ For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms se
`DirtiesContext.HierarchyMode` javadocs. `DirtiesContext.HierarchyMode` javadocs.
===== @TestExecutionListeners ===== @TestExecutionListeners
`@TestExecutionListeners` defines class-level metadata for configuring the `@TestExecutionListeners` defines class-level metadata for configuring the
`TestExecutionListener` implementations that should be registered with the `TestExecutionListener` implementations that should be registered with the
`TestContextManager`. Typically, `@TestExecutionListeners` is used in conjunction with `TestContextManager`. Typically, `@TestExecutionListeners` is used in conjunction with
@ -743,6 +772,7 @@ For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms se
for an example and further details. for an example and further details.
===== @Commit ===== @Commit
`@Commit` indicates that the transaction for a transactional test method should be `@Commit` indicates that the transaction for a transactional test method should be
__committed__ after the test method has completed. `@Commit` can be used as a direct __committed__ after the test method has completed. `@Commit` can be used as a direct
replacement for `@Rollback(false)` in order to more explicitly convey the intent of the replacement for `@Rollback(false)` in order to more explicitly convey the intent of the
@ -760,6 +790,7 @@ method-level annotation.
---- ----
===== @Rollback ===== @Rollback
`@Rollback` indicates whether the transaction for a transactional test method should be `@Rollback` indicates whether the transaction for a transactional test method should be
__rolled back__ after the test method has completed. If `true`, the transaction is rolled __rolled back__ after the test method has completed. If `true`, the transaction is rolled
back; otherwise, the transaction is committed (see also `@Commit`). Rollback semantics back; otherwise, the transaction is committed (see also `@Commit`). Rollback semantics
@ -782,6 +813,7 @@ method, potentially overriding class-level `@Rollback` or `@Commit` semantics.
---- ----
===== @BeforeTransaction ===== @BeforeTransaction
`@BeforeTransaction` indicates that the annotated `void` method should be executed `@BeforeTransaction` indicates that the annotated `void` method should be executed
__before__ a transaction is started for test methods configured to run within a __before__ a transaction is started for test methods configured to run within a
transaction via Spring's `@Transactional` annotation. As of Spring Framework 4.3, transaction via Spring's `@Transactional` annotation. As of Spring Framework 4.3,
@ -798,6 +830,7 @@ transaction via Spring's `@Transactional` annotation. As of Spring Framework 4.3
---- ----
===== @AfterTransaction ===== @AfterTransaction
`@AfterTransaction` indicates that the annotated `void` method should be executed `@AfterTransaction` indicates that the annotated `void` method should be executed
__after__ a transaction is ended for test methods configured to run within a transaction __after__ a transaction is ended for test methods configured to run within a transaction
via Spring's `@Transactional` annotation. As of Spring Framework 4.3, `@AfterTransaction` via Spring's `@Transactional` annotation. As of Spring Framework 4.3, `@AfterTransaction`
@ -814,6 +847,7 @@ default methods.
---- ----
===== @Sql ===== @Sql
`@Sql` is used to annotate a test class or test method to configure SQL scripts to be `@Sql` is used to annotate a test class or test method to configure SQL scripts to be
executed against a given database during integration tests. executed against a given database during integration tests.
@ -830,6 +864,7 @@ executed against a given database during integration tests.
See <<testcontext-executing-sql-declaratively>> for further details. See <<testcontext-executing-sql-declaratively>> for further details.
===== @SqlConfig ===== @SqlConfig
`@SqlConfig` defines metadata that is used to determine how to parse and execute SQL `@SqlConfig` defines metadata that is used to determine how to parse and execute SQL
scripts configured via the `@Sql` annotation. scripts configured via the `@Sql` annotation.
@ -847,6 +882,7 @@ scripts configured via the `@Sql` annotation.
---- ----
===== @SqlGroup ===== @SqlGroup
`@SqlGroup` is a container annotation that aggregates several `@Sql` annotations. `@SqlGroup` is a container annotation that aggregates several `@Sql` annotations.
`@SqlGroup` can be used natively, declaring several nested `@Sql` annotations, or it can `@SqlGroup` can be used natively, declaring several nested `@Sql` annotations, or it can
be used in conjunction with Java 8's support for repeatable annotations, where `@Sql` can be used in conjunction with Java 8's support for repeatable annotations, where `@Sql` can
@ -869,6 +905,7 @@ container annotation.
[[integration-testing-annotations-standard]] [[integration-testing-annotations-standard]]
==== Standard Annotation Support ==== Standard Annotation Support
The following annotations are supported with standard semantics for all configurations The following annotations are supported with standard semantics for all configurations
of the Spring TestContext Framework. Note that these annotations are not specific to of the Spring TestContext Framework. Note that these annotations are not specific to
tests and can be used anywhere in the Spring Framework. tests and can be used anywhere in the Spring Framework.
@ -909,6 +946,7 @@ The following annotations are __only__ supported when used in conjunction with t
4 rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>. 4 rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>.
===== @IfProfileValue ===== @IfProfileValue
`@IfProfileValue` indicates that the annotated test is enabled for a specific testing `@IfProfileValue` indicates that the annotated test is enabled for a specific testing
environment. If the configured `ProfileValueSource` returns a matching `value` for the environment. If the configured `ProfileValueSource` returns a matching `value` for the
provided `name`, the test is enabled. Otherwise, the test will be disabled and provided `name`, the test is enabled. Otherwise, the test will be disabled and
@ -947,6 +985,7 @@ Consider the following example:
---- ----
===== @ProfileValueSourceConfiguration ===== @ProfileValueSourceConfiguration
`@ProfileValueSourceConfiguration` is a class-level annotation that specifies what type `@ProfileValueSourceConfiguration` is a class-level annotation that specifies what type
of `ProfileValueSource` to use when retrieving __profile values__ configured through the of `ProfileValueSource` to use when retrieving __profile values__ configured through the
`@IfProfileValue` annotation. If `@ProfileValueSourceConfiguration` is not declared for a `@IfProfileValue` annotation. If `@ProfileValueSourceConfiguration` is not declared for a
@ -962,6 +1001,7 @@ test, `SystemProfileValueSource` is used by default.
---- ----
===== @Timed ===== @Timed
`@Timed` indicates that the annotated test method must finish execution in a specified `@Timed` indicates that the annotated test method must finish execution in a specified
time period (in milliseconds). If the text execution time exceeds the specified time time period (in milliseconds). If the text execution time exceeds the specified time
period, the test fails. period, the test fails.
@ -986,6 +1026,7 @@ hand, does not preemptively fail the test but rather waits for the test to compl
before failing. before failing.
===== @Repeat ===== @Repeat
`@Repeat` indicates that the annotated test method must be executed repeatedly. The `@Repeat` indicates that the annotated test method must be executed repeatedly. The
number of times that the test method is to be executed is specified in the annotation. number of times that the test method is to be executed is specified in the annotation.
@ -1002,6 +1043,7 @@ well as any __set up__ or __tear down__ of the test fixture.
} }
---- ----
[[integration-testing-annotations-junit-jupiter]] [[integration-testing-annotations-junit-jupiter]]
==== Spring JUnit Jupiter Testing Annotations ==== Spring JUnit Jupiter Testing Annotations
@ -1149,6 +1191,7 @@ public @interface DisabledOnMac {}
[[integration-testing-annotations-meta]] [[integration-testing-annotations-meta]]
==== Meta-Annotation Support for Testing ==== Meta-Annotation Support for Testing
It is possible to use most test-related annotations as It is possible to use most test-related annotations as
<<core.adoc#beans-meta-annotations,meta-annotations>> in order to create custom _composed <<core.adoc#beans-meta-annotations,meta-annotations>> in order to create custom _composed
annotations_ and reduce configuration duplication across a test suite. annotations_ and reduce configuration duplication across a test suite.
@ -1313,8 +1356,10 @@ For further details, consult the <<core.adoc#annotation-programming-model,Spring
Annotation Programming Model>>. Annotation Programming Model>>.
[[testcontext-framework]] [[testcontext-framework]]
=== Spring TestContext Framework === Spring TestContext Framework
The __Spring TestContext Framework__ (located in the The __Spring TestContext Framework__ (located in the
`org.springframework.test.context` package) provides generic, annotation-driven unit and `org.springframework.test.context` package) provides generic, annotation-driven unit and
integration testing support that is agnostic of the testing framework in use. The integration testing support that is agnostic of the testing framework in use. The
@ -1341,6 +1386,7 @@ management>>), <<testcontext-support-classes,support classes>>, and
[[testcontext-key-abstractions]] [[testcontext-key-abstractions]]
==== Key abstractions ==== Key abstractions
The core of the framework consists of the `TestContextManager` class and the The core of the framework consists of the `TestContextManager` class and the
`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A `TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A
`TestContextManager` is created per test class (e.g., for the execution of all test `TestContextManager` is created per test class (e.g., for the execution of all test
@ -1354,12 +1400,14 @@ class. Consult the javadocs and the Spring test suite for further information an
examples of various implementations. examples of various implementations.
===== TestContext ===== TestContext
`TestContext` encapsulates the context in which a test is executed, agnostic of the `TestContext` encapsulates the context in which a test is executed, agnostic of the
actual testing framework in use, and provides context management and caching support for actual testing framework in use, and provides context management and caching support for
the test instance for which it is responsible. The `TestContext` also delegates to a the test instance for which it is responsible. The `TestContext` also delegates to a
`SmartContextLoader` to load an `ApplicationContext` if requested. `SmartContextLoader` to load an `ApplicationContext` if requested.
===== TestContextManager ===== TestContextManager
`TestContextManager` is the main entry point into the __Spring TestContext Framework__ `TestContextManager` is the main entry point into the __Spring TestContext Framework__
and is responsible for managing a single `TestContext` and signaling events to each and is responsible for managing a single `TestContext` and signaling events to each
registered `TestExecutionListener` at well-defined test execution points: registered `TestExecutionListener` at well-defined test execution points:
@ -1373,11 +1421,13 @@ registered `TestExecutionListener` at well-defined test execution points:
* after any __after class__ or __after all__ methods of a particular testing framework * after any __after class__ or __after all__ methods of a particular testing framework
===== TestExecutionListener ===== TestExecutionListener
`TestExecutionListener` defines the API for reacting to test execution events published `TestExecutionListener` defines the API for reacting to test execution events published
by the `TestContextManager` with which the listener is registered. See by the `TestContextManager` with which the listener is registered. See
<<testcontext-tel-config>>. <<testcontext-tel-config>>.
===== Context Loaders ===== Context Loaders
`ContextLoader` is a strategy interface that was introduced in Spring 2.5 for loading an `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. `ApplicationContext` for an integration test managed by the Spring TestContext Framework.
Implement `SmartContextLoader` instead of this interface in order to provide support for Implement `SmartContextLoader` instead of this interface in order to provide support for
@ -1419,6 +1469,7 @@ locations__.
* `GenericPropertiesContextLoader`: loads a standard `ApplicationContext` from Java * `GenericPropertiesContextLoader`: loads a standard `ApplicationContext` from Java
Properties files. Properties files.
[[testcontext-bootstrapping]] [[testcontext-bootstrapping]]
==== Bootstrapping the TestContext framework ==== Bootstrapping the TestContext framework
@ -1444,6 +1495,7 @@ accommodate new requirements, implementers are strongly encouraged not to implem
interface directly but rather to extend `AbstractTestContextBootstrapper` or one of its interface directly but rather to extend `AbstractTestContextBootstrapper` or one of its
concrete subclasses instead. concrete subclasses instead.
[[testcontext-tel-config]] [[testcontext-tel-config]]
==== TestExecutionListener configuration ==== TestExecutionListener configuration
@ -1883,6 +1935,7 @@ from, but you still have the freedom to include or import the other type of conf
[[testcontext-ctx-management-initializers]] [[testcontext-ctx-management-initializers]]
===== Context configuration with context initializers ===== Context configuration with context initializers
To configure an `ApplicationContext` for your tests using context initializers, annotate To configure an `ApplicationContext` for your tests using context initializers, annotate
your test class with `@ContextConfiguration` and configure the `initializers` attribute your test class with `@ContextConfiguration` and configure the `initializers` attribute
with an array that contains references to classes that implement with an array that contains references to classes that implement
@ -1929,6 +1982,7 @@ files or configuration classes.
[[testcontext-ctx-management-inheritance]] [[testcontext-ctx-management-inheritance]]
===== Context configuration inheritance ===== Context configuration inheritance
`@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers` `@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers`
attributes that denote whether resource locations or annotated classes and context attributes that denote whether resource locations or annotated classes and context
initializers declared by superclasses should be __inherited__. The default value for initializers declared by superclasses should be __inherited__. The default value for
@ -2017,6 +2071,7 @@ with Spring's `@Order` annotation or the standard `@Priority` annotation.
[[testcontext-ctx-management-env-profiles]] [[testcontext-ctx-management-env-profiles]]
===== Context configuration with environment profiles ===== Context configuration with environment profiles
Spring 3.1 introduced first-class support in the framework for the notion of Spring 3.1 introduced first-class support in the framework for the notion of
environments and profiles (a.k.a., __bean definition profiles__), and integration tests environments and profiles (a.k.a., __bean definition profiles__), and integration tests
can be configured to activate particular bean definition profiles for various testing can be configured to activate particular bean definition profiles for various testing
@ -2511,6 +2566,7 @@ loaded using the _inlined_ `key1` and `key2` properties.
[[testcontext-ctx-management-web]] [[testcontext-ctx-management-web]]
===== Loading a WebApplicationContext ===== Loading a WebApplicationContext
Spring 3.2 introduced support for loading a `WebApplicationContext` in integration Spring 3.2 introduced support for loading a `WebApplicationContext` in integration
tests. To instruct the TestContext framework to load a `WebApplicationContext` instead tests. To instruct the TestContext framework to load a `WebApplicationContext` instead
of a standard `ApplicationContext`, simply annotate the respective test class with of a standard `ApplicationContext`, simply annotate the respective test class with
@ -2904,6 +2960,7 @@ cleared. For further details consult the discussion of `@DirtiesContext` in
[[testcontext-fixture-di]] [[testcontext-fixture-di]]
==== Dependency injection of test fixtures ==== Dependency injection of test fixtures
When you use the `DependencyInjectionTestExecutionListener` -- which is configured by When you use the `DependencyInjectionTestExecutionListener` -- which is configured by
default -- the dependencies of your test instances are __injected__ from beans in the default -- the dependencies of your test instances are __injected__ from beans in the
application context that you configured with `@ContextConfiguration`. You may use setter application context that you configured with `@ContextConfiguration`. You may use setter
@ -3191,6 +3248,7 @@ configured theme.
} }
---- ----
[[testcontext-tx]] [[testcontext-tx]]
==== Transaction management ==== Transaction management
@ -3293,6 +3351,7 @@ via the `@Commit` and `@Rollback` annotations. See the corresponding entries in
[[testcontext-tx-programmatic-tx-mgt]] [[testcontext-tx-programmatic-tx-mgt]]
===== Programmatic transaction management ===== Programmatic transaction management
Since Spring Framework 4.1, it is possible to interact with test-managed transactions Since Spring Framework 4.1, it is possible to interact with test-managed transactions
_programmatically_ via the static methods in `TestTransaction`. For example, _programmatically_ via the static methods in `TestTransaction`. For example,
`TestTransaction` may be used within _test_ methods, _before_ methods, and _after_ `TestTransaction` may be used within _test_ methods, _before_ methods, and _after_
@ -3557,7 +3616,6 @@ and executing SQL scripts. Similarly, the `executeSqlScript(..)` methods in
internally use a `ResourceDatabasePopulator` for executing SQL scripts. Consult the javadocs internally use a `ResourceDatabasePopulator` for executing SQL scripts. Consult the javadocs
for the various `executeSqlScript(..)` methods for further details. for the various `executeSqlScript(..)` methods for further details.
[[testcontext-executing-sql-declaratively]] [[testcontext-executing-sql-declaratively]]
===== Executing SQL scripts declaratively with @Sql ===== Executing SQL scripts declaratively with @Sql
@ -3817,10 +3875,10 @@ constructor; however, if you use a third-party library that provides a custom
execution. execution.
==== ====
[[testcontext-support-classes]] [[testcontext-support-classes]]
==== TestContext Framework support classes ==== TestContext Framework support classes
[[testcontext-junit4-runner]] [[testcontext-junit4-runner]]
===== Spring JUnit 4 Runner ===== Spring JUnit 4 Runner
@ -3854,7 +3912,6 @@ public class SimpleTest {
} }
---- ----
[[testcontext-junit4-rules]] [[testcontext-junit4-rules]]
===== Spring JUnit 4 Rules ===== Spring JUnit 4 Rules
@ -3898,7 +3955,6 @@ public class IntegrationTest {
} }
---- ----
[[testcontext-support-classes-junit4]] [[testcontext-support-classes-junit4]]
===== JUnit 4 support classes ===== JUnit 4 support classes
@ -3938,7 +3994,6 @@ by using `@RunWith(SpringRunner.class)` or <<testcontext-junit4-rules,Spring's
JUnit rules>>. JUnit rules>>.
==== ====
[[testcontext-junit-jupiter-extension]] [[testcontext-junit-jupiter-extension]]
===== SpringExtension for JUnit Jupiter ===== SpringExtension for JUnit Jupiter
@ -4027,7 +4082,6 @@ class SimpleWebTests {
See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in
<<integration-testing-annotations-junit-jupiter>> for further details. <<integration-testing-annotations-junit-jupiter>> for further details.
[[testcontext-junit-jupiter-di]] [[testcontext-junit-jupiter-di]]
===== Dependency Injection with the SpringExtension ===== Dependency Injection with the SpringExtension
@ -4130,7 +4184,6 @@ class OrderServiceIntegrationTests {
} }
---- ----
[[testcontext-support-classes-testng]] [[testcontext-support-classes-testng]]
===== TestNG support classes ===== TestNG support classes
@ -4200,9 +4253,9 @@ integration tests, see <<spring-mvc-test-vs-end-to-end-integration-tests>>.
==== ====
[[spring-mvc-test-server]] [[spring-mvc-test-server]]
==== Server-Side Tests ==== Server-Side Tests
It's easy to write a plain unit test for a Spring MVC controller using JUnit or TestNG: It's easy to write a plain unit test for a Spring MVC controller using JUnit or TestNG:
simply instantiate the controller, inject it with mocked or stubbed dependencies, and call simply instantiate the controller, inject it with mocked or stubbed dependencies, and call
its methods passing `MockHttpServletRequest`, `MockHttpServletResponse`, etc., as necessary. its methods passing `MockHttpServletRequest`, `MockHttpServletResponse`, etc., as necessary.
@ -4262,6 +4315,7 @@ request that will be discussed below.
[[spring-mvc-test-server-static-imports]] [[spring-mvc-test-server-static-imports]]
===== Static Imports ===== Static Imports
The fluent API in the example above requires a few static imports such as The fluent API in the example above requires a few static imports such as
`MockMvcRequestBuilders.{asterisk}`, `MockMvcResultMatchers.{asterisk}`, `MockMvcRequestBuilders.{asterisk}`, `MockMvcResultMatchers.{asterisk}`,
and `MockMvcBuilders.{asterisk}`. An easy way to find these classes is to search for and `MockMvcBuilders.{asterisk}`. An easy way to find these classes is to search for
@ -4274,6 +4328,7 @@ completion on static members.
[[spring-mvc-test-server-setup-options]] [[spring-mvc-test-server-setup-options]]
===== Setup Choices ===== Setup Choices
There are two main options for creating an instance of `MockMvc`. There are two main options for creating an instance of `MockMvc`.
The first is to load Spring MVC configuration through the __TestContext The first is to load Spring MVC configuration through the __TestContext
framework__, which loads the Spring configuration and injects a `WebApplicationContext` framework__, which loads the Spring configuration and injects a `WebApplicationContext`
@ -4418,10 +4473,9 @@ MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
See `ConfigurableMockMvcBuilder` for a list of all MockMvc builder features See `ConfigurableMockMvcBuilder` for a list of all MockMvc builder features
or use the IDE to explore the available options. or use the IDE to explore the available options.
[[spring-mvc-test-server-performing-requests]] [[spring-mvc-test-server-performing-requests]]
===== Performing Requests ===== Performing Requests
It's easy to perform requests using any HTTP method: It's easy to perform requests using any HTTP method:
[source,java,indent=0] [source,java,indent=0]
@ -4498,6 +4552,7 @@ specified on every request.
[[spring-mvc-test-server-defining-expectations]] [[spring-mvc-test-server-defining-expectations]]
===== Defining Expectations ===== Defining Expectations
Expectations can be defined by appending one or more `.andExpect(..)` calls after Expectations can be defined by appending one or more `.andExpect(..)` calls after
performing a request: performing a request:
@ -4604,6 +4659,7 @@ be verified using XPath expressions:
[[spring-mvc-test-server-filters]] [[spring-mvc-test-server-filters]]
===== Filter Registrations ===== Filter Registrations
When setting up a `MockMvc` instance, you can register one or more Servlet `Filter` instances: When setting up a `MockMvc` instance, you can register one or more Servlet `Filter` instances:
[source,java,indent=0] [source,java,indent=0]
@ -4662,9 +4718,9 @@ integration tests. At the same time it's important not to lose sight of the fact
the response is the most important thing to check. In short, there is room here for the response is the most important thing to check. In short, there is room here for
multiple styles and strategies of testing even within the same project. multiple styles and strategies of testing even within the same project.
[[spring-mvc-test-server-resources]] [[spring-mvc-test-server-resources]]
===== Further Server-Side Test Examples ===== Further Server-Side Test Examples
The framework's own tests include The framework's own tests include
https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples[many https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples[many
sample tests] intended to demonstrate how to use Spring MVC Test. Browse these examples sample tests] intended to demonstrate how to use Spring MVC Test. Browse these examples
@ -5336,7 +5392,6 @@ For additional information on creating a `MockMvc` instance refer to
In the previous section, we saw how to use `MockMvc` with `WebDriver`. In this section, In the previous section, we saw how to use `MockMvc` with `WebDriver`. In this section,
we will use http://www.gebish.org/[Geb] to make our tests even Groovy-er. we will use http://www.gebish.org/[Geb] to make our tests even Groovy-er.
[[spring-mvc-test-server-htmlunit-geb-why]] [[spring-mvc-test-server-htmlunit-geb-why]]
====== Why Geb and MockMvc? ====== Why Geb and MockMvc?
@ -5467,6 +5522,7 @@ http://www.gebish.org/manual/current/[The Book of Geb] user's manual.
[[spring-mvc-test-client]] [[spring-mvc-test-client]]
==== Client-Side REST Tests ==== Client-Side REST Tests
Client-side tests can be used to test code that internally uses the `RestTemplate`. Client-side tests can be used to test code that internally uses the `RestTemplate`.
The idea is to declare expected requests and to provide "stub" responses so that The idea is to declare expected requests and to provide "stub" responses so that
you can focus on testing the code in isolation, i.e. without running a server. you can focus on testing the code in isolation, i.e. without running a server.
@ -5546,10 +5602,9 @@ server-side logic but without running a server. Here is an example:
mockServer.verify(); mockServer.verify();
---- ----
[[spring-mvc-test-client-static-imports]] [[spring-mvc-test-client-static-imports]]
===== Static Imports ===== Static Imports
Just like with server-side tests, the fluent API for client-side tests requires a few Just like with server-side tests, the fluent API for client-side tests requires a few
static imports. Those are easy to find by searching __"MockRest*"__. Eclipse users static imports. Those are easy to find by searching __"MockRest*"__. Eclipse users
should add `"MockRestRequestMatchers.{asterisk}"` and `"MockRestResponseCreators.{asterisk}"` should add `"MockRestRequestMatchers.{asterisk}"` and `"MockRestResponseCreators.{asterisk}"`
@ -5561,14 +5616,17 @@ configuration. Just check the support for code completion on static members.
[[spring-mvc-test-client-resources]] [[spring-mvc-test-client-resources]]
===== Further Examples of Client-side REST Tests ===== Further Examples of Client-side REST Tests
Spring MVC Test's own tests include Spring MVC Test's own tests include
https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/client/samples[example https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/client/samples[example
tests] of client-side REST tests. tests] of client-side REST tests.
include::testing-webtestclient.adoc[leveloffset=+2] include::testing-webtestclient.adoc[leveloffset=+2]
[[testing-examples-petclinic]] [[testing-examples-petclinic]]
=== PetClinic Example === PetClinic Example
@ -5696,4 +5754,3 @@ Consult the following resources for more information about testing:
Maven) targeted for database-driven projects that, among other things, puts your Maven) targeted for database-driven projects that, among other things, puts your
database into a known state between test runs. database into a known state between test runs.
* http://grinder.sourceforge.net/[The Grinder]: Java load testing framework. * http://grinder.sourceforge.net/[The Grinder]: Java load testing framework.

View File

@ -19,6 +19,8 @@ include::web/webflux.adoc[leveloffset=+1]
include::web/webflux-webclient.adoc[leveloffset=+1] include::web/webflux-webclient.adoc[leveloffset=+1]
[[webflux-test]] [[webflux-test]]
== Testing == Testing
@ -31,6 +33,8 @@ response objects to provide support for testing WebFlux applications without and
server. The `WebTestClient` can be used for end-to-end integration tests too. server. The `WebTestClient` can be used for end-to-end integration tests too.
[[webflux-reactive-libraries]] [[webflux-reactive-libraries]]
== Reactive Libraries == Reactive Libraries

View File

@ -1,8 +1,9 @@
[[web-integration]] [[web-integration]]
= Other Web Frameworks = Other Web Frameworks
[[intro]] [[intro]]
== Introduction == Introduction
@ -18,6 +19,8 @@ arguably most evident in the web area, where Spring provides its own web framewo
popular third party web frameworks. popular third party web frameworks.
[[web-integration-common]] [[web-integration-common]]
== Common config == Common config
Before diving into the integration specifics of each supported web framework, let us Before diving into the integration specifics of each supported web framework, let us
@ -103,7 +106,7 @@ has more detail on its specific integration strategies.
[[jsf]] [[jsf]]
== JSF 1.2 == JSF
JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web user 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. interface framework. As of Java EE 5, it is an official part of the Java EE umbrella.
@ -122,15 +125,17 @@ http://projects.spring.io/spring-webflow[Spring Web Flow website] for details!
The key element in Spring's JSF integration is the JSF `ELResolver` mechanism. The key element in Spring's JSF integration is the JSF `ELResolver` mechanism.
[[jsf-springbeanfaceselresolver]] [[jsf-springbeanfaceselresolver]]
=== Spring Bean Resolver === Spring Bean Resolver
`SpringBeanFacesELResolver` is a JSF 1.2 compliant `ELResolver` implementation, `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. Like integrating with the standard Unified EL as used by JSF 1.2 and JSP 2.1. Like
`SpringBeanVariableResolver`, it delegates to the Spring's 'business context' `SpringBeanVariableResolver`, it delegates to the Spring's 'business context'
`WebApplicationContext` __first__, then to the default resolver of the underlying JSF `WebApplicationContext` __first__, then to the default resolver of the underlying JSF
implementation. implementation.
Configuration-wise, simply define `SpringBeanFacesELResolver` in your JSF 1.2 Configuration-wise, simply define `SpringBeanFacesELResolver` in your JSF
__faces-context.xml__ file: __faces-context.xml__ file:
[source,xml,indent=0] [source,xml,indent=0]
@ -145,6 +150,7 @@ __faces-context.xml__ file:
---- ----
[[jsf-facescontextutils]] [[jsf-facescontextutils]]
=== FacesContextUtils === FacesContextUtils
A custom `VariableResolver` works well when mapping one's properties to beans A custom `VariableResolver` works well when mapping one's properties to beans
@ -161,6 +167,7 @@ takes a `FacesContext` parameter rather than a `ServletContext` parameter.
[[struts]] [[struts]]
== Apache Struts 2.x == Apache Struts 2.x
Invented by Craig McClanahan, http://struts.apache.org[Struts] is an open source project Invented by Craig McClanahan, http://struts.apache.org[Struts] is an open source project
@ -176,6 +183,7 @@ built-in Spring integration shipped with Struts.
[[tapestry]] [[tapestry]]
== Tapestry 5.x == Tapestry 5.x
From the http://tapestry.apache.org/[Tapestry homepage]: From the http://tapestry.apache.org/[Tapestry homepage]:
@ -193,6 +201,7 @@ Spring].
[[web-integration-resources]] [[web-integration-resources]]
== Further Resources == Further Resources
Find below links to further resources about the various web frameworks described in this Find below links to further resources about the various web frameworks described in this
@ -201,4 +210,3 @@ chapter.
* The http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[JSF] homepage * The http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[JSF] homepage
* The http://struts.apache.org/[Struts] homepage * The http://struts.apache.org/[Struts] homepage
* The http://tapestry.apache.org/[Tapestry] homepage * The http://tapestry.apache.org/[Tapestry] homepage

View File

@ -7,6 +7,8 @@ It is an alternative to the annotated-based programming model but runs on the sa
<<web-reactive.adoc#webflux-reactive-spring-web>> foundation <<web-reactive.adoc#webflux-reactive-spring-web>> foundation
[[webflux-fn-handler-functions]] [[webflux-fn-handler-functions]]
== HandlerFunction == HandlerFunction
@ -119,6 +121,9 @@ when the `Person` has been saved.
variable `id`. We retrieve that `Person` via the repository, and create a JSON response if it is variable `id`. We retrieve that `Person` via the repository, and create a JSON response if it is
found. If it is not found, we use `switchIfEmpty(Mono<T>)` to return a 404 Not Found response. found. If it is not found, we use `switchIfEmpty(Mono<T>)` to return a 404 Not Found response.
[[webflux-fn-router-functions]] [[webflux-fn-router-functions]]
== RouterFunction == RouterFunction
@ -182,6 +187,8 @@ For instance, `RequestPredicates.GET(String)` is a composition of
`RequestPredicates.method(HttpMethod)` and `RequestPredicates.path(String)`. `RequestPredicates.method(HttpMethod)` and `RequestPredicates.path(String)`.
[[webflux-fn-running]] [[webflux-fn-running]]
== Running a server == Running a server
@ -199,6 +206,7 @@ handle requests with router and handler functions.
[[webflux-fn-handler-filter-function]] [[webflux-fn-handler-filter-function]]
== HandlerFilterFunction == HandlerFilterFunction
@ -232,4 +240,4 @@ RouterFunction<ServerResponse> filteredRoute =
---- ----
You can see in this example that invoking the `next.handle(ServerRequest)` is optional: we only You can see in this example that invoking the `next.handle(ServerRequest)` is optional: we only
allow the handler function to be executed when access is allowed. allow the handler function to be executed when access is allowed.

View File

@ -22,6 +22,8 @@ non-blocking I/O.
==== ====
[[webflux-client-retrieve]] [[webflux-client-retrieve]]
== Retrieve == Retrieve
@ -65,6 +67,7 @@ By default, responses with 4xx or 5xx status codes result in an error of type
[[webflux-client-exchange]] [[webflux-client-exchange]]
== Exchange == Exchange
@ -103,6 +106,8 @@ to complete.
==== ====
[[webflux-client-body]] [[webflux-client-body]]
== Request body == Request body
@ -152,6 +157,8 @@ Or if you have the actual value, use the `syncBody` shortcut method:
---- ----
[[webflux-client-builder]] [[webflux-client-builder]]
== Builder options == Builder options
@ -211,7 +218,6 @@ build a new `WebClient`, based on, but without affecting the current instance:
[[webflux-client-filter]] [[webflux-client-filter]]
== Filters == Filters
@ -254,4 +260,3 @@ You can also mutate an existing `WebClient` instance without affecting the origi
.filter(basicAuthentication("user", "pwd") .filter(basicAuthentication("user", "pwd")
.build(); .build();
---- ----

View File

@ -1,6 +1,9 @@
[[webflux]] [[webflux]]
= Spring WebFlux = Spring WebFlux
[[webflux-introduction]] [[webflux-introduction]]
== Introduction == Introduction
The original web framework included in the Spring Framework, Spring Web MVC, was purpose The original web framework included in the Spring Framework, Spring Web MVC, was purpose
@ -17,6 +20,7 @@ Applications may use one or the other module, or in some cases both --
e.g. Spring MVC controllers with the reactive `WebClient`. e.g. Spring MVC controllers with the reactive `WebClient`.
[[webflux-new-framework]] [[webflux-new-framework]]
=== Why a new web framework? === Why a new web framework?
@ -37,6 +41,7 @@ composition of asynchronous logic. At the programming model level Java 8 enabled
WebFlux to offer functional web endpoints alongside with annotated controllers. WebFlux to offer functional web endpoints alongside with annotated controllers.
[[webflux-why-reactive]] [[webflux-why-reactive]]
=== Reactive: what and why? === Reactive: what and why?
@ -72,6 +77,7 @@ If a publisher can't slow down then it has to decide whether to buffer, drop, or
==== ====
[[webflux-reactive-api]] [[webflux-reactive-api]]
=== Reactive API === Reactive API
@ -100,6 +106,7 @@ Whenever feasible -- e.g. annotated controllers, WebFlux adapts transparently to
of RxJava or other reactive library. See <<webflux-reactive-libraries>> for more details. of RxJava or other reactive library. See <<webflux-reactive-libraries>> for more details.
[[webflux-programming-models]] [[webflux-programming-models]]
=== Programming models === Programming models
@ -120,6 +127,7 @@ is in charge of request handling from start to finish vs declaring intent throug
annotations and being called back. annotations and being called back.
[[webflux-framework-choice]] [[webflux-framework-choice]]
=== Choosing a web framework === Choosing a web framework
@ -170,6 +178,7 @@ https://medium.com/netflix-techblog/zuul-2-the-netflix-journey-to-asynchronous-n
is a good resource. is a good resource.
[[webflux-server-choice]] [[webflux-server-choice]]
=== Choosing a server === Choosing a server
@ -198,6 +207,7 @@ optimized for performance, fully non-blocking, and adapted to Reactive Streams b
pressure. In Spring Boot it is trivial to make the switch. pressure. In Spring Boot it is trivial to make the switch.
[[webflux-performance]] [[webflux-performance]]
=== Performance vs scale === Performance vs scale
@ -215,6 +225,7 @@ dramatic.
[[webflux-reactive-spring-web]] [[webflux-reactive-spring-web]]
== Reactive Spring Web == Reactive Spring Web
@ -230,6 +241,7 @@ for HTTP request handling with Reactive Streams back pressure.
purpose server web API with filter chain style processing. purpose server web API with filter chain style processing.
[[webflux-httphandler]] [[webflux-httphandler]]
=== HttpHandler === HttpHandler
@ -411,6 +423,7 @@ to have the following detected:
|=== |===
[[webflux-codecs]] [[webflux-codecs]]
=== Codecs === Codecs
@ -439,6 +452,7 @@ of defaults along with the ability to override or replace those defaults.
[[webflux-dispatcher-handler]] [[webflux-dispatcher-handler]]
== DispatcherHandler == DispatcherHandler
[.small]#<<web.adoc#mvc-servlet,Same in Spring MVC>># [.small]#<<web.adoc#mvc-servlet,Same in Spring MVC>>#
@ -603,6 +617,7 @@ your Java configuration:
rendering). rendering).
[[webflux-ann-requestmapping]] [[webflux-ann-requestmapping]]
=== Request Mapping === Request Mapping
[.small]#<<web.adoc#mvc-ann-requestmapping,Same in Spring MVC>># [.small]#<<web.adoc#mvc-ann-requestmapping,Same in Spring MVC>>#
@ -859,6 +874,7 @@ is not necessary in the common case.
`@RequestMapping` handler methods have a flexible signature and can choose from a range of `@RequestMapping` handler methods have a flexible signature and can choose from a range of
supported controller method arguments and return values. supported controller method arguments and return values.
[[webflux-ann-arguments]] [[webflux-ann-arguments]]
==== Method arguments ==== Method arguments
[.small]#<<web.adoc#mvc-ann-arguments,Same in Spring MVC>># [.small]#<<web.adoc#mvc-ann-arguments,Same in Spring MVC>>#
@ -969,6 +985,7 @@ as a result of a class-level `@SessionAttributes` declaration.
|For access to request attributes. |For access to request attributes.
|=== |===
[[webflux-ann-return-types]] [[webflux-ann-return-types]]
==== Return values ==== Return values
[.small]#<<web.adoc#mvc-ann-return-types,Same in Spring MVC>># [.small]#<<web.adoc#mvc-ann-return-types,Same in Spring MVC>>#
@ -1029,10 +1046,12 @@ class name of the return type.
include::webflux-functional.adoc[leveloffset=+1] include::webflux-functional.adoc[leveloffset=+1]
[[webflux-config]] [[webflux-config]]
== WebFlux Java Config == WebFlux Java Config
[.small]#<<web.adoc#mvc-config,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config,Same in Spring MVC>>#
@ -1046,6 +1065,7 @@ easy to seem them in `WebFluxConfigurationSupport`, and if you want to learn mor
<<webflux-special-bean-types>>. <<webflux-special-bean-types>>.
[[webflux-config-enable]] [[webflux-config-enable]]
=== Enable WebFlux config === Enable WebFlux config
[.small]#<<web.adoc#mvc-config-enable,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-enable,Same in Spring MVC>>#
@ -1066,6 +1086,7 @@ The above registers a number of Spring WebFlux
available on the classpath -- for JSON, XML, etc. available on the classpath -- for JSON, XML, etc.
[[webflux-config-customize]] [[webflux-config-customize]]
=== WebFlux config API === WebFlux config API
[.small]#<<web.adoc#mvc-config-customize,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-customize,Same in Spring MVC>>#
@ -1118,6 +1139,7 @@ and the `FormattingConversionServiceFactoryBean` for more information on when to
==== ====
[[webflux-config-validation]] [[webflux-config-validation]]
=== Validation === Validation
[.small]#<<web.adoc#mvc-config-validation,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-validation,Same in Spring MVC>>#
@ -1167,6 +1189,7 @@ mark it with `@Primary` in order to avoid conflict with the one declared in the
==== ====
[[webflux-config-content-negotiation]] [[webflux-config-content-negotiation]]
=== Content type resolvers === Content type resolvers
[.small]#<<web.adoc#mvc-config-content-negotiation,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-content-negotiation,Same in Spring MVC>>#
@ -1191,6 +1214,8 @@ To customize the requested content type resolution:
} }
---- ----
[[webflux-config-message-codecs]] [[webflux-config-message-codecs]]
=== HTTP message codecs === HTTP message codecs
[.small]#<<web.adoc#mvc-config-message-converters,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-message-converters,Same in Spring MVC>>#
@ -1229,6 +1254,7 @@ It also automatically registers the following well-known modules if they are det
. https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: support for other Java 8 types like `Optional`. . https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: support for other Java 8 types like `Optional`.
[[webflux-config-view-resolvers]] [[webflux-config-view-resolvers]]
=== View resolvers === View resolvers
[.small]#<<web.adoc#mvc-config-view-resolvers,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-view-resolvers,Same in Spring MVC>>#
@ -1271,6 +1297,7 @@ Note that FreeMarker also requires configuration of the underlying view technolo
---- ----
[[webflux-config-static-resources]] [[webflux-config-static-resources]]
=== Static resources === Static resources
[.small]#<<web.adoc#mvc-config-static-resources,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-static-resources,Same in Spring MVC>>#
@ -1351,6 +1378,7 @@ match to incoming URLs without versions -- e.g. `"/jquery/jquery.min.js"` to
`"/jquery/1.2.0/jquery.min.js"`. `"/jquery/1.2.0/jquery.min.js"`.
[[webflux-config-path-matching]] [[webflux-config-path-matching]]
=== Path Matching === Path Matching
[.small]#<<web.adoc#mvc-config-path-matching,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-path-matching,Same in Spring MVC>>#
@ -1382,6 +1410,7 @@ To customize those options:
---- ----
[[webflux-config-advanced-java]] [[webflux-config-advanced-java]]
=== Advanced config mode === Advanced config mode
[.small]#<<web.adoc#mvc-config-advanced-java,Same in Spring MVC>># [.small]#<<web.adoc#mvc-config-advanced-java,Same in Spring MVC>>#
@ -1407,5 +1436,3 @@ For advanced mode, remove `@EnableWebFlux` and extend directly from
You can keep existing methods in `WebConfig` but you can now also override bean declarations You can keep existing methods in `WebConfig` but you can now also override bean declarations
from the base class and you can still have any number of other ``WebMvcConfigurer``'s on from the base class and you can still have any number of other ``WebMvcConfigurer``'s on
the classpath. the classpath.

View File

@ -3,6 +3,9 @@
This section describes options for client-side access to REST endpoints. This section describes options for client-side access to REST endpoints.
[[webmvc-resttemplate]] [[webmvc-resttemplate]]
== RestTemplate == RestTemplate
@ -19,6 +22,8 @@ See <<integration.adoc#rest-client-access,RestTemplate>> for more details on usi
`RestTemplate`. `RestTemplate`.
[[webmvc-webclient]] [[webmvc-webclient]]
== WebClient == WebClient

View File

@ -1,6 +1,9 @@
[[mvc-cors]] [[mvc-cors]]
= CORS = CORS
== Introduction == Introduction
For security reasons, browsers prohibit AJAX calls to resources residing outside the For security reasons, browsers prohibit AJAX calls to resources residing outside the
@ -31,6 +34,9 @@ Since CORS requests are automatically dispatched, you *do not need* to change th
(`false`) is the recommended approach. (`false`) is the recommended approach.
==== ====
[[mvc-cors-controller]] [[mvc-cors-controller]]
== @Controller CORS == @Controller CORS
@ -110,6 +116,9 @@ public class AccountController {
} }
---- ----
[[mvc-cors-global]] [[mvc-cors-global]]
== Global CORS == Global CORS
@ -119,6 +128,7 @@ be declared within Spring MVC and combined with fine-grained `@CrossOrigin` conf
By default all origins and `GET`, `HEAD`, and `POST` methods are allowed. By default all origins and `GET`, `HEAD`, and `POST` methods are allowed.
[[mvc-cors-global-java]] [[mvc-cors-global-java]]
=== Java Config === Java Config
@ -161,6 +171,7 @@ public class WebConfig implements WebMvcConfigurer {
---- ----
[[mvc-cors-global-xml]] [[mvc-cors-global-xml]]
=== XML Config === XML Config
@ -195,6 +206,9 @@ It is also possible to declare several CORS mappings with customized properties:
</mvc:cors> </mvc:cors>
---- ----
[[mvc-cors-customizations]] [[mvc-cors-customizations]]
== Advanced Customization == Advanced Customization
@ -213,6 +227,8 @@ It can be provided in various ways:
instance for each request. instance for each request.
[[mvc-cors-filter]] [[mvc-cors-filter]]
== CORS Filter == CORS Filter
@ -238,4 +254,4 @@ CorsFilter filter = new CorsFilter(source);
Also the information on Also the information on
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors[CORS] https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors[CORS]
in the Spring Security reference. in the Spring Security reference.

View File

@ -1,13 +1,19 @@
[[testing]] [[testing]]
= Testing = Testing
[[testing-servlet-mocks]] [[testing-servlet-mocks]]
== Servlet API Mocks == Servlet API Mocks
`spring-test` provides mock implementations of Servlet API contracts for unit testing `spring-test` provides mock implementations of Servlet API contracts for unit testing
controllers, filters, and other web components. controllers, filters, and other web components.
See <<testing.adoc#mock-objects-servlet,Servlet API>> mock objects for more details. See <<testing.adoc#mock-objects-servlet,Servlet API>> mock objects for more details.
[[testing-testcontext]] [[testing-testcontext]]
== TestContext Framework == TestContext Framework
@ -17,6 +23,8 @@ loading a `WebApplicationContext` with a `MockServletContext`.
See <<testing.adoc#testcontext-framework,TestContext Framework>> for more details. See <<testing.adoc#testcontext-framework,TestContext Framework>> for more details.
[[testing-mockmvc]] [[testing-mockmvc]]
== Spring MVC Tests == Spring MVC Tests
@ -25,6 +33,8 @@ through the `DispatcherServlet`, complete with Spring MVC infrastructure, but wi
HTTP server. See <<testing.adoc#spring-mvc-test-framework,Spring MVC Test>> for more details. HTTP server. See <<testing.adoc#spring-mvc-test-framework,Spring MVC Test>> for more details.
[[testing-resttemplate]] [[testing-resttemplate]]
== Client-side REST == Client-side REST

View File

@ -2,8 +2,11 @@
= View Technologies = View Technologies
[[mvc-view-introduction]] [[mvc-view-introduction]]
== Introduction == Introduction
One of the areas in which Spring excels is in the separation of view technologies from One of the areas in which Spring excels is in the separation of view technologies from
the rest of the MVC framework. For example, deciding to use Groovy Markup Templates the rest of the MVC framework. For example, deciding to use Groovy Markup Templates
or Thymeleaf in place of an existing JSP is primarily a matter of configuration. or Thymeleaf in place of an existing JSP is primarily a matter of configuration.
@ -13,6 +16,8 @@ briefly on how to add new ones. This chapter assumes you are already familiar wi
to the MVC framework. to the MVC framework.
[[mvc-view-thymeleaf]] [[mvc-view-thymeleaf]]
== Thymeleaf == Thymeleaf
@ -26,6 +31,8 @@ Please refer to the http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring
documentation section for more details. documentation section for more details.
[[mvc-view-groovymarkup]] [[mvc-view-groovymarkup]]
== Groovy Markup == Groovy Markup
@ -37,6 +44,7 @@ text based content.
This requires Groovy 2.3.1+ on the classpath. This requires Groovy 2.3.1+ on the classpath.
[[mvc-view-groovymarkup-configuration]] [[mvc-view-groovymarkup-configuration]]
=== Configuration === Configuration
@ -78,6 +86,7 @@ The XML counterpart using the MVC namespace is:
---- ----
[[mvc-view-groovymarkup-example]] [[mvc-view-groovymarkup-example]]
=== Example === Example
@ -100,15 +109,20 @@ Here is a sample template for an HTML page:
---- ----
[[mvc-view-freemarker]] [[mvc-view-freemarker]]
== FreeMarker == FreeMarker
http://www.freemarker.org[FreeMarker] is a templating language that can be used as a http://www.freemarker.org[FreeMarker] is a templating language that can be used as a
view technology within Spring MVC applications. For details on the template language, view technology within Spring MVC applications. For details on the template language,
see the http://www.freemarker.org[FreeMarker] web site. see the http://www.freemarker.org[FreeMarker] web site.
[[mvc-view-freemarker-dependencies]] [[mvc-view-freemarker-dependencies]]
=== Dependencies === Dependencies
Your web application will need to include `freemarker-2.x.jar` in order to work with Your web application will need to include `freemarker-2.x.jar` in order to work with
FreeMarker. Typically this is included in the `WEB-INF/lib` folder where the jars are FreeMarker. Typically this is included in the `WEB-INF/lib` folder where the jars are
guaranteed to be found by a Java EE server and added to the classpath for your guaranteed to be found by a Java EE server and added to the classpath for your
@ -116,8 +130,10 @@ application. It is of course assumed that you already have the `spring-webmvc.ja
your `'WEB-INF/lib'` directory too! your `'WEB-INF/lib'` directory too!
[[mvc-view-freemarker-contextconfig]] [[mvc-view-freemarker-contextconfig]]
=== Context configuration === Context configuration
A suitable configuration is initialized by adding the relevant configurer bean A suitable configuration is initialized by adding the relevant configurer bean
definition to your `'{asterisk}-servlet.xml'` as shown below: definition to your `'{asterisk}-servlet.xml'` as shown below:
@ -147,8 +163,10 @@ definition file.
==== ====
[[mvc-view-freemarker-createtemplates]] [[mvc-view-freemarker-createtemplates]]
=== Creating templates === Creating templates
Your templates need to be stored in the directory specified by the `FreeMarkerConfigurer` Your templates need to be stored in the directory specified by the `FreeMarkerConfigurer`
shown above. If you use the view resolvers highlighted, then the logical view names shown above. If you use the view resolvers highlighted, then the logical view names
relate to the template file names in similar fashion to `InternalResourceViewResolver` relate to the template file names in similar fashion to `InternalResourceViewResolver`
@ -158,6 +176,7 @@ for JSP's. So if your controller returns a ModelAndView object containing a view
[[mvc-views-freemarker]] [[mvc-views-freemarker]]
=== Advanced config === Advanced config
FreeMarker 'Settings' and 'SharedVariables' can be passed directly to the FreeMarker FreeMarker 'Settings' and 'SharedVariables' can be passed directly to the FreeMarker
`Configuration` object managed by Spring by setting the appropriate bean properties on `Configuration` object managed by Spring by setting the appropriate bean properties on
the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property requires a the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property requires a
@ -186,6 +205,7 @@ the `Configuration` object.
[[mvc-view-freemarker-forms]] [[mvc-view-freemarker-forms]]
=== Form handling === Form handling
Spring provides a tag library for use in JSP's that contains (amongst other things) a Spring provides a tag library for use in JSP's that contains (amongst other things) a
`<spring:bind/>` tag. This tag primarily enables forms to display values from form `<spring:bind/>` tag. This tag primarily enables forms to display values from form
backing objects and to show the results of failed validations from a `Validator` in the backing objects and to show the results of failed validations from a `Validator` in the
@ -195,6 +215,7 @@ with additional convenience macros for generating form input elements themselves
[[mvc-view-bind-macros]] [[mvc-view-bind-macros]]
==== The bind macros ==== The bind macros
A standard set of macros are maintained within the `spring-webmvc.jar` file for both A standard set of macros are maintained within the `spring-webmvc.jar` file for both
languages, so they are always available to a suitably configured application. languages, so they are always available to a suitably configured application.
@ -208,6 +229,7 @@ directly, the file is called `spring.ftl` in the package
[[mvc-view-simple-binding]] [[mvc-view-simple-binding]]
==== Simple binding ==== Simple binding
In your HTML forms (vm / ftl templates) which act as a form view for a Spring MVC In your HTML forms (vm / ftl templates) which act as a form view for a Spring MVC
controller, you can use code similar to the following to bind to field values and controller, you can use code similar to the following to bind to field values and
display error messages for each input field in similar fashion to the JSP equivalent. display error messages for each input field in similar fashion to the JSP equivalent.
@ -252,6 +274,7 @@ They are explained in the next section.
[[mvc-views-form-macros]] [[mvc-views-form-macros]]
==== Input macros ==== Input macros
Additional convenience macros for both languages simplify both binding and form Additional convenience macros for both languages simplify both binding and form
generation (including validation error display). It is never necessary to use these generation (including validation error display). It is never necessary to use these
macros to generate form input fields, and they can be mixed and matched with simple HTML macros to generate form input fields, and they can be mixed and matched with simple HTML
@ -342,6 +365,7 @@ differences exist between the two languages, they are explained in the notes.
[[mvc-views-form-macros-input]] [[mvc-views-form-macros-input]]
===== Input Fields ===== Input Fields
The formInput macro takes the path parameter (command.name) and an additional attributes The formInput macro takes the path parameter (command.name) and an additional attributes
parameter which is empty in the example above. The macro, along with all other form parameter which is empty in the example above. The macro, along with all other form
generation macros, performs an implicit spring bind on the path parameter. The binding generation macros, performs an implicit spring bind on the path parameter. The binding
@ -383,6 +407,7 @@ information or rows and cols attributes for the textarea.
[[mvc-views-form-macros-select]] [[mvc-views-form-macros-select]]
===== Selection Fields ===== Selection Fields
Four selection field macros can be used to generate common UI value selection inputs in Four selection field macros can be used to generate common UI value selection inputs in
your HTML forms. your HTML forms.
@ -457,6 +482,7 @@ user still sees the more user friendly city names.
[[mvc-views-form-macros-html-escaping]] [[mvc-views-form-macros-html-escaping]]
==== HTML escaping ==== HTML escaping
Default usage of the form macros above will result in HTML tags that are HTML 4.01 Default usage of the form macros above will result in HTML tags that are HTML 4.01
compliant and that use the default value for HTML escaping defined in your web.xml as compliant and that use the default value for HTML escaping defined in your web.xml as
used by Spring's bind support. In order to make the tags XHTML compliant or to override used by Spring's bind support. In order to make the tags XHTML compliant or to override
@ -498,6 +524,7 @@ In similar fashion, HTML escaping can be specified per field:
[[mvc-view-jsp]] [[mvc-view-jsp]]
== JSP & JSTL == JSP & JSTL
Spring provides a couple of out-of-the-box solutions for JSP and JSTL views. Using JSP Spring provides a couple of out-of-the-box solutions for JSP and JSTL views. Using JSP
or JSTL is done using a normal view resolver defined in the `WebApplicationContext`. or JSTL is done using a normal view resolver defined in the `WebApplicationContext`.
Furthermore, of course you need to write some JSPs that will actually render the view. Furthermore, of course you need to write some JSPs that will actually render the view.
@ -518,6 +545,7 @@ somewhat.
[[mvc-view-jsp-resolver]] [[mvc-view-jsp-resolver]]
=== View resolvers === View resolvers
Just as with any other view technology you're integrating with Spring, for JSPs you'll Just as with any other view technology you're integrating with Spring, for JSPs you'll
need a view resolver that will resolve your views. The most commonly used view resolvers need a view resolver that will resolve your views. The most commonly used view resolvers
when developing with JSPs are the `InternalResourceViewResolver` and the when developing with JSPs are the `InternalResourceViewResolver` and the
@ -561,6 +589,7 @@ under the `'WEB-INF'` directory, so there can be no direct access by clients.
[[mvc-view-jsp-jstl]] [[mvc-view-jsp-jstl]]
=== JSPs versus JSTL === JSPs versus JSTL
When using the Java Standard Tag Library you must use a special view class, the When using the Java Standard Tag Library you must use a special view class, the
`JstlView`, as JSTL needs some preparation before things such as the I18N features will `JstlView`, as JSTL needs some preparation before things such as the I18N features will
work. work.
@ -569,6 +598,7 @@ work.
[[mvc-view-jsp-tags]] [[mvc-view-jsp-tags]]
=== Spring tags === Spring tags
Spring provides data binding of request parameters to command objects as described in Spring provides data binding of request parameters to command objects as described in
earlier chapters. To facilitate the development of JSP pages in combination with those earlier chapters. To facilitate the development of JSP pages in combination with those
data binding features, Spring provides a few tags that make things even easier. All data binding features, Spring provides a few tags that make things even easier. All
@ -582,6 +612,7 @@ or see the tag library description.
[[mvc-view-jsp-formtaglib]] [[mvc-view-jsp-formtaglib]]
=== Spring form tags === Spring form tags
As of version 2.0, Spring provides a comprehensive set of data binding-aware tags for As of version 2.0, Spring provides a comprehensive set of data binding-aware tags for
handling form elements when using JSP and Spring Web MVC. Each tag provides support for handling form elements when using JSP and Spring Web MVC. Each tag provides support for
the set of attributes of its corresponding HTML tag counterpart, making the tags the set of attributes of its corresponding HTML tag counterpart, making the tags
@ -598,6 +629,7 @@ included generated HTML snippets where certain tags require further commentary.
[[mvc-view-jsp-formtaglib-configuration]] [[mvc-view-jsp-formtaglib-configuration]]
==== Configuration ==== Configuration
The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is
called `spring-form.tld`. called `spring-form.tld`.
@ -1267,6 +1299,7 @@ or see the tag library description.
[[mvc-rest-method-conversion]] [[mvc-rest-method-conversion]]
==== HTTP Method Conversion ==== HTTP Method Conversion
A key principle of REST is the use of the Uniform Interface. This means that all A key principle of REST is the use of the Uniform Interface. This means that all
resources (URLs) can be manipulated using the same four HTTP methods: GET, PUT, POST, resources (URLs) can be manipulated using the same four HTTP methods: GET, PUT, POST,
and DELETE. For each method, the HTTP specification defines the exact semantics. For and DELETE. For each method, the HTTP specification defines the exact semantics. For
@ -1327,6 +1360,7 @@ The corresponding `@Controller` method is shown below:
[[mvc-view-jsp-formtaglib-html5]] [[mvc-view-jsp-formtaglib-html5]]
==== HTML5 Tags ==== HTML5 Tags
Starting with Spring 3, the Spring form tag library allows entering dynamic attributes, Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
which means you can enter any HTML5 specific attributes. which means you can enter any HTML5 specific attributes.
@ -1337,6 +1371,7 @@ is the default type.
[[mvc-view-script]] [[mvc-view-script]]
== Script views == Script views
@ -1354,6 +1389,8 @@ It has been tested with:
* http://www.stuartellis.eu/articles/erb/[ERB] running on http://jruby.org[JRuby] * http://www.stuartellis.eu/articles/erb/[ERB] running on http://jruby.org[JRuby]
* https://docs.python.org/2/library/string.html#template-strings[String templates] running on http://www.jython.org/[Jython] * https://docs.python.org/2/library/string.html#template-strings[String templates] running on http://www.jython.org/[Jython]
[[mvc-view-script-dependencies]] [[mvc-view-script-dependencies]]
=== Requirements === Requirements
@ -1374,6 +1411,7 @@ for Javascript you can use http://www.webjars.org/[WebJars] to add Maven/Gradle
in order to make your javascript libraries available in the classpath. in order to make your javascript libraries available in the classpath.
[[mvc-view-script-integrate]] [[mvc-view-script-integrate]]
=== Script templates === Script templates
@ -1536,6 +1574,7 @@ for more configuration examples.
[[mvc-view-xml-marshalling]] [[mvc-view-xml-marshalling]]
== XML Marshalling == XML Marshalling
The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm` The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm`
package to render the response content as XML. The object to be marshalled can be set package to render the response content as XML. The object to be marshalled can be set
explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view
@ -1547,13 +1586,12 @@ Mappers>>.
[[mvc-view-tiles]] [[mvc-view-tiles]]
== Tiles == Tiles
It is possible to integrate Tiles - just as any other view technology - in web It is possible to integrate Tiles - just as any other view technology - in web
applications using Spring. The following describes in a broad way how to do this. applications using Spring. The following describes in a broad way how to do this.
[NOTE] [NOTE]
==== ====
This section focuses on Spring's support for Tiles v3 in the This section focuses on Spring's support for Tiles v3 in the
@ -1561,15 +1599,19 @@ This section focuses on Spring's support for Tiles v3 in the
==== ====
[[mvc-view-tiles-dependencies]] [[mvc-view-tiles-dependencies]]
=== Dependencies === Dependencies
To be able to use Tiles, you have to add a dependency on Tiles version 3.0.1 or higher To be able to use Tiles, you have to add a dependency on Tiles version 3.0.1 or higher
and http://tiles.apache.org/framework/dependency-management.html[its transitive dependencies] and http://tiles.apache.org/framework/dependency-management.html[its transitive dependencies]
to your project. to your project.
[[mvc-view-tiles-integrate]] [[mvc-view-tiles-integrate]]
=== Configuration === Configuration
To be able to use Tiles, you have to configure it using files containing definitions To be able to use Tiles, you have to configure it using files containing definitions
(for basic information on definitions and other Tiles concepts, please have a look at (for basic information on definitions and other Tiles concepts, please have a look at
http://tiles.apache.org[]). In Spring this is done using the `TilesConfigurer`. Have a http://tiles.apache.org[]). In Spring this is done using the `TilesConfigurer`. Have a
@ -1720,8 +1762,10 @@ per preparer name (as used in your Tiles definitions).
[[mvc-view-xslt]] [[mvc-view-xslt]]
== XSLT == XSLT
XSLT is a transformation language for XML and is popular as a view technology within web XSLT is a transformation language for XML and is popular as a view technology within web
applications. XSLT can be a good choice as a view technology if your application applications. XSLT can be a good choice as a view technology if your application
naturally deals with XML, or if your model can easily be converted to XML. The following naturally deals with XML, or if your model can easily be converted to XML. The following
@ -1735,8 +1779,10 @@ name of our XSLT view. See <<mvc-controller>> for details of Spring Web MVC's
document ready for transformation. document ready for transformation.
[[mvc-view-xslt-beandefs]] [[mvc-view-xslt-beandefs]]
=== Beans === Beans
Configuration is standard for a simple Spring application. Configuration is standard for a simple Spring application.
The MVC configuration has to define a `XsltViewResolver` bean and The MVC configuration has to define a `XsltViewResolver` bean and
regular MVC annotation configuration. regular MVC annotation configuration.
@ -1763,6 +1809,7 @@ public class WebConfig implements WebMvcConfigurer {
And we need a Controller that encapsulates our word generation logic. And we need a Controller that encapsulates our word generation logic.
[[mvc-view-xslt-controllercode]] [[mvc-view-xslt-controllercode]]
=== Controller === Controller
@ -1809,6 +1856,7 @@ Next, `XsltViewResolver` will resolve the "home" XSLT template file and merge th
DOM document into it to generate our view. DOM document into it to generate our view.
[[mvc-view-xslt-transforming]] [[mvc-view-xslt-transforming]]
=== Transformation === Transformation
@ -1817,7 +1865,6 @@ DOM document into it to generate our view. As shown in the `XsltViewResolver`
configuration, XSLT templates live in the war file in the `'WEB-INF/xsl'` directory configuration, XSLT templates live in the war file in the `'WEB-INF/xsl'` directory
and end with a `"xslt"` file extension. and end with a `"xslt"` file extension.
[source,xml,indent=0] [source,xml,indent=0]
[subs="verbatim,quotes"] [subs="verbatim,quotes"]
---- ----
@ -1866,6 +1913,9 @@ This is rendered as:
</html> </html>
---- ----
[[mvc-view-document]] [[mvc-view-document]]
== PDF, Excel == PDF, Excel
@ -1873,6 +1923,7 @@ This is rendered as:
[[mvc-view-document-intro]] [[mvc-view-document-intro]]
=== Introduction === Introduction
Returning an HTML page isn't always the best way for the user to view the model output, Returning an HTML page isn't always the best way for the user to view the model output,
and Spring makes it simple to generate a PDF document or an Excel spreadsheet and Spring makes it simple to generate a PDF document or an Excel spreadsheet
dynamically from the model data. The document is the view and will be streamed from the dynamically from the model data. The document is the view and will be streamed from the
@ -1886,6 +1937,7 @@ for PDF generation, the iText library.
[[mvc-view-document-config]] [[mvc-view-document-config]]
=== Configuration === Configuration
Document based views are handled in an almost identical fashion to XSLT views, and the Document based views are handled in an almost identical fashion to XSLT views, and the
following sections build upon the previous one by demonstrating how the same controller following sections build upon the previous one by demonstrating how the same controller
used in the XSLT example is invoked to render the same model as both a PDF document and used in the XSLT example is invoked to render the same model as both a PDF document and
@ -1894,6 +1946,7 @@ an Excel spreadsheet (which can also be viewed or manipulated in Open Office).
[[mvc-view-document-configviews]] [[mvc-view-document-configviews]]
=== View definition === View definition
First, let's amend the views.properties file (or xml equivalent) and add a simple view First, let's amend the views.properties file (or xml equivalent) and add a simple view
definition for both document types. The entire file now looks like this with the XSLT definition for both document types. The entire file now looks like this with the XSLT
view shown from earlier: view shown from earlier:
@ -1914,16 +1967,20 @@ __If you want to start with a template spreadsheet or a fillable PDF form to add
model data to, specify the location as the 'url' property in the view definition__ model data to, specify the location as the 'url' property in the view definition__
[[mvc-view-document-configcontroller]] [[mvc-view-document-configcontroller]]
=== Controller === Controller
The controller code we'll use remains exactly the same from the XSLT example earlier The controller code we'll use remains exactly the same from the XSLT example earlier
other than to change the name of the view to use. Of course, you could be clever and other than to change the name of the view to use. Of course, you could be clever and
have this selected based on a URL parameter or some other logic - proof that Spring have this selected based on a URL parameter or some other logic - proof that Spring
really is very good at decoupling the views from the controllers! really is very good at decoupling the views from the controllers!
[[mvc-view-document-configsubclasses]] [[mvc-view-document-configsubclasses]]
=== Excel views === Excel views
Exactly as we did for the XSLT example, we'll subclass suitable abstract classes in Exactly as we did for the XSLT example, we'll subclass suitable abstract classes in
order to implement custom behavior in generating our output documents. For Excel, this order to implement custom behavior in generating our output documents. For Excel, this
involves writing a subclass of involves writing a subclass of
@ -2006,8 +2063,10 @@ that the Excel spreadsheet is created and downloaded automatically when you requ
same page as before. same page as before.
[[mvc-view-document-configsubclasspdf]] [[mvc-view-document-configsubclasspdf]]
=== PDF views === PDF views
The PDF version of the word list is even simpler. This time, the class extends The PDF version of the word list is even simpler. This time, the class extends
`org.springframework.web.servlet.view.document.AbstractPdfView` and implements the `org.springframework.web.servlet.view.document.AbstractPdfView` and implements the
`buildPdfDocument()` method as follows: `buildPdfDocument()` method as follows:
@ -2041,6 +2100,7 @@ document should appear listing each of the words in the model map.
[[mvc-view-feeds]] [[mvc-view-feeds]]
== RSS Feeds == RSS Feeds
Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class
`AbstractFeedView` and are used to provide Atom and RSS Feed views respectfully. They `AbstractFeedView` and are used to provide Atom and RSS Feed views respectfully. They
are based on java.net's https://rome.dev.java.net[ROME] project and are located in the are based on java.net's https://rome.dev.java.net[ROME] project and are located in the
@ -2101,11 +2161,16 @@ For an example of creating an Atom view please refer to Alef Arendsen's Spring T
https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry]. https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].
[[mvc-view-jackson]] [[mvc-view-jackson]]
== Jackson == Jackson
[[mvc-view-json-mapping]] [[mvc-view-json-mapping]]
=== JSON === JSON
The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response 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 content as JSON. By default, the entire contents of the model map (with the exception of
framework-specific classes) will be encoded as JSON. For cases where the contents of the framework-specific classes) will be encoded as JSON. For cases where the contents of the
@ -2125,9 +2190,9 @@ name(s) could be customized through the `jsonpParameterNames` property.
[[mvc-view-xml-mapping]] [[mvc-view-xml-mapping]]
=== XML === XML
The `MappingJackson2XmlView` uses the The `MappingJackson2XmlView` uses the
https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension]'s `XmlMapper` https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension]'s `XmlMapper`
to render the response content as XML. If the model contains multiples entries, the to render the response content as XML. If the model contains multiples entries, the
@ -2138,4 +2203,3 @@ XML mapping can be customized as needed through the use of JAXB or Jackson's pro
annotations. When further control is needed, a custom `XmlMapper` can be injected annotations. When further control is needed, a custom `XmlMapper` can be injected
through the `ObjectMapper` property for cases where custom XML through the `ObjectMapper` property for cases where custom XML
serializers/deserializers need to be provided for specific types. serializers/deserializers need to be provided for specific types.

View File

@ -2,8 +2,12 @@
= Spring Web MVC = Spring Web MVC
:doc-spring-security: {doc-root}/spring-security/site/docs/current/reference :doc-spring-security: {doc-root}/spring-security/site/docs/current/reference
[[mvc-introduction]] [[mvc-introduction]]
== Introduction == Introduction
Spring Web MVC is the original web framework built on the Servlet API and included Spring Web MVC is the original web framework built on the Servlet API and included
in the Spring Framework from the very beginning. The formal name "Spring Web MVC" in the Spring Framework from the very beginning. The formal name "Spring Web MVC"
comes from the name of its source module comes from the name of its source module
@ -18,6 +22,7 @@ covers Spring WebFlux.
[[mvc-servlet]] [[mvc-servlet]]
== DispatcherServlet == DispatcherServlet
[.small]#<<web-reactive.adoc#webflux-dispatcher-handler,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-dispatcher-handler,Same in Spring WebFlux>>#
@ -114,6 +119,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu
==== ====
[[mvc-servlet-context-hierarchy]] [[mvc-servlet-context-hierarchy]]
=== Context Hierarchy === Context Hierarchy
@ -287,6 +293,7 @@ provides many extra convenient options on top.
==== ====
[[mvc-container-config]] [[mvc-container-config]]
=== Container Config === Container Config
@ -467,6 +474,7 @@ initialization parameters ( `init-param` elements) to the Servlet declaration in
|=== |===
[[mvc-handlermapping-interceptor]] [[mvc-handlermapping-interceptor]]
=== Interception === Interception
@ -499,8 +507,10 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
`RequestMappingHandlerAdapter`. `RequestMappingHandlerAdapter`.
[[mvc-viewresolver]] [[mvc-viewresolver]]
=== View Resolution === View Resolution
Spring MVC defines the `ViewResolver` and `View` interfaces that enable you to render Spring MVC defines the `ViewResolver` and `View` interfaces that enable you to render
models in a browser without tying you to a specific view technology. `ViewResolver` models in a browser without tying you to a specific view technology. `ViewResolver`
provides a mapping between view names and actual views. `View` addresses the preparation provides a mapping between view names and actual views. `View` addresses the preparation
@ -553,7 +563,6 @@ This table below provides more details on the `ViewResolver` hierarchy:
request file name or `Accept` header. See <<mvc-multiple-representations>>. request file name or `Accept` header. See <<mvc-multiple-representations>>.
|=== |===
You chain view resolvers by configuring more than one resolver and, if necessary, by You chain view resolvers by configuring more than one resolver and, if necessary, by
setting the `order` property to specify ordering. Remember, the higher the order property, setting the `order` property to specify ordering. Remember, the higher the order property,
the later the view resolver is positioned in the chain. the later the view resolver is positioned in the chain.
@ -569,7 +578,6 @@ how to configure view resolution. Also see<<mvc-view>> for more details on suppo
view technologies. view technologies.
[[mvc-redirecting-redirect-prefix]] [[mvc-redirecting-redirect-prefix]]
==== Redirect ==== Redirect
@ -622,8 +630,10 @@ Content-Type was `text/xml` is a compatible match.
See <<mvc-config-view-resolvers>> under <<mvc-config>> for configuration details. See <<mvc-config-view-resolvers>> under <<mvc-config>> for configuration details.
[[mvc-localeresolver]] [[mvc-localeresolver]]
=== Locales === Locale
Most parts of Spring's architecture support internationalization, just as the Spring web Most parts of Spring's architecture support internationalization, just as the Spring web
MVC framework does. `DispatcherServlet` enables you to automatically resolve messages MVC framework does. `DispatcherServlet` enables you to automatically resolve messages
using the client's locale. This is done with `LocaleResolver` objects. using the client's locale. This is done with `LocaleResolver` objects.
@ -643,9 +653,9 @@ context in the normal way. Here is a selection of the locale resolvers included
Spring. Spring.
[[mvc-timezone]] [[mvc-timezone]]
==== TimeZone ==== TimeZone
In addition to obtaining the client's locale, it is often useful to know their time zone. In addition to obtaining the client's locale, it is often useful to know their time zone.
The `LocaleContextResolver` interface offers an extension to `LocaleResolver` that allows The `LocaleContextResolver` interface offers an extension to `LocaleResolver` that allows
resolvers to provide a richer `LocaleContext`, which may include time zone information. resolvers to provide a richer `LocaleContext`, which may include time zone information.
@ -656,16 +666,15 @@ by Date/Time `Converter` and `Formatter` objects registered with Spring's
`ConversionService`. `ConversionService`.
[[mvc-localeresolver-acceptheader]] [[mvc-localeresolver-acceptheader]]
==== Header resolver ==== Header resolver
This locale resolver inspects the `accept-language` header in the request that was sent This locale resolver inspects the `accept-language` header in the request that was sent
by the client (e.g., a web browser). Usually this header field contains the locale of by the client (e.g., a web browser). Usually this header field contains the locale of
the client's operating system. __Note that this resolver does not support time zone the client's operating system. __Note that this resolver does not support time zone
information.__ information.__
[[mvc-localeresolver-cookie]] [[mvc-localeresolver-cookie]]
==== Cookie resolver ==== Cookie resolver
@ -710,7 +719,6 @@ maximum age. Find below an example of defining a `CookieLocaleResolver`.
|=== |===
[[mvc-localeresolver-session]] [[mvc-localeresolver-session]]
==== Session resolver ==== Session resolver
@ -725,7 +733,6 @@ such as the Spring Session project. This `SessionLocaleResolver` will simply eva
modify corresponding `HttpSession` attributes against the current `HttpServletRequest`. modify corresponding `HttpSession` attributes against the current `HttpServletRequest`.
[[mvc-localeresolver-interceptor]] [[mvc-localeresolver-interceptor]]
==== Locale interceptor ==== Locale interceptor
@ -763,7 +770,6 @@ change the site language to Dutch.
[[mvc-themeresolver]] [[mvc-themeresolver]]
=== Themes === Themes
@ -775,6 +781,7 @@ application.
[[mvc-themeresolver-defining]] [[mvc-themeresolver-defining]]
==== Define a theme ==== Define a theme
To use themes in your web application, you must set up an implementation of the To use themes in your web application, you must set up an implementation of the
`org.springframework.ui.context.ThemeSource` interface. The `WebApplicationContext` `org.springframework.ui.context.ThemeSource` interface. The `WebApplicationContext`
interface extends `ThemeSource` but delegates its responsibilities to a dedicated interface extends `ThemeSource` but delegates its responsibilities to a dedicated
@ -823,9 +830,9 @@ example, we could have a `/WEB-INF/classes/cool_nl.properties` that references a
background image with Dutch text on it. background image with Dutch text on it.
[[mvc-themeresolver-resolving]] [[mvc-themeresolver-resolving]]
==== Resolve themes ==== Resolve themes
After you define themes, as in the preceding section, you decide which theme to use. The After you define themes, as in the preceding section, you decide which theme to use. The
`DispatcherServlet` will look for a bean named `themeResolver` to find out which `DispatcherServlet` will look for a bean named `themeResolver` to find out which
`ThemeResolver` implementation to use. A theme resolver works in much the same way as a `ThemeResolver` implementation to use. A theme resolver works in much the same way as a
@ -853,6 +860,7 @@ Spring also provides a `ThemeChangeInterceptor` that allows theme changes on eve
request with a simple request parameter. request with a simple request parameter.
[[mvc-multipart]] [[mvc-multipart]]
=== Multipart requests === Multipart requests
@ -871,7 +879,6 @@ your context is used. After that, the multipart attribute in your request is tre
like any other attribute. like any other attribute.
[[mvc-multipart-resolver-commons]] [[mvc-multipart-resolver-commons]]
==== __Commons FileUpload__ ==== __Commons FileUpload__
@ -902,11 +909,16 @@ Once Servlet 3.0 multipart parsing has been enabled in one of the above mentione
you can add a bean of type `StandardServletMultipartResolver` and with the name you can add a bean of type `StandardServletMultipartResolver` and with the name
`multipartResolver` to your Spring configuration. `multipartResolver` to your Spring configuration.
[[filters]] [[filters]]
== Filters == Filters
The `spring-web` module provides some useful filters. The `spring-web` module provides some useful filters.
[[filters-http-put]] [[filters-http-put]]
=== HTTP PUT Form === HTTP PUT Form
@ -920,6 +932,7 @@ the body of the request, and wraps the `ServletRequest` in order to make the for
available through the `ServletRequest.getParameter{asterisk}()` family of methods. available through the `ServletRequest.getParameter{asterisk}()` family of methods.
[[filters-forwarded-headers]] [[filters-forwarded-headers]]
=== Forwarded Headers === Forwarded Headers
@ -947,6 +960,7 @@ Applications that don't have a proxy and don't need to use forwarded headers can
configure the `ForwardedHeaderFilter` to remove and ignore such headers. configure the `ForwardedHeaderFilter` to remove and ignore such headers.
[[filters-shallow-etag]] [[filters-shallow-etag]]
=== Shallow ETag === Shallow ETag
@ -957,6 +971,7 @@ response and computing the ETag value at the end.
See <<mvc-httpcaching-shallowetag>> for more details. See <<mvc-httpcaching-shallowetag>> for more details.
[[filters-cors]] [[filters-cors]]
=== CORS === CORS
@ -968,6 +983,7 @@ See the section on <<mvc-cors>> and the <<mvc-cors-filter,CorsFilter>> for more
[[mvc-controller]] [[mvc-controller]]
== Annotated Controllers == Annotated Controllers
[.small]#<<web-reactive.adoc#webflux-controller,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-controller,Same in Spring WebFlux>>#
@ -1206,7 +1222,6 @@ the `PathMatcher` implementation used can be customized. See <<mvc-config-path-m
in the configuration section. in the configuration section.
[[mvc-ann-requestmapping-suffix-pattern-match]] [[mvc-ann-requestmapping-suffix-pattern-match]]
==== Suffix match ==== Suffix match
@ -1259,6 +1274,7 @@ recommendations related to RFD.
[[mvc-ann-matrix-variables]] [[mvc-ann-matrix-variables]]
==== Matrix variables ==== Matrix variables
The URI specification http://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] defines The URI specification http://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] defines
the possibility of including name-value pairs within path segments. There is no specific the possibility of including name-value pairs within path segments. There is no specific
term used in the spec. The general "URI path parameters" could be applied although the term used in the spec. The general "URI path parameters" could be applied although the
@ -1288,7 +1304,6 @@ Below is an example of extracting the matrix variable "q":
// petId == 42 // petId == 42
// q == 11 // q == 11
} }
---- ----
@ -1307,7 +1322,6 @@ specific to identify where the variable is expected to be:
// q1 == 11 // q1 == 11
// q2 == 22 // q2 == 22
} }
---- ----
@ -1322,7 +1336,6 @@ A matrix variable may be defined as optional and a default value specified:
public void findPet(@MatrixVariable(required=false, defaultValue="1") int q) { public void findPet(@MatrixVariable(required=false, defaultValue="1") int q) {
// q == 1 // q == 1
} }
---- ----
@ -1340,7 +1353,6 @@ All matrix variables may be obtained in a Map:
// matrixVars: ["q" : [11,22], "r" : 12, "s" : 23] // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
// petMatrixVars: ["q" : 22, "s" : 23] // petMatrixVars: ["q" : 22, "s" : 23]
} }
---- ----
@ -1511,6 +1523,7 @@ is not necessary in the common case.
`@RequestMapping` handler methods have a flexible signature and can choose from a range of `@RequestMapping` handler methods have a flexible signature and can choose from a range of
supported controller method arguments and return values. supported controller method arguments and return values.
[[mvc-ann-arguments]] [[mvc-ann-arguments]]
==== Method Arguments ==== Method Arguments
[.small]#<<web-reactive.adoc#webflux-ann-arguments,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-ann-arguments,Same in Spring WebFlux>>#
@ -1518,7 +1531,7 @@ supported controller method arguments and return values.
The table below shows supported controller method arguments. Reactive types are not supported The table below shows supported controller method arguments. Reactive types are not supported
for any arguments. for any arguments.
JDK 1.8's `java.util.Optional` is supported as a method argument in combination with JDK 8's `java.util.Optional` is supported as a method argument in combination with
annotations that have a `required` attribute -- e.g. `@RequestParam`, `@RequestHeader`, annotations that have a `required` attribute -- e.g. `@RequestParam`, `@RequestHeader`,
etc, and is equivalent to `required=false`. etc, and is equivalent to `required=false`.
@ -1629,6 +1642,7 @@ as a result of a class-level `@SessionAttributes` declaration.
|For access to request attributes. |For access to request attributes.
|=== |===
[[mvc-ann-return-types]] [[mvc-ann-return-types]]
==== Return Values ==== Return Values
[.small]#<<web-reactive.adoc#webflux-ann-return-types,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-ann-return-types,Same in Spring WebFlux>>#
@ -1758,6 +1772,7 @@ parameters.
[[mvc-ann-typeconversion]] [[mvc-ann-typeconversion]]
==== Type Conversion ==== Type Conversion
String-based values extracted from the request including request parameters, path String-based values extracted from the request including request parameters, path
variables, request headers, and cookie values may need to be converted to the target variables, request headers, and cookie values may need to be converted to the target
type of the method parameter or field (e.g., binding a request parameter to a field in type of the method parameter or field (e.g., binding a request parameter to a field in
@ -1770,6 +1785,7 @@ the `FormattingConversionService`, see <<core.adoc#format, Spring Field Formatti
[[mvc-ann-requestheader]] [[mvc-ann-requestheader]]
==== @RequestHeader ==== @RequestHeader
The `@RequestHeader` annotation allows a method parameter to be bound to a request header. The `@RequestHeader` annotation allows a method parameter to be bound to a request header.
Here is a sample request header: Here is a sample request header:
@ -1805,7 +1821,6 @@ When an `@RequestHeader` annotation is used on a `Map<String, String>`,
`MultiValueMap<String, String>`, or `HttpHeaders` argument, the map is populated `MultiValueMap<String, String>`, or `HttpHeaders` argument, the map is populated
with all header values. with all header values.
[TIP] [TIP]
==== ====
Built-in support is available for converting a comma-separated string into an Built-in support is available for converting a comma-separated string into an
@ -1815,7 +1830,6 @@ example a method parameter annotated with `@RequestHeader("Accept")` may be of t
==== ====
[[mvc-ann-cookievalue]] [[mvc-ann-cookievalue]]
==== @CookieValue ==== @CookieValue
@ -1995,6 +2009,7 @@ See <<core.adoc#validation-beanvalidation, Bean validation>> and
[[mvc-multipart-forms]] [[mvc-multipart-forms]]
==== File upload ==== File upload
After the `MultipartResolver` completes its job, the request is processed like any After the `MultipartResolver` completes its job, the request is processed like any
other. First, create a form with a file input that will allow the user to upload a form. other. First, create a form with a file input that will allow the user to upload a form.
The encoding attribute ( `enctype="multipart/form-data"`) lets the browser know how to The encoding attribute ( `enctype="multipart/form-data"`) lets the browser know how to
@ -2178,9 +2193,9 @@ other redirect attributes, flash attributes are saved in the HTTP session (and h
not appear in the URL). See <<mvc-flash-attributes>> for more information. not appear in the URL). See <<mvc-flash-attributes>> for more information.
[[mvc-flash-attributes]] [[mvc-flash-attributes]]
==== Flash attributes ==== Flash attributes
Flash attributes provide a way for one request to store attributes intended for use in Flash attributes provide a way for one request to store attributes intended for use in
another. This is most commonly needed when redirecting -- for example, the another. This is most commonly needed when redirecting -- for example, the
__Post/Redirect/Get__ pattern. Flash attributes are saved temporarily before the __Post/Redirect/Get__ pattern. Flash attributes are saved temporarily before the
@ -2226,6 +2241,7 @@ Therefore the use of flash attributes is recommended mainly for redirect scenari
[[mvc-multipart-forms-non-browsers]] [[mvc-multipart-forms-non-browsers]]
==== @RequestPart ==== @RequestPart
Multipart requests can also be submitted from non-browser clients in a RESTful service Multipart requests can also be submitted from non-browser clients in a RESTful service
scenario. All of the above examples and configuration apply here as well. However, scenario. All of the above examples and configuration apply here as well. However,
unlike browsers that typically submit files and simple form fields, a programmatic unlike browsers that typically submit files and simple form fields, a programmatic
@ -2284,6 +2300,7 @@ converted with the help of the `MappingJackson2HttpMessageConverter`.
[[mvc-ann-requestbody]] [[mvc-ann-requestbody]]
==== @RequestBody ==== @RequestBody
The `@RequestBody` method parameter annotation indicates that a method parameter should The `@RequestBody` method parameter annotation indicates that a method parameter should
be bound to the value of the HTTP request body. For example: be bound to the value of the HTTP request body. For example:
@ -2431,7 +2448,6 @@ converters, see the previous section and <<integration.adoc#rest-message-convers
Message Converters>>. Message Converters>>.
[[mvc-ann-jackson]] [[mvc-ann-jackson]]
==== Jackson JSON ==== Jackson JSON
@ -2538,6 +2554,7 @@ request has a query parameter named `jsonp` or `callback`. Those names can be
customized through `jsonpParameterNames` property. customized through `jsonpParameterNames` property.
[[mvc-ann-modelattrib-methods]] [[mvc-ann-modelattrib-methods]]
=== Model Methods === Model Methods
@ -2605,6 +2622,7 @@ attribute rather than as a view name. The view name is then derived based on vie
conventions instead, much like for methods returning `void` -- see <<mvc-coc-r2vnt>>. conventions instead, much like for methods returning `void` -- see <<mvc-coc-r2vnt>>.
[[mvc-ann-initbinder]] [[mvc-ann-initbinder]]
=== Binder Methods === Binder Methods
@ -2666,6 +2684,7 @@ controller-specific tweaking of the binding rules.
---- ----
[[mvc-ann-controller-advice]] [[mvc-ann-controller-advice]]
=== Controller Advice === Controller Advice
@ -2701,7 +2720,8 @@ Both `@ControllerAdvice` and `@RestControllerAdvice` can target a subset of cont
See the See the
{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[@ControllerAdvice] {api-spring-framework}/web/bind/annotation/ControllerAdvice.html[@ControllerAdvice]
Javadoc for more details. javadoc for more details.
@ -2790,6 +2810,7 @@ the original request. Note that you can also use the
==== ====
[[mvc-links-to-controllers]] [[mvc-links-to-controllers]]
=== Links to Controllers === Links to Controllers
@ -2864,6 +2885,7 @@ with a base URL and then use the instance-based "withXxx" methods. For example:
---- ----
[[mvc-links-to-controllers-from-views]] [[mvc-links-to-controllers-from-views]]
=== Links in views === Links in views
@ -2918,9 +2940,12 @@ in order to use a specific instance of `MvcUriComponentsBuilder` with a custom b
[[mvc-exceptionhandlers]] [[mvc-exceptionhandlers]]
== Exception Handling == Exception Handling
[[mvc-exceptionhandlers-overview]] [[mvc-exceptionhandlers-overview]]
=== Overview === Overview
@ -3007,6 +3032,7 @@ value converted with message converters and written to the response stream.
[[mvc-ann-rest-spring-mvc-exceptions]] [[mvc-ann-rest-spring-mvc-exceptions]]
=== Framework exceptions === Framework exceptions
Spring MVC may raise a number of exceptions while processing a request. The Spring MVC may raise a number of exceptions while processing a request. The
`SimpleMappingExceptionResolver` can easily map any exception to a default error view as `SimpleMappingExceptionResolver` can easily map any exception to a default error view as
needed. However, when working with clients that interpret responses in an automated way needed. However, when working with clients that interpret responses in an automated way
@ -3104,7 +3130,6 @@ See `ResponseEntityExceptionHandler`.
[[mvc-ann-annotated-exceptions]] [[mvc-ann-annotated-exceptions]]
=== Annotated Exception === Annotated Exception
@ -3117,6 +3142,7 @@ response accordingly. By default the `DispatcherServlet` registers the
[[mvc-ann-customer-servlet-container-error-page]] [[mvc-ann-customer-servlet-container-error-page]]
=== Container error page === Container error page
When the status of the response is set to an error status code and the body of the When the status of the response is set to an error status code and the body of the
response is empty, Servlet containers commonly render an HTML formatted error page. To response is empty, Servlet containers commonly render an HTML formatted error page. To
customize the default error page of the container, you can declare an `<error-page>` customize the default error page of the container, you can declare an `<error-page>`
@ -3172,9 +3198,13 @@ or in a JSP:
---- ----
[[mvc-ann-async]] [[mvc-ann-async]]
== Async Requests == Async Requests
[[mvc-ann-async-processing]] [[mvc-ann-async-processing]]
=== Processing === Processing
@ -3271,8 +3301,10 @@ https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-a
blog post series]. blog post series].
[[mvc-ann-async-exceptions]] [[mvc-ann-async-exceptions]]
=== Exception handling === Exception handling
What happens if a `Callable` returned from a controller method raises an What happens if a `Callable` returned from a controller method raises an
Exception while being executed? The short answer is the same as what happens Exception while being executed? The short answer is the same as what happens
when a controller method raises an exception. It goes through the regular when a controller method raises an exception. It goes through the regular
@ -3284,8 +3316,10 @@ When using a `DeferredResult` you have a choice whether to call
`setResult` or `setErrorResult` with an `Exception` instance. `setResult` or `setErrorResult` with an `Exception` instance.
[[mvc-ann-async-interception]] [[mvc-ann-async-interception]]
=== Async interceptors === Async interceptors
A `HandlerInterceptor` can also implement `AsyncHandlerInterceptor` in order A `HandlerInterceptor` can also implement `AsyncHandlerInterceptor` in order
to implement the `afterConcurrentHandlingStarted` callback, which is called to implement the `afterConcurrentHandlingStarted` callback, which is called
instead of `postHandle` and `afterCompletion` when asynchronous processing instead of `postHandle` and `afterCompletion` when asynchronous processing
@ -3304,6 +3338,8 @@ details.
When using a `Callable` you can wrap it with an instance of `WebAsyncTask` When using a `Callable` you can wrap it with an instance of `WebAsyncTask`
which also provides registration methods for timeout and completion. which also provides registration methods for timeout and completion.
[[mvc-ann-async-http-streaming]] [[mvc-ann-async-http-streaming]]
=== Streaming response === Streaming response
@ -3345,6 +3381,8 @@ Note that `ResponseBodyEmitter` can also be used as the body in a
`ResponseEntity` in order to customize the status and headers of `ResponseEntity` in order to customize the status and headers of
the response. the response.
[[mvc-ann-async-sse]] [[mvc-ann-async-sse]]
=== Server-Sent Events === Server-Sent Events
@ -3368,6 +3406,8 @@ a publish-subscribe model within a more messaging-centric architecture.
For further background on this see For further background on this see
http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the following blog post]. http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the following blog post].
[[mvc-ann-async-output-stream]] [[mvc-ann-async-output-stream]]
=== Streaming raw data === Streaming raw data
@ -3399,6 +3439,7 @@ Note that `StreamingResponseBody` can also be used as the body in a
the response. the response.
[[mvc-ann-async-reactive-types]] [[mvc-ann-async-reactive-types]]
=== Reactive return values === Reactive return values
@ -3456,8 +3497,10 @@ processing and hence does not require a thread to absorb the effect of blocking.
For asynchronous requests there are minor requirements at the Servlet container For asynchronous requests there are minor requirements at the Servlet container
level and more controls in Spring MVC configuration. level and more controls in Spring MVC configuration.
[[mvc-ann-async-configuration-servlet3]] [[mvc-ann-async-configuration-servlet3]]
==== Servlet container config ==== Servlet container config
For applications configured with a `web.xml` be sure to update to version 3.0: For applications configured with a `web.xml` be sure to update to version 3.0:
[source,xml,indent=0] [source,xml,indent=0]
@ -3519,6 +3562,7 @@ just like with `web.xml`. To simplify all this configuration, consider extending
`AbstractAnnotationConfigDispatcherServletInitializer` which automatically `AbstractAnnotationConfigDispatcherServletInitializer` which automatically
set those options and make it very easy to register `Filter` instances. set those options and make it very easy to register `Filter` instances.
[[mvc-ann-async-configuration-spring-mvc]] [[mvc-ann-async-configuration-spring-mvc]]
==== Spring MVC config ==== Spring MVC config
@ -3542,9 +3586,13 @@ the timeout value. The class constructor of `WebAsyncTask` also allows providing
`AsyncTaskExecutor`. `AsyncTaskExecutor`.
include::webmvc-cors.adoc[leveloffset=+1] include::webmvc-cors.adoc[leveloffset=+1]
[[mvc-web-security]] [[mvc-web-security]]
== Web Security == Web Security
@ -3563,6 +3611,7 @@ Another option is to use a framework dedicated to Web Security.
http://hdiv.org/[HDIV] is one such framework and integrates with Spring MVC. http://hdiv.org/[HDIV] is one such framework and integrates with Spring MVC.
[[mvc-coc-modelmap]] [[mvc-coc-modelmap]]
=== The Model ModelMap (ModelAndView) === The Model ModelMap (ModelAndView)
@ -3716,6 +3765,7 @@ that can be configured.
[[mvc-caching]] [[mvc-caching]]
== HTTP Caching == HTTP Caching
@ -3737,6 +3787,7 @@ This section describes the different choices available to configure HTTP caching
Spring Web MVC application. Spring Web MVC application.
[[mvc-caching-cachecontrol]] [[mvc-caching-cachecontrol]]
=== Cache-Control === Cache-Control
@ -3775,6 +3826,7 @@ accepted as an argument in several Spring Web MVC APIs.
.noTransform().cachePublic(); .noTransform().cachePublic();
---- ----
[[mvc-caching-static-resources]] [[mvc-caching-static-resources]]
=== Static resources === Static resources
@ -3816,6 +3868,7 @@ And in XML:
---- ----
[[mvc-caching-etag-lastmodified]] [[mvc-caching-etag-lastmodified]]
=== @Controller caching === @Controller caching
@ -3893,6 +3946,7 @@ will check that the resource has not been modified and if it has been, it will r
`HTTP 409 Precondition Failed` response to prevent concurrent modifications. `HTTP 409 Precondition Failed` response to prevent concurrent modifications.
[[mvc-httpcaching-shallowetag]] [[mvc-httpcaching-shallowetag]]
=== ETag Filter === ETag Filter
@ -3914,6 +3968,7 @@ https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3].
[[mvc-config]] [[mvc-config]]
== MVC Config == MVC Config
[.small]#<<web-reactive.adoc#webflux-config,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-config,Same in Spring WebFlux>>#
@ -3994,6 +4049,7 @@ completion feature of your IDE to discover what attributes and sub-elements are
available. available.
[[mvc-config-conversion]] [[mvc-config-conversion]]
=== Type conversion === Type conversion
[.small]#<<web-reactive.adoc#webflux-config-conversion,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-config-conversion,Same in Spring WebFlux>>#
@ -4066,6 +4122,7 @@ and the `FormattingConversionServiceFactoryBean` for more information on when to
==== ====
[[mvc-config-validation]] [[mvc-config-validation]]
=== Validation === Validation
[.small]#<<web-reactive.adoc#webflux-config-validation,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-config-validation,Same in Spring WebFlux>>#
@ -4229,6 +4286,7 @@ In XML, the same:
---- ----
[[mvc-config-message-converters]] [[mvc-config-message-converters]]
=== Message Converters === Message Converters
[.small]#<<web-reactive.adoc#webflux-config-message-codecs,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-config-message-codecs,Same in Spring WebFlux>>#
@ -4319,6 +4377,7 @@ It is also possible to do the same in XML:
---- ----
[[mvc-config-view-controller]] [[mvc-config-view-controller]]
=== View Controllers === View Controllers
@ -4352,6 +4411,7 @@ And the same in XML use the `<mvc:view-controller>` element:
---- ----
[[mvc-config-view-resolvers]] [[mvc-config-view-resolvers]]
=== View Resolvers === View Resolvers
[.small]#<<web-reactive.adoc#webflux-config-view-resolvers,Same in Spring WebFlux>># [.small]#<<web-reactive.adoc#webflux-config-view-resolvers,Same in Spring WebFlux>>#
@ -4550,6 +4610,7 @@ match to incoming URLs without versions -- e.g. `"/jquery/jquery.min.js"` to
`"/jquery/1.2.0/jquery.min.js"`. `"/jquery/1.2.0/jquery.min.js"`.
[[mvc-default-servlet-handler]] [[mvc-default-servlet-handler]]
=== Default Servlet === Default Servlet
@ -4736,7 +4797,6 @@ Note that `MyPostProcessor` needs to be declared as a bean either explicitly in
detected through a `<component scan/>` declaration. detected through a `<component scan/>` declaration.
include::webmvc-view.adoc[leveloffset=+1] include::webmvc-view.adoc[leveloffset=+1]

View File

@ -2,7 +2,6 @@
= WebSockets = WebSockets
:doc-spring-security: {doc-root}/spring-security/site/docs/current/reference :doc-spring-security: {doc-root}/spring-security/site/docs/current/reference
This part of the reference documentation covers the Spring Framework support for Servlet stack This part of the reference documentation covers the Spring Framework support for Servlet stack
based WebSocket messaging including use of STOMP as a a WebSocket sub-protocol. based WebSocket messaging including use of STOMP as a a WebSocket sub-protocol.
@ -24,8 +23,10 @@ applications.
[[websocket-intro]] [[websocket-intro]]
== Introduction == Introduction
The WebSocket protocol http://tools.ietf.org/html/rfc6455[RFC 6455] defines an important The WebSocket protocol http://tools.ietf.org/html/rfc6455[RFC 6455] defines an important
new capability for web applications: full-duplex, two-way communication between client new capability for web applications: full-duplex, two-way communication between client
and server. It is an exciting new capability on the heels of a long history of and server. It is an exciting new capability on the heels of a long history of
@ -49,6 +50,7 @@ and also provides additional value-add as explained in the rest of the introduct
[[websocket-into-fallback-options]] [[websocket-into-fallback-options]]
=== Fallback Options === Fallback Options
An important challenge to adoption is the lack of support for WebSocket in some An important challenge to adoption is the lack of support for WebSocket in some
browsers. Notably the first Internet Explorer version to support WebSocket is browsers. Notably the first Internet Explorer version to support WebSocket is
version 10 (see http://caniuse.com/websockets for support by browser versions). version 10 (see http://caniuse.com/websockets for support by browser versions).
@ -68,6 +70,7 @@ application otherwise.
[[websocket-intro-architecture]] [[websocket-intro-architecture]]
=== Messaging === Messaging
Aside from short-to-midterm adoption challenges, using WebSocket Aside from short-to-midterm adoption challenges, using WebSocket
brings up important design considerations that are important to recognize brings up important design considerations that are important to recognize
early on, especially in contrast to what we know about building web applications today. early on, especially in contrast to what we know about building web applications today.
@ -95,6 +98,7 @@ annotation based programming model.
[[websocket-intro-sub-protocol]] [[websocket-intro-sub-protocol]]
=== WebSocket Sub-Protocol === WebSocket Sub-Protocol
WebSocket does imply a __messaging architecture__ but does not mandate the WebSocket does imply a __messaging architecture__ but does not mandate the
use of any specific __messaging protocol__. It is a very thin layer over TCP use of any specific __messaging protocol__. It is a very thin layer over TCP
that transforms a stream of bytes into a stream of messages that transforms a stream of bytes into a stream of messages
@ -128,6 +132,7 @@ WebSocket and over the web.
[[websocket-intro-when-to-use]] [[websocket-intro-when-to-use]]
=== Do I Use WebSocket? === Do I Use WebSocket?
With all the design considerations surrounding the use of WebSocket, it is With all the design considerations surrounding the use of WebSocket, it is
reasonable to ask, "When is it appropriate to use?". reasonable to ask, "When is it appropriate to use?".
@ -171,6 +176,7 @@ WebSocket clients or to a specific user.
[[websocket-server]] [[websocket-server]]
== WebSocket API == WebSocket API
The Spring Framework provides a WebSocket API designed to adapt to various WebSocket engines. The Spring Framework provides a WebSocket API designed to adapt to various WebSocket engines.
Currently the list includes WebSocket runtimes such as Tomcat 7.0.47+, Jetty 9.1+, Currently the list includes WebSocket runtimes such as Tomcat 7.0.47+, Jetty 9.1+,
GlassFish 4.1+, WebLogic 12.1.3+, and Undertow 1.0+ (and WildFly 8.0+). Additional support GlassFish 4.1+, WebLogic 12.1.3+, and Undertow 1.0+ (and WildFly 8.0+). Additional support
@ -194,6 +200,7 @@ directly.
[[websocket-server-handler]] [[websocket-server-handler]]
=== WebSocketHandler === WebSocketHandler
Creating a WebSocket server is as simple as implementing `WebSocketHandler` or more Creating a WebSocket server is as simple as implementing `WebSocketHandler` or more
likely extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`: likely extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`:
@ -274,6 +281,7 @@ into other HTTP serving environments with the help of
[[websocket-server-handshake]] [[websocket-server-handshake]]
=== WebSocket Handshake === WebSocket Handshake
The easiest way to customize the initial HTTP WebSocket handshake request is through The easiest way to customize the initial HTTP WebSocket handshake request is through
a `HandshakeInterceptor`, which exposes "before" and "after" the handshake methods. a `HandshakeInterceptor`, which exposes "before" and "after" the handshake methods.
Such an interceptor can be used to preclude the handshake or to make any attributes Such an interceptor can be used to preclude the handshake or to make any attributes
@ -346,6 +354,7 @@ session with status `1011` that indicates a server error.
[[websocket-server-deployment]] [[websocket-server-deployment]]
=== Deployment === Deployment
The Spring WebSocket API is easy to integrate into a Spring MVC application where The Spring WebSocket API is easy to integrate into a Spring MVC application where
the `DispatcherServlet` serves both HTTP WebSocket handshake as well as other the `DispatcherServlet` serves both HTTP WebSocket handshake as well as other
HTTP requests. It is also easy to integrate into other HTTP processing scenarios HTTP requests. It is also easy to integrate into other HTTP processing scenarios
@ -417,6 +426,8 @@ Java initialization API, if required:
</web-app> </web-app>
---- ----
[[websocket-server-runtime-configuration]] [[websocket-server-runtime-configuration]]
=== Server config === Server config
@ -543,6 +554,8 @@ or WebSocket XML namespace:
</beans> </beans>
---- ----
[[websocket-server-allowed-origins]] [[websocket-server-allowed-origins]]
=== Allowed origins === Allowed origins
@ -615,14 +628,19 @@ XML configuration equivalent:
---- ----
[[websocket-fallback]] [[websocket-fallback]]
== SockJS Fallback == SockJS Fallback
As explained in the <<websocket-into-fallback-options,introduction>>, WebSocket is not As explained in the <<websocket-into-fallback-options,introduction>>, WebSocket is not
supported in all browsers yet and may be precluded by restrictive network proxies. supported in all browsers yet and may be precluded by restrictive network proxies.
This is why Spring provides fallback options that emulate the WebSocket API as close This is why Spring provides fallback options that emulate the WebSocket API as close
as possible based on the https://github.com/sockjs/sockjs-protocol[SockJS protocol] as possible based on the https://github.com/sockjs/sockjs-protocol[SockJS protocol]
(version 0.3.3). (version 0.3.3).
[[websocket-fallback-sockjs-overview]] [[websocket-fallback-sockjs-overview]]
=== Overview === Overview
@ -684,8 +702,10 @@ For even more detail refer to the SockJS protocol
http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated test]. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated test].
[[websocket-fallback-sockjs-enable]] [[websocket-fallback-sockjs-enable]]
=== Enable SockJS === Enable SockJS
SockJS is easy to enable through Java configuration: SockJS is easy to enable through Java configuration:
[source,java,indent=0] [source,java,indent=0]
@ -746,6 +766,8 @@ https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of
transport types supported by browser. The client also provides several transport types supported by browser. The client also provides several
configuration options, for example, to specify which transports to include. configuration options, for example, to specify which transports to include.
[[websocket-fallback-xhr-vs-iframe]] [[websocket-fallback-xhr-vs-iframe]]
=== IE 8, 9 === IE 8, 9
@ -827,6 +849,8 @@ be cached. For details on how to enable it see the
https://github.com/sockjs/sockjs-client/[SockJS client] page. https://github.com/sockjs/sockjs-client/[SockJS client] page.
==== ====
[[websocket-fallback-sockjs-heartbeat]] [[websocket-fallback-sockjs-heartbeat]]
=== Heartbeats === Heartbeats
@ -848,6 +872,8 @@ for scheduling heartbeats tasks. The task scheduler is backed by a thread pool
with default settings based on the number of available processors. Applications with default settings based on the number of available processors. Applications
should consider customizing the settings according to their specific needs. should consider customizing the settings according to their specific needs.
[[websocket-fallback-sockjs-servlet3-async]] [[websocket-fallback-sockjs-servlet3-async]]
=== Client disconnects === Client disconnects
@ -876,6 +902,8 @@ defined in `AbstractSockJsSession`. If you need to see the stack traces, set tha
log category to TRACE. log category to TRACE.
==== ====
[[websocket-fallback-cors]] [[websocket-fallback-cors]]
=== SockJS and CORS === SockJS and CORS
@ -903,6 +931,7 @@ Alternatively if the CORS configuration allows it consider excluding URLs with t
SockJS endpoint prefix thus letting Spring's `SockJsService` handle it. SockJS endpoint prefix thus letting Spring's `SockJsService` handle it.
[[websocket-fallback-sockjs-client]] [[websocket-fallback-sockjs-client]]
=== SockJsClient === SockJsClient
@ -986,6 +1015,7 @@ public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport
[[websocket-stomp]] [[websocket-stomp]]
== STOMP == STOMP
The WebSocket protocol defines two types of messages, text and binary, but their The WebSocket protocol defines two types of messages, text and binary, but their
content is undefined. It's expected that the client and server may agree on using content is undefined. It's expected that the client and server may agree on using
a sub-protocol (i.e. a higher-level protocol) to define message semantics. a sub-protocol (i.e. a higher-level protocol) to define message semantics.
@ -997,6 +1027,7 @@ messages.
[[websocket-stomp-overview]] [[websocket-stomp-overview]]
=== Overview === Overview
http://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP] is a simple http://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP] is a simple
text-oriented messaging protocol that was originally created for scripting languages text-oriented messaging protocol that was originally created for scripting languages
such as Ruby, Python, and Perl to connect to enterprise message brokers. It is such as Ruby, Python, and Perl to connect to enterprise message brokers. It is
@ -1102,6 +1133,7 @@ Spring MVC provides a programming model based on HTTP.
[[websocket-stomp-enable]] [[websocket-stomp-enable]]
=== Enable STOMP === Enable STOMP
The Spring Framework provides support for using STOMP over WebSocket through The Spring Framework provides support for using STOMP over WebSocket through
the +spring-messaging+ and +spring-websocket+ modules. the +spring-messaging+ and +spring-websocket+ modules.
Here is an example of exposing a STOMP WebSocket/SockJS endpoint at the URL path Here is an example of exposing a STOMP WebSocket/SockJS endpoint at the URL path
@ -1207,6 +1239,7 @@ sections <<websocket-stomp-handle-broker-relay-configure>> and
<<websocket-stomp-authentication>> for more information on authentication. <<websocket-stomp-authentication>> for more information on authentication.
[[websocket-stomp-message-flow]] [[websocket-stomp-message-flow]]
=== Flow of Messages === Flow of Messages
@ -1430,6 +1463,7 @@ But it can also be qualified by its name "brokerMessagingTemplate" if another
bean of the same type exists. bean of the same type exists.
[[websocket-stomp-handle-simple-broker]] [[websocket-stomp-handle-simple-broker]]
=== Simple Broker === Simple Broker
@ -1446,7 +1480,6 @@ See <<websocket-stomp-destination-separator>>.
[[websocket-stomp-handle-broker-relay]] [[websocket-stomp-handle-broker-relay]]
=== External Broker === External Broker
@ -1529,6 +1562,8 @@ subscribed WebSocket clients.
In effect, the broker relay enables robust and scalable message broadcasting. In effect, the broker relay enables robust and scalable message broadcasting.
[[websocket-stomp-handle-broker-relay-configure]] [[websocket-stomp-handle-broker-relay-configure]]
=== Connect to Broker === Connect to Broker
@ -1574,6 +1609,8 @@ and may be useful for example in a cloud environment where the actual host to wh
the TCP connection is established is different from the host providing the the TCP connection is established is different from the host providing the
cloud-based STOMP service. cloud-based STOMP service.
[[websocket-stomp-destination-separator]] [[websocket-stomp-destination-separator]]
=== Dot as Separator === Dot as Separator
@ -1649,7 +1686,6 @@ If the application prefix is set to "/app" then the foo method is effectively ma
[[websocket-stomp-authentication]] [[websocket-stomp-authentication]]
=== Authentication === Authentication
@ -1776,7 +1812,6 @@ its own sub-class of `AbstractWebSocketMessageBrokerConfigurer` marked with
[[websocket-stomp-user-destination]] [[websocket-stomp-user-destination]]
=== User Destinations === User Destinations
@ -1900,7 +1935,6 @@ of the `message-broker` element in XML.
[[websocket-stomp-appplication-context-events]] [[websocket-stomp-appplication-context-events]]
=== Events and Interception === Events and Interception
@ -1980,6 +2014,7 @@ to access information about the message.
---- ----
[[websocket-stomp-client]] [[websocket-stomp-client]]
=== STOMP Client === STOMP Client
@ -2380,6 +2415,8 @@ SockJS Task Scheduler:: stats from thread pool of the SockJS task scheduler whic
is used to send heartbeats. Note that when heartbeats are negotiated on the is used to send heartbeats. Note that when heartbeats are negotiated on the
STOMP level the SockJS heartbeats are disabled. STOMP level the SockJS heartbeats are disabled.
[[websocket-stomp-testing]] [[websocket-stomp-testing]]
=== Testing === Testing