Consistent separation between chapters and after chapter titles
This commit is contained in:
parent
9df6f3e6b8
commit
a3eeda99e0
|
@ -2,28 +2,33 @@
|
|||
= Spring AOP APIs
|
||||
|
||||
|
||||
|
||||
|
||||
[[aop-api-introduction]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
in Spring 4.0.
|
||||
in Spring 5.
|
||||
|
||||
|
||||
|
||||
|
||||
[[aop-api-pointcuts]]
|
||||
== Pointcut API in Spring
|
||||
|
||||
Let's look at how Spring handles the crucial pointcut concept.
|
||||
|
||||
|
||||
|
||||
[[aop-api-concepts]]
|
||||
=== Concepts
|
||||
|
||||
Spring's pointcut model enables pointcut reuse independent of advice types. It's
|
||||
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]
|
||||
====
|
||||
|
||||
If possible, try to make pointcuts static, allowing the AOP framework to cache the
|
||||
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]]
|
||||
=== Operations on pointcuts
|
||||
|
||||
Spring supports operations on pointcuts: notably, __union__ and __intersection__.
|
||||
|
||||
* 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]]
|
||||
=== AspectJ expression pointcuts
|
||||
|
||||
Since 2.0, the most important type of pointcut used by Spring is
|
||||
`org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that
|
||||
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]]
|
||||
=== Convenience pointcut implementations
|
||||
|
||||
Spring provides several convenient pointcut implementations. Some can be used out of the
|
||||
box; others are intended to be subclassed in application-specific pointcuts.
|
||||
|
||||
|
||||
[[aop-api-pointcuts-static]]
|
||||
==== Static pointcuts
|
||||
|
||||
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.
|
||||
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]]
|
||||
===== Regular expression pointcuts
|
||||
|
||||
One obvious way to specify static pointcuts is regular expressions. Several AOP
|
||||
frameworks besides Spring make this possible.
|
||||
`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
|
||||
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]]
|
||||
===== Attribute-driven pointcuts
|
||||
|
||||
An important type of static pointcut is a __metadata-driven__ pointcut. This uses the
|
||||
values of metadata attributes: typically, source-level metadata.
|
||||
|
||||
|
||||
[[aop-api-pointcuts-dynamic]]
|
||||
==== Dynamic pointcuts
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Control flow 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
|
||||
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
|
||||
in the `com.mycompany.web` package, or by the `SomeCaller` class. Control flow pointcuts
|
||||
are specified using the `org.springframework.aop.support.ControlFlowPointcut` class.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Control flow pointcuts are significantly more expensive to evaluate at runtime than even
|
||||
|
@ -221,6 +234,7 @@ pointcuts.
|
|||
|
||||
[[aop-api-pointcuts-superclasses]]
|
||||
=== Pointcut superclasses
|
||||
|
||||
Spring provides useful pointcut superclasses to help you to implement your own pointcuts.
|
||||
|
||||
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]]
|
||||
=== Custom pointcuts
|
||||
|
||||
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
|
||||
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]]
|
||||
== Advice API in Spring
|
||||
|
||||
Let's now look at how Spring AOP handles advice.
|
||||
|
||||
|
||||
|
||||
[[aop-api-advice-lifecycle]]
|
||||
=== Advice lifecycles
|
||||
|
||||
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
|
||||
__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]]
|
||||
=== Advice types in Spring
|
||||
|
||||
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.
|
||||
|
||||
|
||||
[[aop-api-advice-around]]
|
||||
==== 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
|
||||
|
@ -347,6 +366,7 @@ currently define pointcut interfaces.
|
|||
|
||||
[[aop-api-advice-before]]
|
||||
==== Before advice
|
||||
|
||||
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.
|
||||
|
||||
|
@ -395,13 +415,13 @@ An example of a before advice in Spring, which counts all method invocations:
|
|||
|
||||
[TIP]
|
||||
====
|
||||
|
||||
Before advice can be used with any pointcut.
|
||||
====
|
||||
|
||||
|
||||
[[aop-api-advice-throws]]
|
||||
==== Throws advice
|
||||
|
||||
__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
|
||||
`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]
|
||||
====
|
||||
|
||||
Throws advice can be used with any pointcut.
|
||||
====
|
||||
|
||||
|
||||
[[aop-api-advice-after-returning]]
|
||||
==== After Returning advice
|
||||
|
||||
An after returning advice in Spring must implement the
|
||||
__org.springframework.aop.AfterReturningAdvice__ interface, shown below:
|
||||
|
||||
|
@ -527,13 +547,13 @@ thrown up the interceptor chain instead of the return value.
|
|||
|
||||
[TIP]
|
||||
====
|
||||
|
||||
After returning advice can be used with any pointcut.
|
||||
====
|
||||
|
||||
|
||||
[[aop-api-advice-introduction]]
|
||||
==== Introduction advice
|
||||
|
||||
Spring treats introduction advice as a special kind of interception advice.
|
||||
|
||||
Introduction requires an `IntroductionAdvisor`, and an `IntroductionInterceptor`,
|
||||
|
@ -696,6 +716,7 @@ and stateful mixins.
|
|||
|
||||
[[aop-api-advisor]]
|
||||
== Advisor API in Spring
|
||||
|
||||
In Spring, an Advisor is an aspect that contains just a single advice object associated
|
||||
with a pointcut expression.
|
||||
|
||||
|
@ -714,6 +735,7 @@ chain.
|
|||
|
||||
[[aop-pfb]]
|
||||
== Using the ProxyFactoryBean to create AOP proxies
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Basics
|
||||
|
||||
The `ProxyFactoryBean`, like other Spring `FactoryBean` implementations, introduces a
|
||||
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
|
||||
|
@ -750,6 +773,7 @@ framework), benefiting from all the pluggability provided by Dependency Injectio
|
|||
|
||||
[[aop-pfb-2]]
|
||||
=== JavaBean properties
|
||||
|
||||
In common with most `FactoryBean` implementations provided with Spring, the
|
||||
`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]]
|
||||
=== JDK- and CGLIB-based proxies
|
||||
|
||||
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
|
||||
object (that is to be proxied).
|
||||
|
@ -855,6 +880,7 @@ it is significantly less work, and less prone to typos.
|
|||
|
||||
[[aop-api-proxying-intf]]
|
||||
=== Proxying interfaces
|
||||
|
||||
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
|
||||
|
@ -972,6 +998,7 @@ factory might actually be an __advantage__: for example, in certain test scenari
|
|||
|
||||
[[aop-api-proxying-class]]
|
||||
=== Proxying classes
|
||||
|
||||
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
|
||||
|
@ -1006,6 +1033,7 @@ Performance should not be a decisive consideration in this case.
|
|||
|
||||
[[aop-global-advisors]]
|
||||
=== Using 'global' advisors
|
||||
|
||||
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
|
||||
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]]
|
||||
== Concise proxy definitions
|
||||
|
||||
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, can result in much cleaner and more concise proxy definitions.
|
||||
|
@ -1103,6 +1132,7 @@ pre-instantiate it.
|
|||
|
||||
[[aop-prog]]
|
||||
== Creating AOP proxies programmatically with the ProxyFactory
|
||||
|
||||
It's easy to create AOP proxies programmatically using Spring. This enables you to use
|
||||
Spring AOP without dependency on Spring IoC.
|
||||
|
||||
|
@ -1135,7 +1165,6 @@ AdvisedSupport is the superclass of both ProxyFactory and ProxyFactoryBean.
|
|||
|
||||
[TIP]
|
||||
====
|
||||
|
||||
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,
|
||||
as in general.
|
||||
|
@ -1146,6 +1175,7 @@ as in general.
|
|||
|
||||
[[aop-api-advised]]
|
||||
== Manipulating advised objects
|
||||
|
||||
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
|
||||
interface, whichever other interfaces it implements. This interface includes the
|
||||
|
@ -1238,6 +1268,7 @@ required.
|
|||
|
||||
[[aop-autoproxy]]
|
||||
== Using the "auto-proxy" facility
|
||||
|
||||
So far we've considered explicit creation of AOP proxies using a `ProxyFactoryBean` or
|
||||
similar factory bean.
|
||||
|
||||
|
@ -1259,12 +1290,14 @@ There are two ways to do this:
|
|||
|
||||
[[aop-autoproxy-choices]]
|
||||
=== Autoproxy bean definitions
|
||||
|
||||
The `org.springframework.aop.framework.autoproxy` package provides the following
|
||||
standard auto-proxy creators.
|
||||
|
||||
|
||||
[[aop-api-autoproxy]]
|
||||
==== BeanNameAutoProxyCreator
|
||||
|
||||
The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates
|
||||
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]]
|
||||
==== DefaultAdvisorAutoProxyCreator
|
||||
|
||||
A more general and extremely powerful auto proxy creator is
|
||||
`DefaultAdvisorAutoProxyCreator`. This will automagically apply eligible advisors in the
|
||||
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.
|
||||
|
||||
|
||||
[[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]]
|
||||
== Using TargetSources
|
||||
|
||||
Spring offers the concept of a __TargetSource__, expressed in the
|
||||
`org.springframework.aop.TargetSource` interface. This interface is responsible for
|
||||
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]
|
||||
====
|
||||
|
||||
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
|
||||
instance when required.
|
||||
|
@ -1528,6 +1425,7 @@ instance when required.
|
|||
|
||||
[[aop-ts-swap]]
|
||||
=== Hot swappable target sources
|
||||
|
||||
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.
|
||||
|
||||
|
@ -1571,6 +1469,7 @@ arbitrary advice.
|
|||
|
||||
[[aop-ts-pool]]
|
||||
=== Pooling target sources
|
||||
|
||||
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
|
||||
going to free objects in the pool.
|
||||
|
@ -1665,6 +1564,7 @@ used by any auto-proxy creator.
|
|||
|
||||
[[aop-ts-prototype]]
|
||||
=== Prototype target sources
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
|
@ -2,8 +2,11 @@
|
|||
= Aspect Oriented Programming with Spring
|
||||
|
||||
|
||||
|
||||
|
||||
[[aop-introduction]]
|
||||
== Introduction
|
||||
|
||||
__Aspect-Oriented Programming__ (AOP) complements Object-Oriented Programming (OOP) by
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
style>>. Both of these styles offer fully typed advice and use of the AspectJ pointcut
|
||||
language, while still using Spring AOP for weaving.
|
||||
|
||||
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
|
||||
lower-level AOP support offered by the Spring 1.2 APIs is discussed in <<aop-api,the
|
||||
following chapter>>.
|
||||
The Spring 2.0+ schema- and @AspectJ-based AOP support is discussed in this chapter.
|
||||
The lower-level AOP support, as commonly exposed in Spring 1.2 applications, is
|
||||
discussed in <<aop-api,the following chapter>>.
|
||||
****
|
||||
|
||||
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 concepts
|
||||
|
||||
Let us begin by defining some central AOP concepts and terminology. These terms are not
|
||||
Spring-specific... unfortunately, AOP terminology is not particularly intuitive;
|
||||
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]]
|
||||
=== Spring AOP capabilities and goals
|
||||
|
||||
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
|
||||
suitable for use in a Servlet container or application server.
|
||||
|
@ -182,6 +186,7 @@ style.
|
|||
|
||||
[[aop-introduction-proxies]]
|
||||
=== AOP Proxies
|
||||
|
||||
Spring AOP defaults to using standard JDK __dynamic proxies__ for AOP proxies. This
|
||||
enables any interface (or set of interfaces) to be proxied.
|
||||
|
||||
|
@ -202,6 +207,7 @@ implementation detail actually means.
|
|||
|
||||
[[aop-ataspectj]]
|
||||
== @AspectJ support
|
||||
|
||||
@AspectJ refers to a style of declaring aspects as regular Java classes annotated with
|
||||
annotations. The @AspectJ style was introduced by the
|
||||
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]]
|
||||
=== Enabling @AspectJ Support
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Enabling @AspectJ Support with Java configuration
|
||||
|
||||
To enable @AspectJ support with Java `@Configuration` add the `@EnableAspectJAutoProxy`
|
||||
annotation:
|
||||
|
||||
|
@ -250,6 +258,7 @@ annotation:
|
|||
|
||||
[[aop-enable-aspectj-xml]]
|
||||
==== Enabling @AspectJ Support with XML configuration
|
||||
|
||||
To enable @AspectJ support with XML based configuration use the `aop:aspectj-autoproxy`
|
||||
element:
|
||||
|
||||
|
@ -327,6 +336,7 @@ hence excludes it from auto-proxying.
|
|||
|
||||
[[aop-pointcuts]]
|
||||
=== Declaring a pointcut
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Supported Pointcut Designators
|
||||
|
||||
Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut
|
||||
expressions:
|
||||
|
||||
|
@ -456,6 +467,7 @@ it is natural and straightforward to identify specific beans by name.
|
|||
|
||||
[[aop-pointcuts-combining]]
|
||||
==== Combining pointcut expressions
|
||||
|
||||
Pointcut expressions can be combined using '&&', '||' and '!'. It is also possible to
|
||||
refer to pointcut expressions by name. The following example shows three pointcut
|
||||
expressions: `anyPublicOperation` (which matches if a method execution join point
|
||||
|
@ -485,6 +497,7 @@ __matching__.
|
|||
|
||||
[[aop-common-pointcuts]]
|
||||
==== Sharing common pointcut definitions
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Examples
|
||||
|
||||
Spring AOP users are likely to use the `execution` pointcut designator the most often.
|
||||
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
|
||||
|
||||
During compilation, AspectJ processes pointcuts in order to try and optimize matching
|
||||
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
|
||||
|
@ -832,6 +847,7 @@ pointcut should always include one if possible.
|
|||
|
||||
[[aop-advice]]
|
||||
=== Declaring advice
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Before advice
|
||||
|
||||
Before advice is declared in an aspect using the `@Before` annotation:
|
||||
|
||||
[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]]
|
||||
==== After returning advice
|
||||
|
||||
After returning advice runs when a matched method execution returns normally. It is
|
||||
declared using the `@AfterReturning` annotation:
|
||||
|
||||
|
@ -941,6 +959,7 @@ using after-returning advice.
|
|||
|
||||
[[aop-advice-after-throwing]]
|
||||
==== After throwing advice
|
||||
|
||||
After throwing advice runs when a matched method execution exits by throwing an
|
||||
exception. It is declared using the `@AfterThrowing` annotation:
|
||||
|
||||
|
@ -994,6 +1013,7 @@ of the specified type ( `DataAccessException` in this case).
|
|||
|
||||
[[aop-advice-after-finally]]
|
||||
==== After (finally) advice
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Around advice
|
||||
|
||||
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,
|
||||
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]]
|
||||
==== Advice parameters
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Passing parameters to advice
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Advice parameters and generics
|
||||
|
||||
Spring AOP can handle generics used in class declarations and method parameters. Suppose
|
||||
you have a generic type like this:
|
||||
|
||||
|
@ -1218,6 +1242,7 @@ check the type of the elements.
|
|||
|
||||
[[aop-ataspectj-advice-params-names]]
|
||||
===== Determining argument names
|
||||
|
||||
The parameter binding in advice invocations relies on matching names used in pointcut
|
||||
expressions to declared parameter names in (advice and pointcut) method signatures.
|
||||
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]]
|
||||
===== Proceeding with arguments
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Advice ordering
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Introductions
|
||||
|
||||
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 interface on behalf of those objects.
|
||||
|
@ -1389,6 +1417,7 @@ you would write the following:
|
|||
|
||||
[[aop-instantiation-models]]
|
||||
=== Aspect instantiation models
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
(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]]
|
||||
=== Example
|
||||
|
||||
Now that you have seen how all the constituent parts work, let's put them together to do
|
||||
something useful!
|
||||
|
||||
|
@ -1546,6 +1576,7 @@ expression so that only `@Idempotent` operations match:
|
|||
|
||||
[[aop-schema]]
|
||||
== Schema-based AOP support
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Declaring an aspect
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Declaring a pointcut
|
||||
|
||||
A named pointcut can be declared inside an <aop:config> element, enabling the pointcut
|
||||
definition to be shared across several aspects and advisors.
|
||||
|
||||
|
@ -1724,12 +1757,14 @@ style.
|
|||
|
||||
[[aop-schema-advice]]
|
||||
=== Declaring advice
|
||||
|
||||
The same five advice kinds are supported as for the @AspectJ style, and they have
|
||||
exactly the same semantics.
|
||||
|
||||
|
||||
[[aop-schema-advice-before]]
|
||||
==== Before advice
|
||||
|
||||
Before advice runs before a matched method execution. It is declared inside an
|
||||
`<aop:aspect>` using the <aop:before> element.
|
||||
|
||||
|
@ -1777,6 +1812,7 @@ bean will be invoked.
|
|||
|
||||
[[aop-schema-advice-after-returning]]
|
||||
==== After returning advice
|
||||
|
||||
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:
|
||||
|
||||
|
@ -1826,6 +1862,7 @@ example, the method signature may be declared as:
|
|||
|
||||
[[aop-schema-advice-after-throwing]]
|
||||
==== After throwing advice
|
||||
|
||||
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:
|
||||
|
||||
|
@ -1875,6 +1912,7 @@ example, the method signature may be declared as:
|
|||
|
||||
[[aop-schema-advice-after-finally]]
|
||||
==== After (finally) advice
|
||||
|
||||
After (finally) advice runs however a matched method execution exits. It is declared
|
||||
using the `after` element:
|
||||
|
||||
|
@ -1895,6 +1933,7 @@ using the `after` element:
|
|||
|
||||
[[aop-schema-advice-around]]
|
||||
==== Around advice
|
||||
|
||||
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,
|
||||
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]]
|
||||
==== Advice parameters
|
||||
|
||||
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
|
||||
advice method parameters. See <<aop-ataspectj-advice-params>> for details. If you wish
|
||||
|
@ -2078,6 +2118,7 @@ ms % Task name
|
|||
|
||||
[[aop-ordering]]
|
||||
==== Advice ordering
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Introductions
|
||||
|
||||
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 interface on behalf of those objects.
|
||||
|
@ -2143,6 +2185,7 @@ following:
|
|||
|
||||
[[aop-schema-instatiation-models]]
|
||||
=== Aspect instantiation models
|
||||
|
||||
The only supported instantiation model for schema-defined aspects is the singleton
|
||||
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]]
|
||||
=== 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
|
||||
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
|
||||
|
@ -2192,6 +2236,7 @@ use the `order` attribute to define the `Ordered` value of the advisor.
|
|||
|
||||
[[aop-schema-example]]
|
||||
=== Example
|
||||
|
||||
Let's see how the concurrent locking failure retry example from
|
||||
<<aop-ataspectj-example>> looks when rewritten using the schema support.
|
||||
|
||||
|
@ -2318,6 +2363,7 @@ pointcut expression so that only `@Idempotent` operations match:
|
|||
|
||||
[[aop-choosing]]
|
||||
== Choosing which AOP declaration style to use
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Spring AOP or full AspectJ?
|
||||
|
||||
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
|
||||
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]]
|
||||
=== @AspectJ or XML for Spring AOP?
|
||||
|
||||
If you have chosen to use Spring AOP, then you have a choice of @AspectJ or XML style.
|
||||
There are various tradeoffs to consider.
|
||||
|
||||
|
@ -2413,6 +2461,7 @@ that do more than simple "configuration" of enterprise services.
|
|||
|
||||
[[aop-mixing-styles]]
|
||||
== Mixing aspect types
|
||||
|
||||
It is perfectly possible to mix @AspectJ style aspects using the autoproxying support,
|
||||
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.
|
||||
|
@ -2424,6 +2473,7 @@ co-exist without any difficulty.
|
|||
|
||||
[[aop-proxying]]
|
||||
== Proxying mechanisms
|
||||
|
||||
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).
|
||||
|
||||
|
@ -2483,6 +2533,7 @@ proxies __for all three of them__.
|
|||
|
||||
[[aop-understanding-aop-proxies]]
|
||||
=== Understanding AOP proxies
|
||||
|
||||
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
|
||||
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]]
|
||||
== Programmatic creation of @AspectJ Proxies
|
||||
|
||||
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
|
||||
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]]
|
||||
== Using AspectJ with Spring applications
|
||||
|
||||
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
|
||||
addition to, Spring AOP if your needs go beyond the facilities offered by Spring AOP
|
||||
|
@ -2667,6 +2720,7 @@ using AspectJ.
|
|||
|
||||
[[aop-atconfigurable]]
|
||||
=== Using AspectJ to dependency inject domain objects with Spring
|
||||
|
||||
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__
|
||||
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]]
|
||||
==== Working with multiple application contexts
|
||||
|
||||
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
|
||||
`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]]
|
||||
=== Other Spring aspects for 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
|
||||
annotated with the `@Transactional` annotation. This is primarily intended for users who
|
||||
|
@ -2934,6 +2990,7 @@ fully-qualified class names:
|
|||
|
||||
[[aop-aj-configure]]
|
||||
=== Configuring AspectJ aspects using Spring IoC
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Load-time weaving with AspectJ in the Spring Framework
|
||||
|
||||
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).
|
||||
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]]
|
||||
==== A first example
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Aspects
|
||||
|
||||
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.
|
||||
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]]
|
||||
==== Required libraries (JARS)
|
||||
|
||||
At a minimum you will need the following libraries to use the Spring Framework's support
|
||||
for AspectJ LTW:
|
||||
|
||||
|
@ -3272,6 +3333,7 @@ instrumentation>>, you will also need:
|
|||
|
||||
[[aop-aj-ltw-spring]]
|
||||
==== Spring configuration
|
||||
|
||||
The key component in Spring's LTW support is the `LoadTimeWeaver` interface (in the
|
||||
`org.springframework.instrument.classloading` package), and the numerous implementations
|
||||
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]
|
||||
====
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Environment-specific configuration
|
||||
|
||||
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
|
||||
containers.
|
||||
|
||||
[[aop-aj-ltw-environment-tomcat]]
|
||||
===== Tomcat
|
||||
|
||||
Historically, http://tomcat.apache.org/[Apache Tomcat]'s default class loader did not
|
||||
support class transformation which is why Spring provides an enhanced implementation
|
||||
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]]
|
||||
===== WebLogic, WebSphere, Resin, GlassFish, JBoss
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Generic Java applications
|
||||
|
||||
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
|
||||
solution. For such cases, Spring provides `InstrumentationLoadTimeWeaver`, which
|
||||
|
@ -3554,6 +3619,7 @@ support) a dedicated LTW.
|
|||
|
||||
[[aop-resources]]
|
||||
== Further Resources
|
||||
|
||||
More information on AspectJ can be found on the http://www.eclipse.org/aspectj[AspectJ
|
||||
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
|
||||
recommended; the focus of the book is on AspectJ, but a lot of general AOP themes are
|
||||
explored (in some depth).
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
= Appendix
|
||||
|
||||
|
||||
|
||||
|
||||
[[xsd-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
|
||||
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
|
||||
enum value is; consider this JDK 5 enum:
|
||||
enum value is; consider this enum:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
@ -134,7 +136,6 @@ enum value is; consider this JDK 5 enum:
|
|||
|
||||
TRANSACTION,
|
||||
EXTENDED
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -152,7 +153,6 @@ Now consider a setter of type `PersistenceContextType`:
|
|||
public void setPersistenceContextType(PersistenceContextType type) {
|
||||
this.persistenceContextType = type;
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -162,14 +162,10 @@ Now consider a setter of type `PersistenceContextType`:
|
|||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<bean class="example.Client">
|
||||
<property name="persistenceContextType" value="TRANSACTION" />
|
||||
<property name="persistenceContextType" value="TRANSACTION"/>
|
||||
</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]]
|
||||
==== <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
|
||||
Spring before the handler is used
|
||||
* `BeanDefinition parse(Element, ParserContext)` - called when Spring encounters a
|
||||
top-level element (not nested inside a bean definition or a different namespace). This
|
||||
method can register bean definitions itself and/or return a bean definition.
|
||||
top-level element (not nested inside a bean definition or a different namespace).
|
||||
This method can register bean definitions itself and/or return a bean definition.
|
||||
* `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)` - called
|
||||
when Spring encounters an attribute or nested element of a different namespace. The
|
||||
decoration of one or more bean definitions is used for example with
|
||||
the<<core.adoc#beans-factory-scopes,out-of-the-box scopes Spring 2.0 supports>>. We'll start by
|
||||
highlighting a simple example, without using decoration, after which we will show
|
||||
decoration in a somewhat more advanced example.
|
||||
when Spring encounters an attribute or nested element of a different namespace.
|
||||
The decoration of one or more bean definitions is used for example with the
|
||||
<<core.adoc#beans-factory-scopes,out-of-the-box scopes Spring supports>>.
|
||||
We'll start by highlighting a simple example, without using decoration, after which
|
||||
we will show decoration in a somewhat more advanced example.
|
||||
|
||||
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),
|
||||
|
@ -1373,4 +1369,3 @@ http\://www.foo.com/schema/jcache=com.foo.JCacheNamespaceHandler
|
|||
# in 'META-INF/spring.schemas'
|
||||
http\://www.foo.com/schema/jcache/jcache.xsd=com/foo/jcache.xsd
|
||||
----
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
= The IoC container
|
||||
|
||||
|
||||
|
||||
|
||||
[[beans-introduction]]
|
||||
== 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]]
|
||||
== Bean overview
|
||||
|
||||
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
|
||||
`<bean/>` definitions.
|
||||
|
@ -778,6 +781,7 @@ Spring container that will create objects through an
|
|||
|
||||
[[beans-dependencies]]
|
||||
== Dependencies
|
||||
|
||||
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
|
||||
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]]
|
||||
== Bean scopes
|
||||
|
||||
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
|
||||
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]]
|
||||
== Bean definition inheritance
|
||||
|
||||
A bean definition can contain a lot of configuration information, including constructor
|
||||
arguments, property values, and container-specific information such as initialization
|
||||
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]]
|
||||
== Container Extension Points
|
||||
|
||||
Typically, an application developer does not need to subclass `ApplicationContext`
|
||||
implementation classes. Instead, the Spring IoC container can be extended by plugging in
|
||||
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]]
|
||||
== Classpath scanning and managed components
|
||||
|
||||
Most examples in this chapter use XML to specify the configuration metadata that produces
|
||||
each `BeanDefinition` within the Spring container. The previous section
|
||||
(<<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.
|
||||
|
||||
|
||||
|
||||
[[beans-scanning-autodetection]]
|
||||
=== Automatically detecting classes and registering bean definitions
|
||||
|
||||
|
@ -5839,6 +5848,7 @@ metadata is provided per-instance rather than per-class.
|
|||
|
||||
[[beans-scanning-index]]
|
||||
=== Generating an index of candidate components
|
||||
|
||||
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
|
||||
mode, _all modules_ of the application must use this mechanism as, when the
|
||||
|
@ -5893,8 +5903,10 @@ classpath.
|
|||
|
||||
|
||||
|
||||
|
||||
[[beans-standard-annotations]]
|
||||
== Using 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
|
||||
annotations. You just need to have the relevant jars in your classpath.
|
||||
|
@ -6742,6 +6754,7 @@ annotation can be used:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[beans-java-configuration-annotation]]
|
||||
=== Using the @Configuration annotation
|
||||
|
||||
|
@ -7979,7 +7992,7 @@ AspectJ load-time weaving, see <<aop-aj-ltw>>.
|
|||
|
||||
|
||||
[[context-introduction]]
|
||||
== Additional Capabilities of the ApplicationContext
|
||||
== Additional capabilities of the ApplicationContext
|
||||
|
||||
As was discussed in the chapter introduction, the `org.springframework.beans.factory`
|
||||
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]]
|
||||
=== Standard and Custom Events
|
||||
=== Standard and custom events
|
||||
|
||||
Event handling in the `ApplicationContext` is provided through the `ApplicationEvent`
|
||||
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.
|
||||
====
|
||||
|
||||
|
||||
[[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
|
||||
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
|
||||
events instead.
|
||||
|
||||
|
||||
[[context-functionality-events-async]]
|
||||
==== Asynchronous Listeners
|
||||
|
||||
|
@ -8534,7 +8549,7 @@ Be aware of the following limitations when using asynchronous events:
|
|||
|
||||
|
||||
[[context-functionality-events-order]]
|
||||
==== Ordering Listeners
|
||||
==== Ordering listeners
|
||||
|
||||
If you need the listener to be invoked before another one, just add the `@Order`
|
||||
annotation to the method declaration:
|
||||
|
@ -8549,8 +8564,9 @@ annotation to the method declaration:
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[context-functionality-events-generics]]
|
||||
==== Generic Events
|
||||
==== Generic events
|
||||
|
||||
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
|
||||
|
@ -8716,14 +8732,15 @@ be used by other application modules on the same machine.
|
|||
|
||||
[[beans-beanfactory]]
|
||||
== The BeanFactory
|
||||
|
||||
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
|
||||
historical in nature for most users of Spring. The `BeanFactory` and related interfaces,
|
||||
such as `BeanFactoryAware`, `InitializingBean`, `DisposableBean`, are still present in
|
||||
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
|
||||
more modern equivalents such as `@PostConstruct` or `@PreDestroy` in order to remain
|
||||
compatible with JDK 1.4 or to avoid a dependency on JSR-250.
|
||||
more modern equivalents such as `@PostConstruct` or `@PreDestroy` in order to avoid a
|
||||
dependency on JSR-250.
|
||||
|
||||
This section provides additional background into the differences between the
|
||||
`BeanFactory` and `ApplicationContext` and how one might access the IoC container
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
[[expressions-intro]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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]]
|
||||
== Feature Overview
|
||||
== Feature overview
|
||||
|
||||
The expression language supports the following functionality
|
||||
|
||||
* Literal expressions
|
||||
|
@ -66,7 +68,8 @@ The expression language supports the following functionality
|
|||
|
||||
|
||||
[[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.
|
||||
The complete language reference can be found in the section
|
||||
<<expressions-language-ref,Language Reference>>.
|
||||
|
@ -235,6 +238,7 @@ Inventor object in the previous example.
|
|||
|
||||
[[expressions-evaluation-context]]
|
||||
=== The EvaluationContext interface
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Type Conversion
|
||||
==== Type conversion
|
||||
|
||||
By default SpEL uses the conversion service available in Spring core (
|
||||
`org.springframework.core.convert.ConversionService`). This conversion service comes
|
||||
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);
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[expressions-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
|
||||
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`
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
||||
[[expressions-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
|
||||
of the expression.
|
||||
|
||||
|
||||
[[expressions-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`
|
||||
enum values (`off`, `immediate`, or `mixed`).
|
||||
|
||||
|
||||
[[expressions-compiler-limitations]]
|
||||
==== Compiler limitations
|
||||
|
||||
|
@ -430,8 +442,12 @@ at the moment:
|
|||
|
||||
More and more types of expression will be compilable in the future.
|
||||
|
||||
|
||||
|
||||
|
||||
[[expressions-beandef]]
|
||||
== Expression support for defining bean definitions
|
||||
|
||||
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
|
||||
form `#{ <expression string> }`.
|
||||
|
@ -440,6 +456,7 @@ form `#{ <expression string> }`.
|
|||
|
||||
[[expressions-beandef-xml-based]]
|
||||
=== XML based configuration
|
||||
|
||||
A property or constructor-arg value can be set using expressions as shown below.
|
||||
|
||||
[source,xml,indent=0]
|
||||
|
@ -488,6 +505,7 @@ You can also refer to other bean properties by name, for example.
|
|||
|
||||
[[expressions-beandef-annotation-based]]
|
||||
=== Annotation-based configuration
|
||||
|
||||
The `@Value` annotation can be placed on fields, methods and method/constructor
|
||||
parameters to specify a default value.
|
||||
|
||||
|
@ -584,6 +602,7 @@ Autowired methods and constructors can also use the `@Value` annotation.
|
|||
|
||||
[[expressions-ref-literal]]
|
||||
=== Literal expressions
|
||||
|
||||
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
|
||||
in a string, use two single quote characters.
|
||||
|
@ -617,6 +636,7 @@ By default real numbers are parsed using Double.parseDouble().
|
|||
|
||||
[[expressions-properties-arrays]]
|
||||
=== Properties, Arrays, Lists, Maps, Indexers
|
||||
|
||||
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
|
||||
data listed in the section <<expressions-example-classes,Classes used in the examples>>.
|
||||
|
@ -685,6 +705,7 @@ string literals.
|
|||
|
||||
[[expressions-inline-lists]]
|
||||
=== Inline lists
|
||||
|
||||
Lists can be expressed directly in an expression using `{}` notation.
|
||||
|
||||
[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
|
||||
expression, rather than building a new list on each evaluation.
|
||||
|
||||
|
||||
|
||||
[[expressions-inline-maps]]
|
||||
=== Inline Maps
|
||||
|
||||
Maps can also be expressed directly in an expression using `{key:value}` notation.
|
||||
|
||||
[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
|
||||
is optional, the examples above are not using quoted keys.
|
||||
|
||||
|
||||
|
||||
[[expressions-array-construction]]
|
||||
=== Array construction
|
||||
|
||||
Arrays can be built using the familiar Java syntax, optionally supplying an initializer
|
||||
to have the array populated at construction time.
|
||||
|
||||
|
@ -741,6 +768,7 @@ multi-dimensional array.
|
|||
|
||||
[[expressions-methods]]
|
||||
=== Methods
|
||||
|
||||
Methods are invoked using typical Java programming syntax. You may also invoke methods
|
||||
on literals. Varargs are also supported.
|
||||
|
||||
|
@ -763,6 +791,7 @@ on literals. Varargs are also supported.
|
|||
|
||||
[[expressions-operators-relational]]
|
||||
==== Relational operators
|
||||
|
||||
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.
|
||||
|
||||
|
@ -825,6 +854,7 @@ shown here: `lt` (`<`), `gt` (`>`), `le` (`<=`), `ge` (`>=`), `eq` (`==`),
|
|||
|
||||
[[expressions-operators-logical]]
|
||||
==== Logical operators
|
||||
|
||||
The logical operators that are supported are and, or, and not. Their use is demonstrated
|
||||
below.
|
||||
|
||||
|
@ -862,6 +892,7 @@ below.
|
|||
|
||||
[[expressions-operators-mathematical]]
|
||||
==== Mathematical operators
|
||||
|
||||
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
|
||||
modulus (%) and exponential power (^). Standard operator precedence is enforced. These
|
||||
|
@ -904,6 +935,7 @@ operators are demonstrated below.
|
|||
|
||||
[[expressions-assignment]]
|
||||
=== Assignment
|
||||
|
||||
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`.
|
||||
|
||||
|
@ -925,6 +957,7 @@ done within a call to `setValue` but can also be done inside a call to `getValue
|
|||
|
||||
[[expressions-types]]
|
||||
=== Types
|
||||
|
||||
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
|
||||
`StandardEvaluationContext` uses a `TypeLocator` to find types and the
|
||||
|
@ -948,6 +981,7 @@ fully qualified, but all other type references must be.
|
|||
|
||||
[[expressions-constructors]]
|
||||
=== Constructors
|
||||
|
||||
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
|
||||
used).
|
||||
|
@ -969,6 +1003,7 @@ used).
|
|||
|
||||
[[expressions-ref-variables]]
|
||||
=== Variables
|
||||
|
||||
Variables can be referenced in the expression using the syntax `#variableName`. Variables
|
||||
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]]
|
||||
==== The #this and #root variables
|
||||
|
||||
The variable #this is always defined and refers to the current evaluation object
|
||||
(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
|
||||
|
@ -1014,6 +1050,7 @@ an expression are evaluated, #root always refers to the root.
|
|||
|
||||
[[expressions-ref-functions]]
|
||||
=== Functions
|
||||
|
||||
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
|
||||
the method.
|
||||
|
@ -1062,6 +1099,7 @@ expression string.
|
|||
|
||||
[[expressions-bean-references]]
|
||||
=== Bean references
|
||||
|
||||
If the evaluation context has been configured with a bean resolver it is possible to
|
||||
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]]
|
||||
=== Ternary Operator (If-Then-Else)
|
||||
|
||||
You can use the ternary operator for performing if-then-else conditional logic inside
|
||||
the expression. A minimal example is:
|
||||
|
||||
|
@ -1126,6 +1165,7 @@ ternary operator.
|
|||
|
||||
[[expressions-operator-elvis]]
|
||||
=== The Elvis Operator
|
||||
|
||||
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.
|
||||
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]]
|
||||
=== Safe Navigation operator
|
||||
|
||||
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]
|
||||
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]]
|
||||
=== Collection Selection
|
||||
|
||||
Selection is a powerful expression language feature that allows you to transform some
|
||||
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]]
|
||||
=== Collection Projection
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Expression templating
|
||||
|
||||
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
|
||||
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]]
|
||||
== Classes used in the examples
|
||||
|
||||
Inventor.java
|
||||
|
||||
[source,java,indent=0]
|
||||
|
|
|
@ -28,6 +28,9 @@ scope of this feature.
|
|||
Libraries like Reactor or Spring Data provide null-safe APIs leveraging this feature.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
== Use cases
|
||||
|
||||
In addition to providing an explicit declaration for Spring Framework API nullability,
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
[[resources]]
|
||||
= Resources
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-introduction]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resource]]
|
||||
== The Resource interface
|
||||
|
||||
|
@ -378,6 +382,7 @@ used. The following two examples show how to force a `ClassPathResource` and a
|
|||
|
||||
[[resources-app-ctx-construction]]
|
||||
=== Constructing application contexts
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Wildcards in application context constructor resource paths
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Ant-style Patterns
|
||||
|
||||
When the path location contains an Ant-style pattern, for example:
|
||||
|
||||
[literal]
|
||||
|
@ -503,6 +510,7 @@ the wildcards.
|
|||
|
||||
[[resources-app-ctx-portability]]
|
||||
===== Implications on portability
|
||||
|
||||
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
|
||||
a completely portable fashion.
|
||||
|
@ -525,7 +533,7 @@ environment before you rely on it.
|
|||
|
||||
|
||||
[[resources-classpath-wildcards]]
|
||||
==== The Classpath*: portability classpath*: prefix
|
||||
==== The classpath*: prefix
|
||||
|
||||
When constructing an XML-based application context, a location string may use the
|
||||
special `classpath*:` prefix:
|
||||
|
@ -565,6 +573,7 @@ strategy described above is used for the wildcard subpath.
|
|||
|
||||
[[resources-wildcards-in-path-other-stuff]]
|
||||
==== Other notes relating to wildcards
|
||||
|
||||
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
|
||||
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 =
|
||||
new FileSystemXmlApplicationContext("file:///conf/context.xml");
|
||||
----
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
= Validation, Data Binding, and Type Conversion
|
||||
|
||||
|
||||
|
||||
|
||||
[[validation-introduction]]
|
||||
== Introduction
|
||||
|
||||
|
@ -169,6 +171,7 @@ methods it offers can be found in the javadocs.
|
|||
|
||||
[[validation-conversion]]
|
||||
== Resolving codes to error messages
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Setting and getting basic and nested properties
|
||||
|
||||
Setting and getting properties is done using the `setPropertyValue(s)` and
|
||||
`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
|
||||
|
@ -698,6 +702,7 @@ registration code to be encapsulated in a class and then shared amongst as many
|
|||
|
||||
[[core-convert]]
|
||||
== Spring 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
|
||||
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]]
|
||||
=== Converter SPI
|
||||
|
||||
The SPI to implement type conversion logic is simple and strongly typed:
|
||||
|
||||
[source,java,indent=0]
|
||||
|
@ -756,6 +762,7 @@ Consider `StringToInteger` as an example for a typical `Converter` implementatio
|
|||
|
||||
[[core-convert-ConverterFactory-SPI]]
|
||||
=== ConverterFactory
|
||||
|
||||
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
|
||||
`ConverterFactory`:
|
||||
|
@ -808,6 +815,7 @@ Consider the `StringToEnum` ConverterFactory as an example:
|
|||
|
||||
[[core-convert-GenericConverter-SPI]]
|
||||
=== GenericConverter
|
||||
|
||||
When you require a sophisticated Converter implementation, consider the GenericConverter
|
||||
interface. With a more flexible but less strongly typed signature, a GenericConverter
|
||||
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]]
|
||||
==== ConditionalGenericConverter
|
||||
|
||||
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
|
||||
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]]
|
||||
=== ConversionService API
|
||||
|
||||
The ConversionService defines a unified API for executing type conversion logic at
|
||||
runtime. Converters are often executed behind this facade interface:
|
||||
|
||||
|
@ -916,6 +926,7 @@ creating common ConversionService configurations.
|
|||
|
||||
[[core-convert-Spring-config]]
|
||||
=== Configuring a ConversionService
|
||||
|
||||
A ConversionService is a stateless object designed to be instantiated at application
|
||||
startup, then shared between multiple threads. In a Spring application, you typically
|
||||
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]]
|
||||
=== Using a ConversionService programmatically
|
||||
|
||||
To work with a ConversionService instance programmatically, simply inject a reference to
|
||||
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]]
|
||||
== Spring Field Formatting
|
||||
|
||||
As discussed in the previous section, <<core-convert, `core.convert`>> is a
|
||||
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
|
||||
|
@ -1048,6 +1061,7 @@ ConversionService provides a unified type conversion API for both SPIs.
|
|||
|
||||
[[format-Formatter-SPI]]
|
||||
=== Formatter SPI
|
||||
|
||||
The Formatter SPI to implement field formatting logic is simple and strongly typed:
|
||||
|
||||
[source,java,indent=0]
|
||||
|
@ -1139,6 +1153,7 @@ https://jira.spring.io/browse/SPR[jira.spring.io] to contribute.
|
|||
|
||||
[[format-CustomFormatAnnotations]]
|
||||
=== Annotation-driven Formatting
|
||||
|
||||
As you will see, field formatting can be configured by field type or annotation. To bind
|
||||
an Annotation to a formatter, implement AnnotationFormatterFactory:
|
||||
|
||||
|
@ -1222,6 +1237,7 @@ To trigger formatting, simply annotate fields with @NumberFormat:
|
|||
|
||||
[[format-annotations-api]]
|
||||
==== Format Annotation API
|
||||
|
||||
A portable format annotation API exists in the `org.springframework.format.annotation`
|
||||
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.
|
||||
|
@ -1244,6 +1260,7 @@ The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date
|
|||
|
||||
[[format-FormatterRegistry-SPI]]
|
||||
=== FormatterRegistry SPI
|
||||
|
||||
The FormatterRegistry is an SPI for registering formatters and converters.
|
||||
`FormattingConversionService` is an implementation of FormatterRegistry suitable for
|
||||
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]]
|
||||
=== FormatterRegistrar SPI
|
||||
|
||||
The FormatterRegistrar is an SPI for registering formatters and converters through the
|
||||
FormatterRegistry:
|
||||
|
||||
|
@ -1317,6 +1335,7 @@ See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> in the Spring
|
|||
|
||||
[[format-configuring-formatting-globaldatetimeformat]]
|
||||
== Configuring a global date & time format
|
||||
|
||||
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
|
||||
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]]
|
||||
== Spring Validation
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Overview of the JSR-303 Bean Validation API
|
||||
|
||||
JSR-303 standardizes validation constraint declaration and metadata for the Java
|
||||
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
|
||||
|
@ -1466,6 +1487,7 @@ bean, keep reading.
|
|||
|
||||
[[validation-beanvalidation-spring]]
|
||||
=== Configuring a Bean Validation Provider
|
||||
|
||||
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.
|
||||
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]]
|
||||
==== Injecting a Validator
|
||||
|
||||
`LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and
|
||||
`javax.validation.Validator`, as well as Spring's
|
||||
`org.springframework.validation.Validator`. You may inject a reference to either of
|
||||
|
@ -1527,6 +1550,7 @@ the Spring Validation API:
|
|||
|
||||
[[validation-beanvalidation-spring-constraints]]
|
||||
==== Configuring Custom Constraints
|
||||
|
||||
Each Bean Validation constraint consists of two parts. First, a `@Constraint` annotation
|
||||
that declares the constraint and its configurable properties. Second, an implementation
|
||||
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]]
|
||||
==== Spring-driven Method Validation
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Additional Configuration Options
|
||||
|
||||
The default `LocalValidatorFactoryBean` configuration should prove sufficient for most
|
||||
cases. There are a number of configuration options for various Bean Validation
|
||||
constructs, from message interpolation to traversal resolution. See the
|
||||
|
@ -1599,6 +1625,7 @@ constructs, from message interpolation to traversal resolution. See the
|
|||
|
||||
[[validation-binder]]
|
||||
=== Configuring a DataBinder
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
See <<web.adoc#mvc-config-validation, Validation>> in the Spring MVC chapter.
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
= Appendix
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas]]
|
||||
== XML Schemas
|
||||
|
||||
This part of the appendix lists XML schemas for data access.
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-tx]]
|
||||
=== The `tx` schema
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,15 @@
|
|||
= Appendix
|
||||
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas]]
|
||||
== XML Schemas
|
||||
|
||||
This part of the appendix lists XML schemas related to integration technologies.
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-jee]]
|
||||
=== The jee schema
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,9 @@
|
|||
:toclevels: 4
|
||||
:docinfo1:
|
||||
|
||||
|
||||
|
||||
|
||||
[[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 + Kotlin applications almost as if the Spring Framework was a native Kotlin framework.
|
||||
|
||||
|
||||
|
||||
|
||||
[[requirements]]
|
||||
== Requirements ==
|
||||
== Requirements
|
||||
|
||||
Spring Framework supports Kotlin 1.1+ and requires
|
||||
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
|
||||
https://start.spring.io/#!language=kotlin[start.spring.io].
|
||||
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
for shorter syntax.
|
||||
|
||||
|
||||
|
||||
|
||||
[[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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[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?`
|
||||
won’t raise an error if such bean does not exist.
|
||||
|
||||
|
||||
|
||||
|
||||
[[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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[web]]
|
||||
== Web
|
||||
|
||||
|
||||
|
||||
=== WebFlux Functional DSL
|
||||
|
||||
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]
|
||||
for a concrete example.
|
||||
|
||||
|
||||
|
||||
=== Kotlin Script templates
|
||||
|
||||
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
|
||||
project for more details.
|
||||
|
||||
|
||||
|
||||
|
||||
[[spring-projects-in-kotlin]]
|
||||
== Spring projects in Kotlin
|
||||
|
||||
This section provides focus on some specific hints and recommendations worth
|
||||
knowing when developing Spring projects in Kotlin.
|
||||
|
||||
|
||||
|
||||
=== Final by default
|
||||
|
||||
By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`].
|
||||
|
@ -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
|
||||
you will be able to write your Kotlin beans without any additional `open` keyword, like in Java.
|
||||
|
||||
|
||||
|
||||
=== Using immutable class instances for persistence
|
||||
|
||||
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.).
|
||||
====
|
||||
|
||||
|
||||
|
||||
=== Injecting dependencies
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
=== Annotation array attributes
|
||||
|
||||
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
|
||||
https://youtrack.jetbrains.com/issue/KT-11235[this Kotlin language design issue].
|
||||
|
||||
|
||||
|
||||
=== Testing
|
||||
|
||||
|
||||
==== Per class lifecycle
|
||||
|
||||
Kotlin allows one to specify meaningful test function names between backticks,
|
||||
|
@ -591,6 +635,7 @@ class IntegrationTests {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
==== Specification-like tests
|
||||
|
||||
It is possible to create specification-like tests with JUnit 5 and Kotlin.
|
||||
|
@ -620,9 +665,13 @@ class SpecificationLikeTests {
|
|||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[getting-started]]
|
||||
== Getting started
|
||||
|
||||
|
||||
|
||||
=== start.spring.io
|
||||
|
||||
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
|
||||
https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[this blog post].
|
||||
|
||||
|
||||
|
||||
=== Choosing the web flavor
|
||||
|
||||
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
|
||||
MVC and its annotation-based programming model is a perfectly valid and fully supported choice.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-started]]
|
||||
== 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://kotlin.link/[Awesome Kotlin]
|
||||
|
||||
|
||||
|
||||
=== Blog posts
|
||||
|
||||
* 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/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way]
|
||||
|
||||
|
||||
|
||||
=== Examples
|
||||
|
||||
* 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/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application
|
||||
|
||||
|
||||
|
||||
=== Tutorials
|
||||
|
||||
* https://kotlinlang.org/docs/tutorials/spring-boot-restful.html[Creating a RESTful Web Service with Spring Boot]
|
||||
|
||||
|
||||
|
||||
=== Issues
|
||||
|
||||
Here is a list of pending issues related to Spring + Kotlin support.
|
||||
|
||||
|
||||
==== Spring Framework
|
||||
|
||||
* https://jira.spring.io/browse/SPR-15413[Add support for Kotlin coroutines]
|
||||
|
||||
|
||||
==== Spring Boot
|
||||
|
||||
* 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/8115[Expose the functional bean registration API via `SpringApplication`]
|
||||
|
||||
|
||||
==== Kotlin
|
||||
|
||||
* https://github.com/Kotlin/KEEP/issues/79[Better generics null-safety support]
|
||||
|
|
|
@ -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
|
||||
evolve over a very long time.
|
||||
|
||||
|
||||
|
||||
|
||||
[[overview-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").
|
||||
Of course, Spring's framework jars keep working fine on the classpath on both JDK 8 and 9.
|
||||
|
||||
|
||||
|
||||
|
||||
[[overview-history]]
|
||||
== History of Spring and the Spring Framework
|
||||
|
||||
|
@ -85,6 +91,9 @@ among others. It’s important to remember that each project has its own source
|
|||
issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for
|
||||
the complete list of Spring projects.
|
||||
|
||||
|
||||
|
||||
|
||||
[[overview-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
|
||||
clean code structure with no circular dependencies between packages.
|
||||
|
||||
|
||||
|
||||
|
||||
[[overview-feedback]]
|
||||
== 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
|
||||
versions, contributor guidelines, the Spring Framework code style, and other information.
|
||||
|
||||
|
||||
|
||||
|
||||
[[overview-getting-started]]
|
||||
== Getting Started
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ without the need for an HTTP server.
|
|||
|
||||
|
||||
|
||||
|
||||
[[webtestclient-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.
|
||||
|
||||
|
||||
|
||||
[[webtestclient-controller-config]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[webtestclient-fn-config]]
|
||||
=== Bind to RouterFunction
|
||||
|
||||
|
@ -53,6 +56,7 @@ The resulting WebFlux application will be tested without an HTTP server using mo
|
|||
request and response objects.
|
||||
|
||||
|
||||
|
||||
[[webtestclient-context-config]]
|
||||
=== Bind to ApplicationContext
|
||||
|
||||
|
@ -90,6 +94,7 @@ resulting WebFlux application will be tested without an HTTP server using mock r
|
|||
and response objects.
|
||||
|
||||
|
||||
|
||||
[[webtestclient-server-config]]
|
||||
=== Bind to server
|
||||
|
||||
|
@ -284,6 +289,3 @@ from the `reactor-test` module to do that, for example:
|
|||
.thenCancel()
|
||||
.verify();
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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-introduction]]
|
||||
== Introduction to Spring Testing
|
||||
|
||||
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
|
||||
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.)__
|
||||
|
||||
|
||||
|
||||
|
||||
[[unit-testing]]
|
||||
== Unit Testing
|
||||
|
||||
Dependency Injection should make your code less dependent on the container than it would
|
||||
be with traditional Java EE development. The POJOs that make up your application should
|
||||
be testable in JUnit or TestNG tests, with objects simply instantiated using the `new`
|
||||
|
@ -54,6 +60,7 @@ support classes.
|
|||
|
||||
[[mock-objects-env]]
|
||||
==== Environment
|
||||
|
||||
The `org.springframework.mock.env` package contains mock implementations of the
|
||||
`Environment` and `PropertySource` abstractions (see
|
||||
<<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]]
|
||||
==== JNDI
|
||||
|
||||
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
|
||||
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]]
|
||||
==== 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 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]]
|
||||
==== Spring Web Reactive
|
||||
|
||||
The package `org.springframework.mock.http.server.reactive` contains mock
|
||||
implementations of `ServerHttpRequest` and `ServerHttpResponse` for use in WebFlux
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[unit-testing-support-classes]]
|
||||
=== Unit Testing support Classes
|
||||
|
||||
|
||||
[[unit-testing-utilities]]
|
||||
==== General testing utilities
|
||||
|
||||
The `org.springframework.test.util` package contains several general purpose utilities
|
||||
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`.
|
||||
|
||||
|
||||
|
||||
[[unit-testing-spring-mvc]]
|
||||
==== Spring MVC
|
||||
|
||||
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
|
||||
dealing with Spring MVC `ModelAndView` objects.
|
||||
|
@ -173,6 +185,7 @@ Framework_>> instead.
|
|||
|
||||
[[integration-testing-overview]]
|
||||
=== Overview
|
||||
|
||||
It is important to be able to perform some integration testing without requiring
|
||||
deployment to your application server or connecting to other enterprise infrastructure.
|
||||
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]]
|
||||
=== Goals of Integration Testing
|
||||
|
||||
Spring's integration testing support has the following primary goals:
|
||||
|
||||
* To manage <<testing-ctx-management,Spring IoC container caching>> between test
|
||||
|
@ -215,6 +229,7 @@ configuration details.
|
|||
|
||||
[[testing-ctx-management]]
|
||||
==== Context management and caching
|
||||
|
||||
The Spring TestContext Framework provides consistent loading of Spring
|
||||
``ApplicationContext``s and ``WebApplicationContext``s as well as caching of those
|
||||
contexts. Support for the caching of loaded contexts is important, because startup time
|
||||
|
@ -245,6 +260,7 @@ TestContext framework.
|
|||
|
||||
[[testing-fixture-di]]
|
||||
==== Dependency Injection of test fixtures
|
||||
|
||||
When the TestContext framework loads your application context, it can optionally
|
||||
configure instances of your test classes via Dependency Injection. This provides a
|
||||
convenient mechanism for setting up test fixtures using preconfigured beans from your
|
||||
|
@ -270,6 +286,7 @@ framework>>.
|
|||
|
||||
[[testing-tx]]
|
||||
==== Transaction management
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Support classes for integration testing
|
||||
|
||||
The Spring TestContext Framework provides several `abstract` support classes that
|
||||
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,
|
||||
|
@ -317,6 +335,7 @@ See support classes for the <<testcontext-support-classes,TestContext framework>
|
|||
|
||||
[[integration-testing-support-jdbc]]
|
||||
=== JDBC Testing Support
|
||||
|
||||
The `org.springframework.test.jdbc` package contains `JdbcTestUtils`, which is a
|
||||
collection of JDBC related utility functions intended to simplify standard database
|
||||
testing scenarios. Specifically, `JdbcTestUtils` provides the following static utility
|
||||
|
@ -348,20 +367,24 @@ with an embedded database>>.
|
|||
=== Annotations
|
||||
|
||||
|
||||
|
||||
[[integration-testing-annotations-spring]]
|
||||
==== Spring Testing Annotations
|
||||
|
||||
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
|
||||
framework. Refer to the corresponding javadocs for further information, including
|
||||
default attribute values, attribute aliases, and so on.
|
||||
|
||||
===== @BootstrapWith
|
||||
|
||||
`@BootstrapWith` is a class-level annotation that is used to configure how the _Spring
|
||||
TestContext Framework_ is bootstrapped. Specifically, `@BootstrapWith` is used to specify
|
||||
a custom `TestContextBootstrapper`. Consult the <<testcontext-bootstrapping,Bootstrapping
|
||||
the TestContext framework>> section for further details.
|
||||
|
||||
===== @ContextConfiguration
|
||||
|
||||
`@ContextConfiguration` defines class-level metadata that is used to determine how to
|
||||
load and configure an `ApplicationContext` for integration tests. Specifically,
|
||||
`@ContextConfiguration` declares the application context resource `locations` or the
|
||||
|
@ -427,6 +450,7 @@ See <<testcontext-ctx-management>> and the `@ContextConfiguration` javadocs for
|
|||
further details.
|
||||
|
||||
===== @WebAppConfiguration
|
||||
|
||||
`@WebAppConfiguration` is a class-level annotation that is used to declare that the
|
||||
`ApplicationContext` loaded for an integration test should be a `WebApplicationContext`.
|
||||
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.
|
||||
|
||||
===== @ContextHierarchy
|
||||
|
||||
`@ContextHierarchy` is a class-level annotation that is used to define a hierarchy of
|
||||
``ApplicationContext``s for integration tests. `@ContextHierarchy` should be declared
|
||||
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.
|
||||
|
||||
===== @ActiveProfiles
|
||||
|
||||
`@ActiveProfiles` is a class-level annotation that is used to declare which __bean
|
||||
definition profiles__ should be active when loading an `ApplicationContext` for an
|
||||
integration test.
|
||||
|
@ -542,6 +568,7 @@ See <<testcontext-ctx-management-env-profiles>> and the `@ActiveProfiles` javado
|
|||
for examples and further details.
|
||||
|
||||
===== @TestPropertySource
|
||||
|
||||
`@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
|
||||
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` indicates that the underlying Spring `ApplicationContext` has been
|
||||
__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
|
||||
|
@ -724,6 +752,7 @@ For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms se
|
|||
`DirtiesContext.HierarchyMode` javadocs.
|
||||
|
||||
===== @TestExecutionListeners
|
||||
|
||||
`@TestExecutionListeners` defines class-level metadata for configuring the
|
||||
`TestExecutionListener` implementations that should be registered with the
|
||||
`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.
|
||||
|
||||
===== @Commit
|
||||
|
||||
`@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
|
||||
replacement for `@Rollback(false)` in order to more explicitly convey the intent of the
|
||||
|
@ -760,6 +790,7 @@ method-level annotation.
|
|||
----
|
||||
|
||||
===== @Rollback
|
||||
|
||||
`@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
|
||||
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` indicates that the annotated `void` method should be executed
|
||||
__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,
|
||||
|
@ -798,6 +830,7 @@ transaction via Spring's `@Transactional` annotation. As of Spring Framework 4.3
|
|||
----
|
||||
|
||||
===== @AfterTransaction
|
||||
|
||||
`@AfterTransaction` indicates that the annotated `void` method should be executed
|
||||
__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`
|
||||
|
@ -814,6 +847,7 @@ default methods.
|
|||
----
|
||||
|
||||
===== @Sql
|
||||
|
||||
`@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.
|
||||
|
||||
|
@ -830,6 +864,7 @@ executed against a given database during integration tests.
|
|||
See <<testcontext-executing-sql-declaratively>> for further details.
|
||||
|
||||
===== @SqlConfig
|
||||
|
||||
`@SqlConfig` defines metadata that is used to determine how to parse and execute SQL
|
||||
scripts configured via the `@Sql` annotation.
|
||||
|
||||
|
@ -847,6 +882,7 @@ scripts configured via the `@Sql` annotation.
|
|||
----
|
||||
|
||||
===== @SqlGroup
|
||||
|
||||
`@SqlGroup` is a container annotation that aggregates several `@Sql` annotations.
|
||||
`@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
|
||||
|
@ -869,6 +905,7 @@ container annotation.
|
|||
|
||||
[[integration-testing-annotations-standard]]
|
||||
==== Standard Annotation Support
|
||||
|
||||
The following annotations are supported with standard semantics for all configurations
|
||||
of the Spring TestContext Framework. Note that these annotations are not specific to
|
||||
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>>.
|
||||
|
||||
===== @IfProfileValue
|
||||
|
||||
`@IfProfileValue` indicates that the annotated test is enabled for a specific testing
|
||||
environment. If the configured `ProfileValueSource` returns a matching `value` for the
|
||||
provided `name`, the test is enabled. Otherwise, the test will be disabled and
|
||||
|
@ -947,6 +985,7 @@ Consider the following example:
|
|||
----
|
||||
|
||||
===== @ProfileValueSourceConfiguration
|
||||
|
||||
`@ProfileValueSourceConfiguration` is a class-level annotation that specifies what type
|
||||
of `ProfileValueSource` to use when retrieving __profile values__ configured through the
|
||||
`@IfProfileValue` annotation. If `@ProfileValueSourceConfiguration` is not declared for a
|
||||
|
@ -962,6 +1001,7 @@ test, `SystemProfileValueSource` is used by default.
|
|||
----
|
||||
|
||||
===== @Timed
|
||||
|
||||
`@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
|
||||
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.
|
||||
|
||||
===== @Repeat
|
||||
|
||||
`@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.
|
||||
|
||||
|
@ -1002,6 +1043,7 @@ well as any __set up__ or __tear down__ of the test fixture.
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[integration-testing-annotations-junit-jupiter]]
|
||||
==== Spring JUnit Jupiter Testing Annotations
|
||||
|
||||
|
@ -1149,6 +1191,7 @@ public @interface DisabledOnMac {}
|
|||
|
||||
[[integration-testing-annotations-meta]]
|
||||
==== Meta-Annotation Support for Testing
|
||||
|
||||
It is possible to use most test-related annotations as
|
||||
<<core.adoc#beans-meta-annotations,meta-annotations>> in order to create custom _composed
|
||||
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>>.
|
||||
|
||||
|
||||
|
||||
[[testcontext-framework]]
|
||||
=== Spring TestContext Framework
|
||||
|
||||
The __Spring TestContext Framework__ (located in the
|
||||
`org.springframework.test.context` package) provides generic, annotation-driven unit and
|
||||
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]]
|
||||
==== Key abstractions
|
||||
|
||||
The core of the framework consists of the `TestContextManager` class and the
|
||||
`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A
|
||||
`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.
|
||||
|
||||
===== TestContext
|
||||
|
||||
`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
|
||||
the test instance for which it is responsible. The `TestContext` also delegates to a
|
||||
`SmartContextLoader` to load an `ApplicationContext` if requested.
|
||||
|
||||
===== TestContextManager
|
||||
|
||||
`TestContextManager` is the main entry point into the __Spring TestContext Framework__
|
||||
and is responsible for managing a single `TestContext` and signaling events to each
|
||||
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
|
||||
|
||||
===== TestExecutionListener
|
||||
|
||||
`TestExecutionListener` defines the API for reacting to test execution events published
|
||||
by the `TestContextManager` with which the listener is registered. See
|
||||
<<testcontext-tel-config>>.
|
||||
|
||||
===== Context Loaders
|
||||
|
||||
`ContextLoader` is a strategy interface that was introduced in Spring 2.5 for loading an
|
||||
`ApplicationContext` for an integration test managed by the Spring TestContext Framework.
|
||||
Implement `SmartContextLoader` instead of this interface in order to provide support for
|
||||
|
@ -1419,6 +1469,7 @@ locations__.
|
|||
* `GenericPropertiesContextLoader`: loads a standard `ApplicationContext` from Java
|
||||
Properties files.
|
||||
|
||||
|
||||
[[testcontext-bootstrapping]]
|
||||
==== 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
|
||||
concrete subclasses instead.
|
||||
|
||||
|
||||
[[testcontext-tel-config]]
|
||||
==== 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]]
|
||||
===== Context configuration with context initializers
|
||||
|
||||
To configure an `ApplicationContext` for your tests using context initializers, annotate
|
||||
your test class with `@ContextConfiguration` and configure the `initializers` attribute
|
||||
with an array that contains references to classes that implement
|
||||
|
@ -1929,6 +1982,7 @@ files or configuration classes.
|
|||
|
||||
[[testcontext-ctx-management-inheritance]]
|
||||
===== Context configuration inheritance
|
||||
|
||||
`@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers`
|
||||
attributes that denote whether resource locations or annotated classes and context
|
||||
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]]
|
||||
===== Context configuration with environment profiles
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Loading a WebApplicationContext
|
||||
|
||||
Spring 3.2 introduced support for loading a `WebApplicationContext` in integration
|
||||
tests. To instruct the TestContext framework to load a `WebApplicationContext` instead
|
||||
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]]
|
||||
==== Dependency injection of test fixtures
|
||||
|
||||
When you use the `DependencyInjectionTestExecutionListener` -- which is configured by
|
||||
default -- the dependencies of your test instances are __injected__ from beans in the
|
||||
application context that you configured with `@ContextConfiguration`. You may use setter
|
||||
|
@ -3191,6 +3248,7 @@ configured theme.
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[testcontext-tx]]
|
||||
==== Transaction management
|
||||
|
||||
|
@ -3293,6 +3351,7 @@ via the `@Commit` and `@Rollback` annotations. See the corresponding entries in
|
|||
|
||||
[[testcontext-tx-programmatic-tx-mgt]]
|
||||
===== Programmatic transaction management
|
||||
|
||||
Since Spring Framework 4.1, it is possible to interact with test-managed transactions
|
||||
_programmatically_ via the static methods in `TestTransaction`. For example,
|
||||
`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
|
||||
for the various `executeSqlScript(..)` methods for further details.
|
||||
|
||||
|
||||
[[testcontext-executing-sql-declaratively]]
|
||||
===== Executing SQL scripts declaratively with @Sql
|
||||
|
||||
|
@ -3817,10 +3875,10 @@ constructor; however, if you use a third-party library that provides a custom
|
|||
execution.
|
||||
====
|
||||
|
||||
|
||||
[[testcontext-support-classes]]
|
||||
==== TestContext Framework support classes
|
||||
|
||||
|
||||
[[testcontext-junit4-runner]]
|
||||
===== Spring JUnit 4 Runner
|
||||
|
||||
|
@ -3854,7 +3912,6 @@ public class SimpleTest {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[testcontext-junit4-rules]]
|
||||
===== Spring JUnit 4 Rules
|
||||
|
||||
|
@ -3898,7 +3955,6 @@ public class IntegrationTest {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[testcontext-support-classes-junit4]]
|
||||
===== JUnit 4 support classes
|
||||
|
||||
|
@ -3938,7 +3994,6 @@ by using `@RunWith(SpringRunner.class)` or <<testcontext-junit4-rules,Spring's
|
|||
JUnit rules>>.
|
||||
====
|
||||
|
||||
|
||||
[[testcontext-junit-jupiter-extension]]
|
||||
===== SpringExtension for JUnit Jupiter
|
||||
|
||||
|
@ -4027,7 +4082,6 @@ class SimpleWebTests {
|
|||
See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in
|
||||
<<integration-testing-annotations-junit-jupiter>> for further details.
|
||||
|
||||
|
||||
[[testcontext-junit-jupiter-di]]
|
||||
===== Dependency Injection with the SpringExtension
|
||||
|
||||
|
@ -4130,7 +4184,6 @@ class OrderServiceIntegrationTests {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[testcontext-support-classes-testng]]
|
||||
===== TestNG support classes
|
||||
|
||||
|
@ -4200,9 +4253,9 @@ integration tests, see <<spring-mvc-test-vs-end-to-end-integration-tests>>.
|
|||
====
|
||||
|
||||
|
||||
|
||||
[[spring-mvc-test-server]]
|
||||
==== Server-Side Tests
|
||||
|
||||
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
|
||||
its methods passing `MockHttpServletRequest`, `MockHttpServletResponse`, etc., as necessary.
|
||||
|
@ -4262,6 +4315,7 @@ request that will be discussed below.
|
|||
|
||||
[[spring-mvc-test-server-static-imports]]
|
||||
===== Static Imports
|
||||
|
||||
The fluent API in the example above requires a few static imports such as
|
||||
`MockMvcRequestBuilders.{asterisk}`, `MockMvcResultMatchers.{asterisk}`,
|
||||
and `MockMvcBuilders.{asterisk}`. An easy way to find these classes is to search for
|
||||
|
@ -4274,6 +4328,7 @@ completion on static members.
|
|||
|
||||
[[spring-mvc-test-server-setup-options]]
|
||||
===== Setup Choices
|
||||
|
||||
There are two main options for creating an instance of `MockMvc`.
|
||||
The first is to load Spring MVC configuration through the __TestContext
|
||||
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
|
||||
or use the IDE to explore the available options.
|
||||
|
||||
|
||||
|
||||
[[spring-mvc-test-server-performing-requests]]
|
||||
===== Performing Requests
|
||||
|
||||
It's easy to perform requests using any HTTP method:
|
||||
|
||||
[source,java,indent=0]
|
||||
|
@ -4498,6 +4552,7 @@ specified on every request.
|
|||
|
||||
[[spring-mvc-test-server-defining-expectations]]
|
||||
===== Defining Expectations
|
||||
|
||||
Expectations can be defined by appending one or more `.andExpect(..)` calls after
|
||||
performing a request:
|
||||
|
||||
|
@ -4604,6 +4659,7 @@ be verified using XPath expressions:
|
|||
|
||||
[[spring-mvc-test-server-filters]]
|
||||
===== Filter Registrations
|
||||
|
||||
When setting up a `MockMvc` instance, you can register one or more Servlet `Filter` instances:
|
||||
|
||||
[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
|
||||
multiple styles and strategies of testing even within the same project.
|
||||
|
||||
|
||||
[[spring-mvc-test-server-resources]]
|
||||
===== Further Server-Side Test Examples
|
||||
|
||||
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
|
||||
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,
|
||||
we will use http://www.gebish.org/[Geb] to make our tests even Groovy-er.
|
||||
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-geb-why]]
|
||||
====== 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]]
|
||||
==== Client-Side REST Tests
|
||||
|
||||
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
|
||||
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();
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[spring-mvc-test-client-static-imports]]
|
||||
===== Static Imports
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Further Examples of Client-side REST Tests
|
||||
|
||||
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
|
||||
tests] of client-side REST tests.
|
||||
|
||||
|
||||
|
||||
include::testing-webtestclient.adoc[leveloffset=+2]
|
||||
|
||||
|
||||
|
||||
[[testing-examples-petclinic]]
|
||||
=== 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
|
||||
database into a known state between test runs.
|
||||
* http://grinder.sourceforge.net/[The Grinder]: Java load testing framework.
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ include::web/webflux.adoc[leveloffset=+1]
|
|||
include::web/webflux-webclient.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-test]]
|
||||
== 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.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-reactive-libraries]]
|
||||
== Reactive Libraries
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
|
||||
[[web-integration]]
|
||||
= Other Web Frameworks
|
||||
|
||||
|
||||
|
||||
|
||||
[[intro]]
|
||||
== Introduction
|
||||
|
||||
|
@ -18,6 +19,8 @@ arguably most evident in the web area, where Spring provides its own web framewo
|
|||
popular third party web frameworks.
|
||||
|
||||
|
||||
|
||||
|
||||
[[web-integration-common]]
|
||||
== Common config
|
||||
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 1.2
|
||||
== JSF
|
||||
JavaServer Faces (JSF) is the JCP's standard component-based, event-driven web user
|
||||
interface framework. As of Java EE 5, it is an official part of the Java EE umbrella.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
||||
[[jsf-springbeanfaceselresolver]]
|
||||
=== 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
|
||||
`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
|
||||
implementation.
|
||||
|
||||
Configuration-wise, simply define `SpringBeanFacesELResolver` in your JSF 1.2
|
||||
Configuration-wise, simply define `SpringBeanFacesELResolver` in your JSF
|
||||
__faces-context.xml__ file:
|
||||
|
||||
[source,xml,indent=0]
|
||||
|
@ -145,6 +150,7 @@ __faces-context.xml__ file:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[jsf-facescontextutils]]
|
||||
=== FacesContextUtils
|
||||
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]]
|
||||
== Apache Struts 2.x
|
||||
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 5.x
|
||||
From the http://tapestry.apache.org/[Tapestry homepage]:
|
||||
|
@ -193,6 +201,7 @@ Spring].
|
|||
|
||||
|
||||
|
||||
|
||||
[[web-integration-resources]]
|
||||
== Further Resources
|
||||
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://struts.apache.org/[Struts] homepage
|
||||
* The http://tapestry.apache.org/[Tapestry] homepage
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-fn-handler-functions]]
|
||||
== 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
|
||||
found. If it is not found, we use `switchIfEmpty(Mono<T>)` to return a 404 Not Found response.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-fn-router-functions]]
|
||||
== RouterFunction
|
||||
|
||||
|
@ -182,6 +187,8 @@ For instance, `RequestPredicates.GET(String)` is a composition of
|
|||
`RequestPredicates.method(HttpMethod)` and `RequestPredicates.path(String)`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-fn-running]]
|
||||
== Running a server
|
||||
|
||||
|
@ -199,6 +206,7 @@ handle requests with router and handler functions.
|
|||
|
||||
|
||||
|
||||
|
||||
[[webflux-fn-handler-filter-function]]
|
||||
== HandlerFilterFunction
|
||||
|
||||
|
@ -232,4 +240,4 @@ RouterFunction<ServerResponse> filteredRoute =
|
|||
----
|
||||
|
||||
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.
|
||||
|
|
|
@ -22,6 +22,8 @@ non-blocking I/O.
|
|||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-client-retrieve]]
|
||||
== Retrieve
|
||||
|
||||
|
@ -65,6 +67,7 @@ By default, responses with 4xx or 5xx status codes result in an error of type
|
|||
|
||||
|
||||
|
||||
|
||||
[[webflux-client-exchange]]
|
||||
== Exchange
|
||||
|
||||
|
@ -103,6 +106,8 @@ to complete.
|
|||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-client-body]]
|
||||
== Request body
|
||||
|
||||
|
@ -152,6 +157,8 @@ Or if you have the actual value, use the `syncBody` shortcut method:
|
|||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-client-builder]]
|
||||
== Builder options
|
||||
|
||||
|
@ -211,7 +218,6 @@ build a new `WebClient`, based on, but without affecting the current instance:
|
|||
|
||||
|
||||
|
||||
|
||||
[[webflux-client-filter]]
|
||||
== Filters
|
||||
|
||||
|
@ -254,4 +260,3 @@ You can also mutate an existing `WebClient` instance without affecting the origi
|
|||
.filter(basicAuthentication("user", "pwd")
|
||||
.build();
|
||||
----
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
[[webflux]]
|
||||
= Spring WebFlux
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-introduction]]
|
||||
== Introduction
|
||||
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`.
|
||||
|
||||
|
||||
|
||||
[[webflux-new-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-why-reactive]]
|
||||
=== 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]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[webflux-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.
|
||||
|
||||
|
||||
|
||||
[[webflux-framework-choice]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[webflux-server-choice]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[webflux-performance]]
|
||||
=== Performance vs scale
|
||||
|
||||
|
@ -215,6 +225,7 @@ dramatic.
|
|||
|
||||
|
||||
|
||||
|
||||
[[webflux-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.
|
||||
|
||||
|
||||
|
||||
[[webflux-httphandler]]
|
||||
=== HttpHandler
|
||||
|
||||
|
@ -411,6 +423,7 @@ to have the following detected:
|
|||
|===
|
||||
|
||||
|
||||
|
||||
[[webflux-codecs]]
|
||||
=== Codecs
|
||||
|
||||
|
@ -439,6 +452,7 @@ of defaults along with the ability to override or replace those defaults.
|
|||
|
||||
|
||||
|
||||
|
||||
[[webflux-dispatcher-handler]]
|
||||
== DispatcherHandler
|
||||
[.small]#<<web.adoc#mvc-servlet,Same in Spring MVC>>#
|
||||
|
@ -603,6 +617,7 @@ your Java configuration:
|
|||
rendering).
|
||||
|
||||
|
||||
|
||||
[[webflux-ann-requestmapping]]
|
||||
=== Request Mapping
|
||||
[.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
|
||||
supported controller method arguments and return values.
|
||||
|
||||
|
||||
[[webflux-ann-arguments]]
|
||||
==== Method arguments
|
||||
[.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.
|
||||
|===
|
||||
|
||||
|
||||
[[webflux-ann-return-types]]
|
||||
==== Return values
|
||||
[.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]
|
||||
|
||||
|
||||
|
||||
|
||||
[[webflux-config]]
|
||||
== WebFlux Java Config
|
||||
[.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-config-enable]]
|
||||
=== Enable WebFlux config
|
||||
[.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.
|
||||
|
||||
|
||||
|
||||
[[webflux-config-customize]]
|
||||
=== WebFlux config API
|
||||
[.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]]
|
||||
=== Validation
|
||||
[.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]]
|
||||
=== Content type resolvers
|
||||
[.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]]
|
||||
=== HTTP message codecs
|
||||
[.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`.
|
||||
|
||||
|
||||
|
||||
[[webflux-config-view-resolvers]]
|
||||
=== View resolvers
|
||||
[.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]]
|
||||
=== Static resources
|
||||
[.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"`.
|
||||
|
||||
|
||||
|
||||
[[webflux-config-path-matching]]
|
||||
=== Path Matching
|
||||
[.small]#<<web.adoc#mvc-config-path-matching,Same in Spring MVC>>#
|
||||
|
@ -1382,6 +1410,7 @@ To customize those options:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[webflux-config-advanced-java]]
|
||||
=== Advanced config mode
|
||||
[.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
|
||||
from the base class and you can still have any number of other ``WebMvcConfigurer``'s on
|
||||
the classpath.
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
This section describes options for client-side access to REST endpoints.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webmvc-resttemplate]]
|
||||
== RestTemplate
|
||||
|
||||
|
@ -19,6 +22,8 @@ See <<integration.adoc#rest-client-access,RestTemplate>> for more details on usi
|
|||
`RestTemplate`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[webmvc-webclient]]
|
||||
== WebClient
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
[[mvc-cors]]
|
||||
= CORS
|
||||
|
||||
|
||||
|
||||
|
||||
== Introduction
|
||||
|
||||
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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-controller]]
|
||||
== @Controller CORS
|
||||
|
||||
|
@ -110,6 +116,9 @@ public class AccountController {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-global]]
|
||||
== 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.
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-global-java]]
|
||||
=== Java Config
|
||||
|
||||
|
@ -161,6 +171,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-global-xml]]
|
||||
=== XML Config
|
||||
|
||||
|
@ -195,6 +206,9 @@ It is also possible to declare several CORS mappings with customized properties:
|
|||
</mvc:cors>
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-customizations]]
|
||||
== Advanced Customization
|
||||
|
||||
|
@ -213,6 +227,8 @@ It can be provided in various ways:
|
|||
instance for each request.
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-cors-filter]]
|
||||
== CORS Filter
|
||||
|
||||
|
@ -238,4 +254,4 @@ CorsFilter filter = new CorsFilter(source);
|
|||
|
||||
Also the information on
|
||||
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors[CORS]
|
||||
in the Spring Security reference.
|
||||
in the Spring Security reference.
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
[[testing]]
|
||||
= Testing
|
||||
|
||||
|
||||
|
||||
|
||||
[[testing-servlet-mocks]]
|
||||
== Servlet API Mocks
|
||||
|
||||
`spring-test` provides mock implementations of Servlet API contracts for unit testing
|
||||
controllers, filters, and other web components.
|
||||
See <<testing.adoc#mock-objects-servlet,Servlet API>> mock objects for more details.
|
||||
|
||||
|
||||
|
||||
|
||||
[[testing-testcontext]]
|
||||
== TestContext Framework
|
||||
|
||||
|
@ -17,6 +23,8 @@ loading a `WebApplicationContext` with a `MockServletContext`.
|
|||
See <<testing.adoc#testcontext-framework,TestContext Framework>> for more details.
|
||||
|
||||
|
||||
|
||||
|
||||
[[testing-mockmvc]]
|
||||
== 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.
|
||||
|
||||
|
||||
|
||||
|
||||
[[testing-resttemplate]]
|
||||
== Client-side REST
|
||||
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
= View Technologies
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-introduction]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-thymeleaf]]
|
||||
== Thymeleaf
|
||||
|
||||
|
@ -26,6 +31,8 @@ Please refer to the http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring
|
|||
documentation section for more details.
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-groovymarkup]]
|
||||
== Groovy Markup
|
||||
|
||||
|
@ -37,6 +44,7 @@ text based content.
|
|||
This requires Groovy 2.3.1+ on the classpath.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-groovymarkup-configuration]]
|
||||
=== Configuration
|
||||
|
||||
|
@ -78,6 +86,7 @@ The XML counterpart using the MVC namespace is:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-view-groovymarkup-example]]
|
||||
=== Example
|
||||
|
||||
|
@ -100,15 +109,20 @@ Here is a sample template for an HTML page:
|
|||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-freemarker]]
|
||||
== FreeMarker
|
||||
|
||||
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,
|
||||
see the http://www.freemarker.org[FreeMarker] web site.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-freemarker-dependencies]]
|
||||
=== Dependencies
|
||||
|
||||
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
|
||||
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!
|
||||
|
||||
|
||||
|
||||
[[mvc-view-freemarker-contextconfig]]
|
||||
=== Context configuration
|
||||
|
||||
A suitable configuration is initialized by adding the relevant configurer bean
|
||||
definition to your `'{asterisk}-servlet.xml'` as shown below:
|
||||
|
||||
|
@ -147,8 +163,10 @@ definition file.
|
|||
====
|
||||
|
||||
|
||||
|
||||
[[mvc-view-freemarker-createtemplates]]
|
||||
=== Creating templates
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Advanced config
|
||||
|
||||
FreeMarker 'Settings' and 'SharedVariables' can be passed directly to the FreeMarker
|
||||
`Configuration` object managed by Spring by setting the appropriate bean properties on
|
||||
the `FreeMarkerConfigurer` bean. The `freemarkerSettings` property requires a
|
||||
|
@ -186,6 +205,7 @@ the `Configuration` object.
|
|||
|
||||
[[mvc-view-freemarker-forms]]
|
||||
=== Form handling
|
||||
|
||||
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
|
||||
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]]
|
||||
==== The bind macros
|
||||
|
||||
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.
|
||||
|
||||
|
@ -208,6 +229,7 @@ directly, the file is called `spring.ftl` in the package
|
|||
|
||||
[[mvc-view-simple-binding]]
|
||||
==== Simple binding
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Input macros
|
||||
|
||||
Additional convenience macros for both languages simplify both binding and form
|
||||
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
|
||||
|
@ -342,6 +365,7 @@ differences exist between the two languages, they are explained in the notes.
|
|||
|
||||
[[mvc-views-form-macros-input]]
|
||||
===== Input Fields
|
||||
|
||||
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
|
||||
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]]
|
||||
===== Selection Fields
|
||||
|
||||
Four selection field macros can be used to generate common UI value selection inputs in
|
||||
your HTML forms.
|
||||
|
||||
|
@ -457,6 +482,7 @@ user still sees the more user friendly city names.
|
|||
|
||||
[[mvc-views-form-macros-html-escaping]]
|
||||
==== HTML escaping
|
||||
|
||||
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
|
||||
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]]
|
||||
== JSP & JSTL
|
||||
|
||||
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`.
|
||||
Furthermore, of course you need to write some JSPs that will actually render the view.
|
||||
|
@ -518,6 +545,7 @@ somewhat.
|
|||
|
||||
[[mvc-view-jsp-resolver]]
|
||||
=== View resolvers
|
||||
|
||||
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
|
||||
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]]
|
||||
=== JSPs versus JSTL
|
||||
|
||||
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
|
||||
work.
|
||||
|
@ -569,6 +598,7 @@ work.
|
|||
|
||||
[[mvc-view-jsp-tags]]
|
||||
=== Spring tags
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Spring form tags
|
||||
|
||||
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
|
||||
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]]
|
||||
==== Configuration
|
||||
|
||||
The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is
|
||||
called `spring-form.tld`.
|
||||
|
||||
|
@ -1267,6 +1299,7 @@ or see the tag library description.
|
|||
|
||||
[[mvc-rest-method-conversion]]
|
||||
==== HTTP Method Conversion
|
||||
|
||||
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,
|
||||
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]]
|
||||
==== HTML5 Tags
|
||||
|
||||
Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
|
||||
which means you can enter any HTML5 specific attributes.
|
||||
|
||||
|
@ -1337,6 +1371,7 @@ is the default type.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-script]]
|
||||
== Script views
|
||||
|
||||
|
@ -1354,6 +1389,8 @@ It has been tested with:
|
|||
* 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]
|
||||
|
||||
|
||||
|
||||
[[mvc-view-script-dependencies]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-script-integrate]]
|
||||
=== Script templates
|
||||
|
||||
|
@ -1536,6 +1574,7 @@ for more configuration examples.
|
|||
|
||||
[[mvc-view-xml-marshalling]]
|
||||
== XML Marshalling
|
||||
|
||||
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
|
||||
explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view
|
||||
|
@ -1547,13 +1586,12 @@ Mappers>>.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-tiles]]
|
||||
== Tiles
|
||||
|
||||
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.
|
||||
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
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]]
|
||||
=== Dependencies
|
||||
|
||||
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]
|
||||
to your project.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-tiles-integrate]]
|
||||
=== Configuration
|
||||
|
||||
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
|
||||
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]]
|
||||
== XSLT
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-xslt-beandefs]]
|
||||
=== Beans
|
||||
|
||||
Configuration is standard for a simple Spring application.
|
||||
The MVC configuration has to define a `XsltViewResolver` bean and
|
||||
regular MVC annotation configuration.
|
||||
|
@ -1763,6 +1809,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
And we need a Controller that encapsulates our word generation logic.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-xslt-controllercode]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-xslt-transforming]]
|
||||
=== 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
|
||||
and end with a `"xslt"` file extension.
|
||||
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
|
@ -1866,6 +1913,9 @@ This is rendered as:
|
|||
</html>
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document]]
|
||||
== PDF, Excel
|
||||
|
||||
|
@ -1873,6 +1923,7 @@ This is rendered as:
|
|||
|
||||
[[mvc-view-document-intro]]
|
||||
=== Introduction
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Configuration
|
||||
|
||||
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
|
||||
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]]
|
||||
=== View definition
|
||||
|
||||
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
|
||||
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__
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configcontroller]]
|
||||
=== Controller
|
||||
|
||||
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
|
||||
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!
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configsubclasses]]
|
||||
=== Excel views
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configsubclasspdf]]
|
||||
=== PDF views
|
||||
|
||||
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
|
||||
`buildPdfDocument()` method as follows:
|
||||
|
@ -2041,6 +2100,7 @@ document should appear listing each of the words in the model map.
|
|||
|
||||
[[mvc-view-feeds]]
|
||||
== RSS Feeds
|
||||
|
||||
Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class
|
||||
`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
|
||||
|
@ -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].
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-view-jackson]]
|
||||
== Jackson
|
||||
|
||||
|
||||
|
||||
[[mvc-view-json-mapping]]
|
||||
=== JSON
|
||||
|
||||
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
|
||||
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]]
|
||||
=== XML
|
||||
|
||||
The `MappingJackson2XmlView` uses the
|
||||
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
|
||||
|
@ -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
|
||||
through the `ObjectMapper` property for cases where custom XML
|
||||
serializers/deserializers need to be provided for specific types.
|
||||
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
= Spring Web MVC
|
||||
:doc-spring-security: {doc-root}/spring-security/site/docs/current/reference
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-introduction]]
|
||||
== Introduction
|
||||
|
||||
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"
|
||||
comes from the name of its source module
|
||||
|
@ -18,6 +22,7 @@ covers Spring WebFlux.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-servlet]]
|
||||
== DispatcherServlet
|
||||
[.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]]
|
||||
=== Context Hierarchy
|
||||
|
||||
|
@ -287,6 +293,7 @@ provides many extra convenient options on top.
|
|||
====
|
||||
|
||||
|
||||
|
||||
[[mvc-container-config]]
|
||||
=== Container Config
|
||||
|
||||
|
@ -467,6 +474,7 @@ initialization parameters ( `init-param` elements) to the Servlet declaration in
|
|||
|===
|
||||
|
||||
|
||||
|
||||
[[mvc-handlermapping-interceptor]]
|
||||
=== Interception
|
||||
|
||||
|
@ -499,8 +507,10 @@ declare it as an <<mvc-ann-controller-advice>> bean or configure it directly on
|
|||
`RequestMappingHandlerAdapter`.
|
||||
|
||||
|
||||
|
||||
[[mvc-viewresolver]]
|
||||
=== View Resolution
|
||||
|
||||
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`
|
||||
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>>.
|
||||
|===
|
||||
|
||||
|
||||
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,
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-redirecting-redirect-prefix]]
|
||||
==== 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.
|
||||
|
||||
|
||||
|
||||
[[mvc-localeresolver]]
|
||||
=== Locales
|
||||
=== Locale
|
||||
|
||||
Most parts of Spring's architecture support internationalization, just as the Spring web
|
||||
MVC framework does. `DispatcherServlet` enables you to automatically resolve messages
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-timezone]]
|
||||
==== TimeZone
|
||||
|
||||
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
|
||||
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`.
|
||||
|
||||
|
||||
|
||||
[[mvc-localeresolver-acceptheader]]
|
||||
==== Header resolver
|
||||
|
||||
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
|
||||
the client's operating system. __Note that this resolver does not support time zone
|
||||
information.__
|
||||
|
||||
|
||||
|
||||
[[mvc-localeresolver-cookie]]
|
||||
==== Cookie resolver
|
||||
|
||||
|
@ -710,7 +719,6 @@ maximum age. Find below an example of defining a `CookieLocaleResolver`.
|
|||
|===
|
||||
|
||||
|
||||
|
||||
[[mvc-localeresolver-session]]
|
||||
==== 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`.
|
||||
|
||||
|
||||
|
||||
[[mvc-localeresolver-interceptor]]
|
||||
==== Locale interceptor
|
||||
|
||||
|
@ -763,7 +770,6 @@ change the site language to Dutch.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-themeresolver]]
|
||||
=== Themes
|
||||
|
||||
|
@ -775,6 +781,7 @@ application.
|
|||
|
||||
[[mvc-themeresolver-defining]]
|
||||
==== Define a theme
|
||||
|
||||
To use themes in your web application, you must set up an implementation of the
|
||||
`org.springframework.ui.context.ThemeSource` interface. The `WebApplicationContext`
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-themeresolver-resolving]]
|
||||
==== Resolve themes
|
||||
|
||||
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
|
||||
`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.
|
||||
|
||||
|
||||
|
||||
[[mvc-multipart]]
|
||||
=== Multipart requests
|
||||
|
||||
|
@ -871,7 +879,6 @@ your context is used. After that, the multipart attribute in your request is tre
|
|||
like any other attribute.
|
||||
|
||||
|
||||
|
||||
[[mvc-multipart-resolver-commons]]
|
||||
==== __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
|
||||
`multipartResolver` to your Spring configuration.
|
||||
|
||||
|
||||
|
||||
|
||||
[[filters]]
|
||||
== Filters
|
||||
|
||||
The `spring-web` module provides some useful filters.
|
||||
|
||||
|
||||
|
||||
[[filters-http-put]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[filters-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.
|
||||
|
||||
|
||||
|
||||
[[filters-shallow-etag]]
|
||||
=== Shallow ETag
|
||||
|
||||
|
@ -957,6 +971,7 @@ response and computing the ETag value at the end.
|
|||
See <<mvc-httpcaching-shallowetag>> for more details.
|
||||
|
||||
|
||||
|
||||
[[filters-cors]]
|
||||
=== CORS
|
||||
|
||||
|
@ -968,6 +983,7 @@ See the section on <<mvc-cors>> and the <<mvc-cors-filter,CorsFilter>> for more
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-controller]]
|
||||
== Annotated Controllers
|
||||
[.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.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-requestmapping-suffix-pattern-match]]
|
||||
==== Suffix match
|
||||
|
||||
|
@ -1259,6 +1274,7 @@ recommendations related to RFD.
|
|||
|
||||
[[mvc-ann-matrix-variables]]
|
||||
==== Matrix variables
|
||||
|
||||
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
|
||||
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
|
||||
// q == 11
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -1307,7 +1322,6 @@ specific to identify where the variable is expected to be:
|
|||
|
||||
// q1 == 11
|
||||
// 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) {
|
||||
|
||||
// q == 1
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -1340,7 +1353,6 @@ All matrix variables may be obtained in a Map:
|
|||
|
||||
// matrixVars: ["q" : [11,22], "r" : 12, "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
|
||||
supported controller method arguments and return values.
|
||||
|
||||
|
||||
[[mvc-ann-arguments]]
|
||||
==== Method Arguments
|
||||
[.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
|
||||
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`,
|
||||
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.
|
||||
|===
|
||||
|
||||
|
||||
[[mvc-ann-return-types]]
|
||||
==== Return Values
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-return-types,Same in Spring WebFlux>>#
|
||||
|
@ -1758,6 +1772,7 @@ parameters.
|
|||
|
||||
[[mvc-ann-typeconversion]]
|
||||
==== Type Conversion
|
||||
|
||||
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
|
||||
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]]
|
||||
==== @RequestHeader
|
||||
|
||||
The `@RequestHeader` annotation allows a method parameter to be bound to a 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
|
||||
with all header values.
|
||||
|
||||
|
||||
[TIP]
|
||||
====
|
||||
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]]
|
||||
==== @CookieValue
|
||||
|
||||
|
@ -1995,6 +2009,7 @@ See <<core.adoc#validation-beanvalidation, Bean validation>> and
|
|||
|
||||
[[mvc-multipart-forms]]
|
||||
==== File upload
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-flash-attributes]]
|
||||
==== Flash attributes
|
||||
|
||||
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
|
||||
__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]]
|
||||
==== @RequestPart
|
||||
|
||||
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,
|
||||
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]]
|
||||
==== @RequestBody
|
||||
|
||||
The `@RequestBody` method parameter annotation indicates that a method parameter should
|
||||
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>>.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-jackson]]
|
||||
==== Jackson JSON
|
||||
|
||||
|
@ -2538,6 +2554,7 @@ request has a query parameter named `jsonp` or `callback`. Those names can be
|
|||
customized through `jsonpParameterNames` property.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-modelattrib-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>>.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-initbinder]]
|
||||
=== Binder Methods
|
||||
|
||||
|
@ -2666,6 +2684,7 @@ controller-specific tweaking of the binding rules.
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-controller-advice]]
|
||||
=== Controller Advice
|
||||
|
||||
|
@ -2701,7 +2720,8 @@ Both `@ControllerAdvice` and `@RestControllerAdvice` can target a subset of cont
|
|||
|
||||
See the
|
||||
{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]]
|
||||
=== 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]]
|
||||
=== Links in views
|
||||
|
||||
|
@ -2918,9 +2940,12 @@ in order to use a specific instance of `MvcUriComponentsBuilder` with a custom b
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-exceptionhandlers]]
|
||||
== Exception Handling
|
||||
|
||||
|
||||
|
||||
[[mvc-exceptionhandlers-overview]]
|
||||
=== Overview
|
||||
|
||||
|
@ -3007,6 +3032,7 @@ value converted with message converters and written to the response stream.
|
|||
|
||||
[[mvc-ann-rest-spring-mvc-exceptions]]
|
||||
=== Framework exceptions
|
||||
|
||||
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
|
||||
needed. However, when working with clients that interpret responses in an automated way
|
||||
|
@ -3104,7 +3130,6 @@ See `ResponseEntityExceptionHandler`.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-annotated-exceptions]]
|
||||
=== Annotated Exception
|
||||
|
||||
|
@ -3117,6 +3142,7 @@ response accordingly. By default the `DispatcherServlet` registers the
|
|||
|
||||
[[mvc-ann-customer-servlet-container-error-page]]
|
||||
=== Container error page
|
||||
|
||||
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
|
||||
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]]
|
||||
== Async Requests
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-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].
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-exceptions]]
|
||||
=== Exception handling
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-interception]]
|
||||
=== Async interceptors
|
||||
|
||||
A `HandlerInterceptor` can also implement `AsyncHandlerInterceptor` in order
|
||||
to implement the `afterConcurrentHandlingStarted` callback, which is called
|
||||
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`
|
||||
which also provides registration methods for timeout and completion.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-http-streaming]]
|
||||
=== 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
|
||||
the response.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-sse]]
|
||||
=== Server-Sent Events
|
||||
|
||||
|
@ -3368,6 +3406,8 @@ a publish-subscribe model within a more messaging-centric architecture.
|
|||
For further background on this see
|
||||
http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the following blog post].
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-output-stream]]
|
||||
=== Streaming raw data
|
||||
|
||||
|
@ -3399,6 +3439,7 @@ Note that `StreamingResponseBody` can also be used as the body in a
|
|||
the response.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-async-reactive-types]]
|
||||
=== 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
|
||||
level and more controls in Spring MVC configuration.
|
||||
|
||||
|
||||
[[mvc-ann-async-configuration-servlet3]]
|
||||
==== Servlet container config
|
||||
|
||||
For applications configured with a `web.xml` be sure to update to version 3.0:
|
||||
|
||||
[source,xml,indent=0]
|
||||
|
@ -3519,6 +3562,7 @@ just like with `web.xml`. To simplify all this configuration, consider extending
|
|||
`AbstractAnnotationConfigDispatcherServletInitializer` which automatically
|
||||
set those options and make it very easy to register `Filter` instances.
|
||||
|
||||
|
||||
[[mvc-ann-async-configuration-spring-mvc]]
|
||||
==== Spring MVC config
|
||||
|
||||
|
@ -3542,9 +3586,13 @@ the timeout value. The class constructor of `WebAsyncTask` also allows providing
|
|||
`AsyncTaskExecutor`.
|
||||
|
||||
|
||||
|
||||
|
||||
include::webmvc-cors.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
|
||||
|
||||
[[mvc-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.
|
||||
|
||||
|
||||
|
||||
[[mvc-coc-modelmap]]
|
||||
=== The Model ModelMap (ModelAndView)
|
||||
|
||||
|
@ -3716,6 +3765,7 @@ that can be configured.
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-caching]]
|
||||
== HTTP Caching
|
||||
|
||||
|
@ -3737,6 +3787,7 @@ This section describes the different choices available to configure HTTP caching
|
|||
Spring Web MVC application.
|
||||
|
||||
|
||||
|
||||
[[mvc-caching-cachecontrol]]
|
||||
=== Cache-Control
|
||||
|
||||
|
@ -3775,6 +3826,7 @@ accepted as an argument in several Spring Web MVC APIs.
|
|||
.noTransform().cachePublic();
|
||||
----
|
||||
|
||||
|
||||
[[mvc-caching-static-resources]]
|
||||
=== Static resources
|
||||
|
||||
|
@ -3816,6 +3868,7 @@ And in XML:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-caching-etag-lastmodified]]
|
||||
=== @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.
|
||||
|
||||
|
||||
|
||||
[[mvc-httpcaching-shallowetag]]
|
||||
=== ETag Filter
|
||||
|
||||
|
@ -3914,6 +3968,7 @@ https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3].
|
|||
|
||||
|
||||
|
||||
|
||||
[[mvc-config]]
|
||||
== MVC Config
|
||||
[.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.
|
||||
|
||||
|
||||
|
||||
[[mvc-config-conversion]]
|
||||
=== Type conversion
|
||||
[.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]]
|
||||
=== Validation
|
||||
[.small]#<<web-reactive.adoc#webflux-config-validation,Same in Spring WebFlux>>#
|
||||
|
@ -4229,6 +4286,7 @@ In XML, the same:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-config-message-converters]]
|
||||
=== Message Converters
|
||||
[.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]]
|
||||
=== View Controllers
|
||||
|
||||
|
@ -4352,6 +4411,7 @@ And the same in XML use the `<mvc:view-controller>` element:
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[mvc-config-view-resolvers]]
|
||||
=== View Resolvers
|
||||
[.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"`.
|
||||
|
||||
|
||||
|
||||
[[mvc-default-servlet-handler]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
|
||||
include::webmvc-view.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
= WebSockets
|
||||
: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
|
||||
based WebSocket messaging including use of STOMP as a a WebSocket sub-protocol.
|
||||
|
||||
|
@ -24,8 +23,10 @@ applications.
|
|||
|
||||
|
||||
|
||||
|
||||
[[websocket-intro]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Fallback Options
|
||||
|
||||
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
|
||||
version 10 (see http://caniuse.com/websockets for support by browser versions).
|
||||
|
@ -68,6 +70,7 @@ application otherwise.
|
|||
|
||||
[[websocket-intro-architecture]]
|
||||
=== Messaging
|
||||
|
||||
Aside from short-to-midterm adoption challenges, using WebSocket
|
||||
brings up important design considerations that are important to recognize
|
||||
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 Sub-Protocol
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Do I Use WebSocket?
|
||||
|
||||
With all the design considerations surrounding the use of WebSocket, it is
|
||||
reasonable to ask, "When is it appropriate to use?".
|
||||
|
||||
|
@ -171,6 +176,7 @@ WebSocket clients or to a specific user.
|
|||
|
||||
[[websocket-server]]
|
||||
== WebSocket API
|
||||
|
||||
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+,
|
||||
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]]
|
||||
=== WebSocketHandler
|
||||
|
||||
Creating a WebSocket server is as simple as implementing `WebSocketHandler` or more
|
||||
likely extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`:
|
||||
|
||||
|
@ -274,6 +281,7 @@ into other HTTP serving environments with the help of
|
|||
|
||||
[[websocket-server-handshake]]
|
||||
=== WebSocket Handshake
|
||||
|
||||
The easiest way to customize the initial HTTP WebSocket handshake request is through
|
||||
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
|
||||
|
@ -346,6 +354,7 @@ session with status `1011` that indicates a server error.
|
|||
|
||||
[[websocket-server-deployment]]
|
||||
=== Deployment
|
||||
|
||||
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
|
||||
HTTP requests. It is also easy to integrate into other HTTP processing scenarios
|
||||
|
@ -417,6 +426,8 @@ Java initialization API, if required:
|
|||
</web-app>
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[websocket-server-runtime-configuration]]
|
||||
=== Server config
|
||||
|
||||
|
@ -543,6 +554,8 @@ or WebSocket XML namespace:
|
|||
</beans>
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[websocket-server-allowed-origins]]
|
||||
=== Allowed origins
|
||||
|
||||
|
@ -615,14 +628,19 @@ XML configuration equivalent:
|
|||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback]]
|
||||
== SockJS Fallback
|
||||
|
||||
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.
|
||||
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]
|
||||
(version 0.3.3).
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-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].
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-enable]]
|
||||
=== Enable SockJS
|
||||
|
||||
SockJS is easy to enable through Java configuration:
|
||||
|
||||
[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
|
||||
configuration options, for example, to specify which transports to include.
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-xhr-vs-iframe]]
|
||||
=== 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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-heartbeat]]
|
||||
=== 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
|
||||
should consider customizing the settings according to their specific needs.
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-servlet3-async]]
|
||||
=== Client disconnects
|
||||
|
||||
|
@ -876,6 +902,8 @@ defined in `AbstractSockJsSession`. If you need to see the stack traces, set tha
|
|||
log category to TRACE.
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-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.
|
||||
|
||||
|
||||
|
||||
[[websocket-fallback-sockjs-client]]
|
||||
=== SockJsClient
|
||||
|
||||
|
@ -986,6 +1015,7 @@ public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport
|
|||
|
||||
[[websocket-stomp]]
|
||||
== STOMP
|
||||
|
||||
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
|
||||
a sub-protocol (i.e. a higher-level protocol) to define message semantics.
|
||||
|
@ -997,6 +1027,7 @@ messages.
|
|||
|
||||
[[websocket-stomp-overview]]
|
||||
=== Overview
|
||||
|
||||
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
|
||||
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]]
|
||||
=== Enable STOMP
|
||||
|
||||
The Spring Framework provides support for using STOMP over WebSocket through
|
||||
the +spring-messaging+ and +spring-websocket+ modules.
|
||||
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-message-flow]]
|
||||
=== 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.
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-handle-simple-broker]]
|
||||
=== Simple Broker
|
||||
|
||||
|
@ -1446,7 +1480,6 @@ See <<websocket-stomp-destination-separator>>.
|
|||
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-handle-broker-relay]]
|
||||
=== External Broker
|
||||
|
||||
|
@ -1529,6 +1562,8 @@ subscribed WebSocket clients.
|
|||
|
||||
In effect, the broker relay enables robust and scalable message broadcasting.
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-handle-broker-relay-configure]]
|
||||
=== 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
|
||||
cloud-based STOMP service.
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-destination-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]]
|
||||
=== Authentication
|
||||
|
||||
|
@ -1776,7 +1812,6 @@ its own sub-class of `AbstractWebSocketMessageBrokerConfigurer` marked with
|
|||
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-user-destination]]
|
||||
=== User Destinations
|
||||
|
||||
|
@ -1900,7 +1935,6 @@ of the `message-broker` element in XML.
|
|||
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-appplication-context-events]]
|
||||
=== Events and Interception
|
||||
|
||||
|
@ -1980,6 +2014,7 @@ to access information about the message.
|
|||
----
|
||||
|
||||
|
||||
|
||||
[[websocket-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
|
||||
STOMP level the SockJS heartbeats are disabled.
|
||||
|
||||
|
||||
|
||||
[[websocket-stomp-testing]]
|
||||
=== Testing
|
||||
|
||||
|
|
Loading…
Reference in New Issue