Before this commit the object that #this would refer to in
nested expressions within projection/selection clauses was always
the root context object. This was incorrect as it should be the
element being projected/selected over. This commit introduces
a scope root context object which is set upon entering a new
scope (like when entering a projection or selection). Any
object. With this change this kind of expression now behaves:
where #this is the element of list1. Unqualified references
are also resolved against this scope root context object.
Issues: SPR-10417, SPR-12035, SPR-13055
This commit introduces a test that will fail if SynthesizedAnnotation is
not public as is required by the contract for getProxyClass() in
java.lang.reflect.Proxy.
Issue: SPR-13057
This commit introduces support for asynchronous return values thanks
to the new AsyncHandlerMethodReturnValueHandler interface. Out of
the box support for ListenableFuture is also provided.
Issue: SPR-12168
Commit 3d86f15 added a lot of new feature in AbstractPropertyAccessor
shared by both DirectFieldAccessor and BeanWrapperImpl. This makes this
abstract class harder to implement for others having simpler use cases.
It turns that Spring Data has such use case; this commit split these new
features in a dedicated new base class, leaving AbstractPropertyAccessor
untouched.
Issue: SPR-12805
Enable public visibility on SynthetizedAnnotation to allow annotation
outside its package to be proxied properly. This commit is pending a
unit test that actually reproduces the problem.
Issue: SPR-13057
This commit introduces first-class support for aliases for annotation
attributes. Specifically, this commit introduces a new @AliasFor
annotation that can be used to declare a pair of aliased attributes
within a single annotation or an alias from an attribute in a custom
composed annotation to an attribute in a meta-annotation.
To support @AliasFor within annotation instances, AnnotationUtils has
been overhauled to "synthesize" any annotations returned by "get" and
"find" searches. A SynthesizedAnnotation is an annotation that is
wrapped in a JDK dynamic proxy which provides run-time support for
@AliasFor semantics. SynthesizedAnnotationInvocationHandler is the
actual handler behind the proxy.
In addition, the contract for @AliasFor is fully validated, and an
AnnotationConfigurationException is thrown in case invalid
configuration is detected.
For example, @ContextConfiguration from the spring-test module is now
declared as follows:
public @interface ContextConfiguration {
@AliasFor(attribute = "locations")
String[] value() default {};
@AliasFor(attribute = "value")
String[] locations() default {};
// ...
}
The following annotations and their related support classes have been
modified to use @AliasFor.
- @ManagedResource
- @ContextConfiguration
- @ActiveProfiles
- @TestExecutionListeners
- @TestPropertySource
- @Sql
- @ControllerAdvice
- @RequestMapping
Similarly, support for AnnotationAttributes has been reworked to
support @AliasFor as well. This allows for fine-grained control over
exactly which attributes are overridden within an annotation hierarchy.
In fact, it is now possible to declare an alias for the 'value'
attribute of a meta-annotation.
For example, given the revised declaration of @ContextConfiguration
above, one can now develop a composed annotation with a custom
attribute override as follows.
@ContextConfiguration
public @interface MyTestConfig {
@AliasFor(
annotation = ContextConfiguration.class,
attribute = "locations"
)
String[] xmlFiles();
// ...
}
Consequently, the following are functionally equivalent.
- @MyTestConfig(xmlFiles = "test.xml")
- @ContextConfiguration("test.xml")
- @ContextConfiguration(locations = "test.xml").
Issue: SPR-11512, SPR-11513
Previously, the binding may have to call the getter first to retrieve the
old value of a property before actually setting it. This was guarded by
a catch block that was accidentally removed in 3d86f15
Restore that catch block and add a test to cover it.
Issue: SPR-12805
Prior to this commit, the `ResourceHttpRequestHandler` would not
properly handle HTTP requests to **directories contained in JARs**.
This would result in HTTP 500 errors, caused by `FileNotFoundException`
or `NullPointerException`.
This can be tracked to webapp ClassLoader implementations in servlet
containers:
* in Jetty9x, fetching a directory within a JAR as a `Resource` and
getting its InputStream work fine, but attempting to `close()` it
results in a NullPointerException as the underlying stream is null.
* In Tomcat6x, one cannot fetch an InputStream for the same `Resource`
as it throws a FileNotFoundException.
This change adds more try/catch clauses and catches more Exception so as
to result in HTTP 200 OK responses instead of server errors. While this
is inconsistent because the same code path would result in HTTP 404 with
existing directories on the file system, there's no other simple way to
make those checks for resources contained in JARs.
Issue: SPR-12999
`BeanWrapperImpl` and `DirectFieldAccessor` are two
`ConfigurablePropertyAccessor` implementations with different features
set.
This commit harmonizes the two implementations to use a common base class
that delegates the actual property handling to the sub-classes:
* `BeanWrapperImpl`: `PropertyDescriptor` and introspection utilities
* `DirectFieldAccessor`: reflection on `java.lang.Field`
Issues: SPR-12206 - SPR-12805
Previously, a Bean implementing `AutoCloseable` (or `Closeable`) was
always destroyed regardless of its bean definition. In particular, the
documented way of disabling the destruction callback via an empty String
did not work.
AutoCloseable beans are now treated pretty much as any other bean: we
still use the presence of the interface to optimize the check of a
destroy method and we only auto-discover the method name to invoke if
the inferred mode is enabled.
Issue: SPR-13022
Prior to this commit, WebJars users needed to use versioned links within
templates for WebJars resources, such as `/jquery/1.2.0/jquery.js`.
This can be rather cumbersome when updating libraries - all references
in templates need to be updated.
One could use version-less links in templates, but needed to add a
specific MVC Handler that uses webjars.org's webjar-locator library.
While this approach makes maintaing templates easier, this makes HTTP
caching strategies less optimal.
This commit adds a new WebJarsResourceResolver that search for resources
located in WebJar locations. This ResourceResolver is automatically
registered if the "org.webjars:webjars-locator" dependency is present.
Registering WebJars resource handling can be done like this:
```java
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:META-INF/resources/webjars")
.resourceChain(true)
.addResolver(new WebJarsResourceResolver());
}
```
Issue: SPR-12323
polish
Prior to this commit, registering `HandlerInterceptor`s using the
`InterceptorRegistry` would not guarantee their order of execution. In
fact, `HandlerInterceptor`s would always be executed before
`MappedInterceptor`s.
This change makes `MappedInterceptor` implement the `HandlerInterceptor`
interface, in order to register all interceptors in a single ordered
list. The order of execution of interceptors is now guaranteed in the
`HandlerExecutionChain` built by `AbstractHandlerMapping`.
Issue: SPR-12673
This commit introduces support for OkHttp
(http://square.github.io/okhttp/) as a backing implementation for
ClientHttpRequestFactory and AsyncClientHttpRequestFactory.
Issue: SPR-12893
MvcUriComponentsBuilder::fromMethodCall creates wrong URLs with derived
controller classes. The @RequestMapping of the declaring class of the
method that is called is used instead of the @RequstMapping of the
given controller class.
https://jira.spring.io/browse/SPR-13033
After this change CorsProcessor has a single processRequest method and
it also explicitly deals with a null CorsConfiguration, which for
pre-flight requests results in a rejection while for simple requests
results in no CORS headers added.
The AbstractHandlerMapping now uses a LinkedHashMap to preserve the
order in which global patterns are provided.