- renamed resolveParameterizedReturnType() to
resolveReturnTypeForGenericMethod()
- fleshed out Javadoc for resolveReturnType() and
resolveReturnTypeForGenericMethod() regarding declaration of formal
type variables
- improved wording in log statements and naming of local variables
within resolveReturnTypeForGenericMethod()
Issue: SPR-9493
Prior to this commit null literals in SpEL expressions had to be
specified as "null" (i.e., all lowercase).
With this commit null literals in SpEL expressions are interpreted in a
case-insensitive manner, analogous to the current support for boolean
literals.
Issue: SPR-9613
When attempting to parse an Integer literal expression such as
42.toString(), SpEL currently throws a SpelParseException with a message
similar to: "EL1041E:(pos 3): After parsing a valid expression, there is
still more data in the expression: 'toString'". The problem here is that
'3.' is currently considered a valid number (including the dot).
However, SpEL succeeds at parsing an equivalent expression for a Double
literal such as 3.14.isInfinite().
To address this issue, the SpEL Tokenizer no longer consumes the
trailing '.' on an integer as part of the integer. So '3.foo()' will now
be parsed as '3' '.' 'foo()' and not '3.' 'foo()' -- which was what
prevented parsing of method invocations on integers. To keep the change
simple, the parser will no longer handle real numbers of the form
'3.e4'. From now on they must include the extra 0 (i.e., '3.0e4').
Issue: SPR-9612
Recently new utility methods were added to JdbcTestUtils, and a
JdbcTemplate was introduced in abstract transactional base classes in
the TestContext framework. This presents an easy opportunity to make
these new utility methods available as convenience methods in the base
test classes.
This commit introduces new countRowsInTableWhere() and dropTables()
convenience methods in the abstract transactional base classes in the
TestContext framework. These new methods internally delegate to methods
of the same names in JdbcTestUtils.
Issue: SPR-9665
Since Spring 2.5, the abstract transactional base classes in the
TestContext framework have defined and delegated to a protected
SimpleJdbcTemplate instance variable; however, SimpleJdbcTemplate has
deprecated since Spring 3.1. Consequently, subclasses of
AbstractTransactionalJUnit4SpringContextTests and
AbstractTransactionalTestNGSpringContextTests that use this instance
variable suffer from seemingly unnecessary deprecation warnings.
This commit addresses this issue by introducing a protected JdbcTemplate
instance variable in abstract transactional base classes to replace the
use of the existing SimpleJdbcTemplate. Furthermore, the existing
simpleJdbcTemplate instance variable has been deprecated, and utility
methods in the affected base classes now delegate to JdbcTestUtils
instead of the now deprecated SimpleJdbcTestUtils.
Issue: SPR-8990
Several static utility methods in SimpleJdbcTestUtils accept an instance
of SimpleJdbcTemplate as an argument; however, SimpleJdbcTemplate has
been deprecated since Spring 3.1 in favor of simply using JdbcTemplate
which now also supports Java 5 language constructs such as var-args.
Consequently, use of such methods from SimpleJdbcTestUtils results in
deprecation warnings without an equivalent API to migrate to.
This commit addresses this issue by migrating all existing methods in
SimpleJdbcTestUtils to JdbcTestUtils. The migrated methods now accept an
instance of JdbcTemplate as an argument, thereby avoiding the
deprecation warnings but maintaining semantic compatibility with the
functionality previous available in SimpleJdbcTestUtils.
In addition, this commit also introduces two new methods:
- countRowsInTableWhere(): counts the rows in a given table, using
a provided `WHERE` clause
- dropTables(): drops the tables with the specified names
Issue: SPR-9235
For legacy reasons, a MockEnvironment implementation already exists in multiple places within Spring's test suite; however, it is not available to the general public.
This commit promotes MockEnvironment to a first-class citizen in the spring-test module, alongside the existing MockPropertySource.
In addition, the following house cleaning has been performed.
- deleted MockPropertySource from the spring-expression module
- deleted MockEnvironment from the "spring" integration testing module
- updated test copies of MockPropertySource and MockEnvironment
- documented MockEnvironment and MockPropertySource in the testing
chapter of the reference manual
Issue: SPR-9492
Currently the Spring TestContext Framework looks up a
PlatformTransactionManager bean named "transactionManager". The exact
name of the bean can be overridden via @TransactionConfiguration or
@Transactional; however, the bean will always be looked up 'by name'.
The TransactionManagementConfigurer interface that was introduced in
Spring 3.1 provides a programmatic approach to specifying the
PlatformTransactionManager bean to be used for annotation-driven
transaction management, and that bean is not required to be named
"transactionManager". However, as of Spring 3.1.2, using the
TransactionManagementConfigurer on a @Configuration class has no effect
on how the TestContext framework looks up the transaction manager.
Consequently, if an explicit name or qualifier has not been specified,
the bean must be named "transactionManager" in order for a transactional
integration test to work.
This commit addresses this issue by refactoring the
TransactionalTestExecutionListener so that it looks up and delegates to
a single TransactionManagementConfigurer as part of the algorithm for
determining the transaction manager.
Issue: SPR-9604
TransactionalTestExecutionListener currently requires that the
PlatformTransactionManager bean be named "transactionManager" by
default. Otherwise, the bean name can only be overridden via the
transactionManager attribute of @TransactionConfiguration or the value
attribute of @Transactional.
However, if there is only a single PlatformTransactionManager in the
test's ApplicationContext, then the requirement to specify the exact
name of that bean (or to name it exactly "transactionManager") is often
superfluous.
This commit addresses this issue by refactoring the
TransactionalTestExecutionListener so that it is comparable to the
algorithm for determining the transaction manager used in
TransactionAspectSupport for "production" code. Specifically, the TTEL
now uses the following algorithm to retrieve the transaction manager.
- look up by type and qualifier from @Transactional
- else, look up by type and explicit name from
@TransactionConfiguration
- else, look up single bean by type
- else, look up by type and default name from @TransactionConfiguration
Issue: SPR-9645
Currently the getNamedDispatcher(String) method of MockServletContext
always returns null. This poses a problem in certain testing scenarios
since one would always expect at least a default Servlet to be present.
This is specifically important for web application tests that involve
the DefaultServletHttpRequestHandler which attempts to forward to the
default Servlet after retrieving it by name. Furthermore, there is no
way to register a named RequestDispatcher with the MockServletContext.
This commit addresses these issues by introducing the following in
MockServletContext.
- a new defaultServletName property for configuring the name of the
default Servlet, which defaults to "default"
- named RequestDispatchers can be registered and unregistered
- a MockRequestDispatcher is registered for the "default" Servlet
automatically in the constructor
- when the defaultServletName property is set to a new value the
the current default RequestDispatcher is unregistered and replaced
with a MockRequestDispatcher for the new defaultServletName
Issue: SPR-9587
The MVC Java config and the MVC namespace now support options to
configure content negotiation. By default both support checking path
extensions first and the "Accept" header second. For path extensions
.json, .xml, .atom, and .rss are recognized out of the box if the
Jackson, JAXB2, or Rome libraries are available. The ServletContext
and the Java Activation Framework may be used as fallback options
for path extension lookups.
Issue: SPR-8420
After this change each call stack level pushes and pops an async
Callable to ensure the AsyncExecutionChain is in sync with the
call stack. Before this change, a controller returning a "forward:"
prefixed string caused the AsyncExecutionChain to contain a
extra Callables that did not match the actual call stack.
Issue: SPR-9611
Update section on exception handling in Spring MVC chapter to include
more guidance on exception handling when implementing a REST API.
Issue: SPR-9290
Previously DefaultHandlerExceptionResolver did not handle BindException
but after this change it does. A BindException is raised when an
@ModelAttribute annotated argument is not followed by a BindingResult
argument. Hence this is unlikely to affect browser rendering.
For programmatic clients however this change ensures an unhandled
BindException is at least turned into a 400 error.
Issue: SPR-9310
The Atom/RSS message converters are now registered ahead of the
Jackson and the JAXB2 message converters by default. Since the Atom
and RSS converters convert to and from very specific object types
Feed and Channel respectively, that shouldn't introduce any regressions
and will work more intuitively when the requested media type is "*/*".
Issue: SPR-9054
Before this change @ExceptionHandler methods could be located in and
apply locally within a controller. The change makes it possible to have
such methods applicable globally regardless of the controller that
raised the exception.
The easiest way to do that is to add them to a class annotated with
`@ExceptionResolver`, a new annotation that is also an `@Component`
annotation (and therefore works with component scanning). It is also
possible to register classes containing `@ExceptionHandler` methods
directly with the ExceptionHandlerExceptionResolver.
When multiple `@ExceptionResolver` classes are detected, or registered
directly, the order in which they're used depends on the the `@Order`
annotation (if present) or on the value of the order field (if the
Ordered interface is implemented).
Issue: SPR-9112
Before this change the StringHttpMessageConverter used a fixed charset
"ISO-8859-1" if the requested content type did not specify one. This
change adds a defaultCharset field and a constructor to configure it in
StringHttpMessageConverter.
Issue: SPR-9487
Following the introduction of ContentNegotiationManager that allows,
among other things, to configure the file extensions to use for content
negotiation, this change adds "smart" suffix pattern match that matches
against the configured file extensions only rather than against any
extension.
Given the request mapping "/jobs/{jobName}" and one configured file
extension ("json"), a request for "/jobs/my.job" will select the
pattern "/jobs/{jobName}" while a request for "/jobs/my.job.json" will
select the pattern "/jobs/{jobName}.json". Previously, both requests
would have resulted in the pattern "/jobs/{jobName}.*".
Issue: SPR-7632, SPR-8474
The HTTP PATCH method is now supported whereever HTTP methods are used.
Annotated controllers can be mapped to RequestMethod.PATCH.
On the client side the RestTemplate execute(..) and exchange(..)
methods can be used with HttpMethod.PATCH. In terms of HTTP client
libraries, Apache HttpComponents HttpClient version 4.2 or later is
required (see HTTPCLIENT-1191). The JDK HttpURLConnection does not
support the HTTP PATCH method.
Issue: SPR-7985
Introduced ContentNeogtiationStrategy for resolving the requested
media types from an incoming request. The available implementations
are based on path extension, request parameter, 'Accept' header,
and a fixed default content type. The logic for these implementations
is based on equivalent options, previously available only in the
ContentNegotiatingViewResolver.
Also in this commit is ContentNegotiationManager, the central class to
use when configuring content negotiation options. It accepts one or
more ContentNeogtiationStrategy instances and delegates to them.
The ContentNeogiationManager can now be used to configure the
following classes:
- RequestMappingHandlerMappingm
- RequestMappingHandlerAdapter
- ExceptionHandlerExceptionResolver
- ContentNegotiatingViewResolver
Issue: SPR-8410, SPR-8417, SPR-8418,SPR-8416, SPR-8419,SPR-7722
The reference manual currently documents the wrong file name for the
default data SQL script used by EmbeddedDatabaseBuilder. In addition,
the testing chapter of the reference manual does not link to the testing
section of the JDBC chapter.
- Updated the "Testing data access logic with an embedded database"
section of the reference manual appropriately.
- Added a new paragraph to the "JDBC Testing Support" section of the
testing chapter which cross references the "Testing data access logic
with an embedded database" section.
Issue: SPR-9467
The BeanFactory makes it easier to configure a customized Jackson
ObjectMapper (for example enable/disable certain features).
This bean factory is usually used with
MappingJacksonHttpMessageConverter or MappingJacksonJsonView.
See JavaDoc for examples.
Issue: SPR-9125
HttpStatus cannot be created with an unknown status code. If a server
returns a status code that's not in the HttpStatus enum values, an
IllegalArgumentException is raised. Rather than allowing it to
propagate as such, this change ensures the actual exception raised is
a RestClientException.
Issue: SPR-9406
The junit:junit Maven artifact includes a bundled version of hamcrest
core. For projects that depend on later versions of hamcrest this causes
significant issues in terms of dependency management.
The spring-test module now depends on junit:junit-dep, thus allowing
developers to better manage their test dependencies on a more fine
grained level.
Also tidied up dependency issues regarding hamcrest-core and
hamcrest-all across the build.
Issue: SPR-6966
In Spring 3.1 the spring-test Maven artifact did not have a required
dependency on spring-core, but there is practically no part of
spring-test that can be used without spring-core. Most test utilities
that are intended to be stand-alone utilities in fact use utility
classes from spring-core (e.g., ReflectionTestUtils). Even some of the
web mocks/stubs use spring-core (e.g., DelegatingServletInputStream).
In addition, the current Gradle build configuration for the spring-test
module is very simplistic -- in that it does not explicitly list any
optional dependencies such as the Servlet and Portlet APIs -- and it
defines a 'compile' dependency on spring-webmvc-portlet.
The resulting Maven dependencies in the generated POM are therefore not
what a typical consumer of the spring-test artifact would reasonably
expect.
To address these issues, the Gradle build configuration for the
spring-test module now explicitly defines the following 'compile'
dependencies:
- spring-core
- spring-webmvc, optional
- spring-webmvc-portlet, optional
- junit, optional
- testng, optional
- servlet-api, optional
- jsp-api, optional
- portlet-api, optional
- activation, provided
The only required dependency is now spring-core; all other dependencies
are 'optional'.
Issue: SPR-8861
Changes introduced in Spring 3.1 for Environment support inadvertently
established a cyclic dependency between the
org.springframework.web.context and
org.springframework.web.context.support packages, specifically through
web.context.ContextLoader's invocation of
web.context.support.WebApplicationContextUtils#initServletPropertySources.
This commit introduces ConfigurableWebEnvironment to break this cyclic
dependency. All web.context.ConfigurableWebApplicationContext types now
return web.context.ConfigurableWebEnvironment from their #getEnvironment
methods; web.context.support.StandardServletEnvironment now implements
ConfigurableWebEnvironment and makes the call to
web.context.support.WebApplicationContextUtils#initServletPropertySources
within its implementation of #initPropertySources. This means that
web.context.ContextLoader now invokes
web.context.ConfigurableWebEnvironment#initPropertySources instead of
web.context.support.WebApplicationContextUtils#initServletPropertySources
and thus the cycle is broken.
Issue: SPR-9439
java.util.concurrent's ScheduledExecutorService and its #schedule*
methods allow for an 'initialDelay' parameter in milliseconds.
Similarly, Spring's TaskExecutor abstraction allows for a concrete
'startTime' expressed as a Date. However, Spring's <task:scheduled> XML
element and @Scheduled annotation have, to date, not allowed for an
initial delay parameter that can be propagated down to the underlying
TaskScheduler/ScheduledExecutorService.
This commit introduces initial-delay and #initialDelay attributes to
task:scheduled and @Scheduled respectively, both indicating the number
of milliseconds to wait before the first invocation of the method in
question. Specifying a delay in this fashion is only valid in
conjunction with fixed-rate and fixed-delay tasks (i.e. not with cron
or trigger tasks).
The principal changes required to support these new attributes lie in
ScheduledTaskRegistrar, which previously supported registration of
tasks in the form of a Runnable and a Long parameter indicating (in the
case of fixed-rate and fixed-delay tasks), the interval with which the
task should be executed. In order to accommodate a third (and optional)
'initialDelay' parameter, the IntervalTask class has been added as a
holder for the Runnable to be executed, the interval in which to run
it, and the optional initial delay. For symmetry, a TriggerTask and
CronTask have also been added, the latter subclassing the former. And a
'Task' class has been added as a common ancestor for all the above.
One oddity of the implementation is in the naming of the new
setters in ScheduledTaskRegistrar. Prior to this commit, the setters
were named #setFixedDelayTasks, #setFixedRateTasks, etc, each accepting
a Map<Runnable, long>. In adding new setters for each task type, each
accepting a List<IntervalTask>, List<CronTask> etc, naturally the
approach would be to use method overloading and to introduce methods
of the same name but with differing parameter types. Unfortunately
however, Spring does not support injection against overloaded methods
(due to fundamental limitations of the underlying JDK Introspector).
This is not a problem when working with the ScheduledTaskRegistrar
directly, e.g. from within a @Configuration class that implements
SchedulingConfigurer, but is a problem from the point of view of the
ScheduledTasksBeanDefinitionParser which parses the <task:scheduled>
element - here the ScheduledTaskRegistrar is treated as a Spring bean
and is thus subject to these limitations. The solution to this problem
was simply to avoid overloading altogether, thus the naming of the new
methods ending in "List", e.g. #setFixedDelayTasksList, etc. These
methods exist primarily for use by the BeanDefinitionParser and are
not really intended for use by application developers. The Javadoc for
each of the new methods makes note of this.
Issue: SPR-7022
In anticipation of substantive changes required to implement "initial
delay" support in the <task:scheduled> element and @Scheduled
annotation, the following updates have been made to the components and
infrastructure supporting scheduled task execution:
- Fix code style violations
- Fix compiler warnings
- Add Javadoc where missing, update to use {@code} tags, etc.
- Organize imports to follow conventions
This commit introduces three abstract WebApplicationInitializers, to be
used in the typical setup of a Spring-based web application.
- AbstractContextLoaderInitializer provides an abstract base class for
registering a ContextLoaderListener.
- AbstractDispatcherServletInitializer provides an abstract base class
for registering a DispatcherServlet, with an optional root context.
- AbstractAnnotationConfigDispatcherServletInitializer provides an
abstract base class for registering a DispatcherServlet and optional
ContextLoaderListener based on annotated (e.g. @Configuration)
classes.
Issue: SPR-9300
Prior to this change, Spring's @Async annotation support was tied to a
single AsyncTaskExecutor bean, meaning that all methods marked with
@Async were forced to use the same executor. This is an undesirable
limitation, given that certain methods may have different priorities,
etc. This leads to the need to (optionally) qualify which executor
should handle each method.
This is similar to the way that Spring's @Transactional annotation was
originally tied to a single PlatformTransactionManager, but in Spring
3.0 was enhanced to allow for a qualifier via the #value attribute, e.g.
@Transactional("ptm1")
public void m() { ... }
where "ptm1" is either the name of a PlatformTransactionManager bean or
a qualifier value associated with a PlatformTransactionManager bean,
e.g. via the <qualifier> element in XML or the @Qualifier annotation.
This commit introduces the same approach to @Async and its relationship
to underlying executor beans. As always, the following syntax remains
supported
@Async
public void m() { ... }
indicating that calls to #m will be delegated to the "default" executor,
i.e. the executor provided to
<task:annotation-driven executor="..."/>
or the executor specified when authoring a @Configuration class that
implements AsyncConfigurer and its #getAsyncExecutor method.
However, it now also possible to qualify which executor should be used
on a method-by-method basis, e.g.
@Async("e1")
public void m() { ... }
indicating that calls to #m will be delegated to the executor bean
named or otherwise qualified as "e1". Unlike the default executor
which is specified up front at configuration time as described above,
the "e1" executor bean is looked up within the container on the first
execution of #m and then cached in association with that method for the
lifetime of the container.
Class-level use of Async#value behaves as expected, indicating that all
methods within the annotated class should be executed with the named
executor. In the case of both method- and class-level annotations, any
method-level #value overrides any class level #value.
This commit introduces the following major changes:
- Add @Async#value attribute for executor qualification
- Introduce AsyncExecutionAspectSupport as a common base class for
both MethodInterceptor- and AspectJ-based async aspects. This base
class provides common structure for specifying the default executor
(#setExecutor) as well as logic for determining (and caching) which
executor should execute a given method (#determineAsyncExecutor) and
an abstract method to allow subclasses to provide specific strategies
for executor qualification (#getExecutorQualifier).
- Introduce AnnotationAsyncExecutionInterceptor as a specialization of
the existing AsyncExecutionInterceptor to allow for introspection of
the @Async annotation and its #value attribute for a given method.
Note that this new subclass was necessary for packaging reasons -
the original AsyncExecutionInterceptor lives in
org.springframework.aop and therefore does not have visibility to
the @Async annotation in org.springframework.scheduling.annotation.
This new subclass replaces usage of AsyncExecutionInterceptor
throughout the framework, though the latter remains usable and
undeprecated for compatibility with any existing third-party
extensions.
- Add documentation to spring-task-3.2.xsd and reference manual
explaining @Async executor qualification
- Add tests covering all new functionality
Note that the public API of all affected components remains backward-
compatible.
Issue: SPR-6847
The reference manual previously did not mention the applicability of
JSR-250 lifecycle annotations within the TestContext framework. The
lacking documentation here has lead to misunderstandings of the support
provided for @PostConstruct and @PreDestroy in test classes.
The testing chapter of the reference manual has therefore been updated
to explicitly define the limited support for these annotations.
Also introduced Jsr250LifecycleTests for empirical verification of the
expected behavior.
Issue: SPR-4868
Updated the testing chapter of the reference manual to refer to
'annotated classes' instead of 'configuration classes' where
appropriate.
Also revised the content and examples in the @ContextConfiguration
annotation section, mentioned Gradle, and reformatted the entire text.
Issue: SPR-9401
When URL decoding is turned off in AbstractHandlerMapping, the
extracted path variables are also not encoded. Turning off URL decoding
may be necessary for request mapping to work correctly when the path
may contain the (encoded) special character '/'. At the same time there
is no good reason not to leave path variables encoded. This change
ensures path variables are encoded when URL decoding is turned off.
Issue: SPR-9098
MappingJackson2JsonView and MappingJacksonJsonView now provide an
option that will set the Content-Length header of JSON responses.
Use of the option implies buffering of the response and it must be
enabled explicitly.
Issue: SPR-7866
This change makes it possible to provide a custom MessageCodesResolver
through the MVC Java config whether using @EnableWebMvc and extending
WebMVcConfigurerAdapter or sub-classing directly from
WebMvcConfigurationSupport.
Issue: SPR-9223