Prior to this commit if the return type is a CompletableFuture but a
cache get returns null, the execution falls through to the
reactiveCachingHandler.
This commit ensures that evaluation instead continues onto the next
cache (if any).
Closes gh-33371
This commit revises QualifierAnnotationAutowireCandidateResolver to
reinstate "qualifier" support for the legacy JSR-330
@javax.inject.Named annotation.
See gh-31090
Closes gh-33345
When ScheduledAnnotationReactiveSupport adds the Observation to the
context, Reactor opens a scope through the Context Propagation API.
This happens before TrackingSubscriber would start the Observation and
opening a scope without starting an Observation is invalid.
This change moves the Observation start before the scope opening.
Closes gh-33349
Before UnknownContentTypeException is thrown, it is added to the current
Observation but since UnknownContentTypeException is a
RestClientException, the exception is added again in one of the
catch blocks later on.
Closes gh-33347
ClientHttpResponse implements Closeable and the close method of
DefaultConvertibleClientHttpResponse also stops the current Observation.
Before this change exiting the try-with-resource block stopped the
Observation since it called close on ClientHttpResponse.
After this, there were multiple error and stop calls on the Observation
in the catch blocks after the Observation was already stopped
which is invalid.
This change reorders the flow by stopping the Observation in the
finally block (closing ClientHttpResponse) and not stopping
the Observation in any of the catch blocks.
Closes gh-33346
Prior to this commit, the Gradle build output the following warning
multiple times.
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Since we don't need CDS enabled for our tests, I've added `-Xshare:off`
as a JVM argument for our tests to disable CDS.
(cherry picked from commit 27985b1439)
Since the me.champeau.mrjar stores Java 21 main and test sources in
non-standard locations, and since we can only use a single JDK within
Eclipse, this commit updates `ide.gradle` to remove `java21` classpath
entries in Eclipse projects.
This commit implements modifyContextPath in ServletRequestPath and
apply the same logic of concatenating the servlet path with the
context path.
Closes gh-33251
This changes the criteria for simplified task rejection logging from
to be that the executor is in the shutdown phase, not fully terminated.
See gh-33334
Closes gh-33336
SimpleEvaluationContext.forReadOnlyDataBinding() documents that it
creates a SimpleEvaluationContext for read-only access to public
properties; however, prior to this commit write access was not disabled
for indexed structures when using the assignment operator, the
increment operator, or the decrement operator.
In order to better align with the documented contract for
forReadOnlyDataBinding(), this commit makes it possible to disable
assignment in general in order to enforce read-only semantics for
SpEL's SimpleEvaluationContext when created via the
forReadOnlyDataBinding() factory method. Specifically:
- This commit introduces a new isAssignmentEnabled() "default" method
in the EvaluationContext API, which returns true by default.
- SimpleEvaluationContext overrides isAssignmentEnabled(), returning
false if the context was created via the forReadOnlyDataBinding()
factory method.
- The Assign, OpDec, and OpInc AST nodes -- representing the assignment
(=), increment (++), and decrement (--) operators, respectively --
now throw a SpelEvaluationException if assignment is disabled for the
current EvaluationContext.
Closes gh-33319
The changes made in conjunction with gh-33013 resulted in a regression
for varargs support in SpEL expressions. Specifically, before gh-33013
one could supply a list -- for example, an "inline list" -- as the
varargs array when invoking a varargs constructor, method, or function
within a SpEL expression. However, after gh-33013 an inline list (or
collection in general) is no longer converted to an array for varargs
invocations. Instead, the list is supplied as a single argument of the
resulting varargs array which breaks applications that depend on the
previous behavior.
Although it was never intended that one could supply a collection as
the set of varargs, we concede that this is a regression in existing
behavior, and this commit therefore restores support for supplying a
java.util.List as the varargs "array".
In addition, this commit introduces the same "list to array" conversion
support for MethodHandle-based functions that accept varargs.
Note, however, that this commit does not restore support for converting
arbitrary single objects to an array for varargs invocations if the
single object is already an instance of the varargs array's component
type.
See gh-33013
Closes gh-33315
Prior to this commit, the Indexer in the Spring Expression Language
(SpEL) silently ignored a failure to set a property via the indexed
property syntax (['<property name>'] = <new value>) – for example, if
property write access was disabled in the EvaluationContext.
This commit addresses this issue by properly throwing a
SpelEvaluationException in PropertyIndexingValueRef.setValue(Object) if
the property could not be set.
Closes gh-33310
Prior to this commit, SpEL incorrectly wrapped a primitive array in an
Object[] array when invoking Object[] varargs methods and constructors.
This commit addresses this by updating the convertArguments(...) method
in ReflectionHelper as follows when the user supplies the varargs
already packaged in a primitive array.
- When deciding whether to convert a single element passed as varargs,
we now check if the argument is an array that is assignable to the
varargs array type.
- When converting an array supplied as the varargs, we convert that
array to the varargs array type.
Closes gh-33317
Prior to this commit, the ConversionService failed to convert a primitive
array (such as int[]) to an Object[] due to an error in the logic in
ArrayToArrayConverter.
This commit addresses this by augmenting the "can bypass conversion"
check in ArrayToArrayConverter to ensure that the supplied source object
is an instance of the target type (i.e., that the source array can be
cast to the target type array without conversion).
Closes gh-33212
Our recent switch from the `org.unbroken-dome.xjc` plugin to the
`com.github.bjornvester.xjc` plugin resulted in errors when trying to
import Spring Framework projects into the Eclipse IDE.
This commit fixes those issues as follows.
- @wilkinsona revised the XJC configuration in `spring-oxm.gradle` to
avoid the ConcurrentModificationException encountered when running
`./gradlew eclipse`.
- I added a workaround in `ide.gradle` to manually remove lingering
"main" classpath entries for sources generated by XJC.
Co-authored-by: Andy Wilkinson <andy.wilkinson@broadcom.com>
Closes gh-33264
This commit improves CodeWarnings so that it detects if an enclosing
class is deprecated. Previously, it would only consider the annotated
element itself and the enclosing element is important for a class as
it is required to refer to it.
Closes gh-33273
This commit upgrades our build to use a different plugin for XJC
processing, so that Gradle doesn't output a compatibility warning
anymore.
Unfortunately, com.github.bjornvester.xjc only works against main
sources and our schema is only used for test purposes. This commit
therefore reconfigure the task to remove the xjc main source set and
apply it to the test source set instead.
Closes gh-33264
This commit makes sure to consistently check that the content length
is not set above 2GB. Previously it was only checked in
setContentLength.
Closes gh-33256
* pr/33248:
Polish "Stop referring to STRUCT and ARRAY as they are deprecated"
Stop referring to STRUCT and ARRAY as they are deprecated
Closes gh-33248
Prior to this commit, the observation instrumentation for `@JmsListener`
annotated methods (implemented in `AbstractMessageListenerContainer`
would not instrument the JMS session using the Micrometer JMS support.
This means that response messages returned from the listener method
would be sent but no observation would be recorded. As a result, tracing
message properties would be also missing.
This commit ensures that the session provided to the listener method is
instrumented beforehand, if Micrometer is on the classpath and an
observation registry has been configured.
Fixes gh-33221
This change simplifies the CacheInterceptor way of dealing with cached
coroutines, thanks to the fact that lower level support for AOP has been
introduced in c8169e5c. This fix is similar to the one applied for
`@Transactional` in gh-33095.
Closes gh-33210
Prior to this commit, the Spring Expression Language (SpEL) could not
invoke a varargs MethodHandle function with a primitive array
containing the variable arguments, although that is supported for a
varargs Method function. Attempting to do so resulted in the first
element of the primitive array being supplied as a single argument to
the MethodHandle, effectively ignoring any variable arguments after the
first one.
This commit addresses this by updating the
convertAllMethodHandleArguments(...) method in ReflectionHelper as
follows when the user supplies the varargs already packaged in a
primitive array.
- Regarding conversion, use the wrapper type for a primitive varargs
array, since we eventually need an Object array in order to invoke
the MethodHandle in FunctionReference#executeFunctionViaMethodHandle().
- When deciding whether to convert a single element passed as varargs,
we now check if the argument is an array that is assignable to the
varargs array type.
- When converting an array supplied as the varargs, we now convert that
array to the varargs array type instead of the varargs component type.
Note, however, that a SpEL expression cannot provide a primitive array
for an Object[] varargs target. This is due to the fact that the
ArrayToArrayConverter used by Spring's ConversionService does not
support conversion from a primitive array to Object[] -- for example,
from int[] to Object[].
See gh-33191
Closes gh-33198
This change tracks the multipart nature of the async request
within the `DispatcherServlet`, in the `WebAsyncManager`.
This allows for the second ASYNC dispatch to recognize the
multipart aspect and clean up the associated resources.
Closes gh-33161
This commit makes sure that JAXBContext.newInstance consistently use
the target class classloader to detect the necessary resources.
Previously, the current thread's context classloader was used, which
could lead to not finding the required JAXB components.
Closes gh-33158
This commit makes sure that docs artifacts have their attributes set
for staging as well. Previously they were not and deployment of Javadoc
did not occur.
Closes gh-33204
This commit ensures that the varargs component type for a MethodHandle
cannot be null in ReflectionHelper's
convertAllMethodHandleArguments(...) method in SpEL.
Closes gh-33193
Prior to this commit, the Spring Expression Language (SpEL) could not
invoke a varargs MethodHandle function with an array containing the
variable arguments, although that is supported for a varargs Method
function. Attempting to do so resulted in the array being supplied as a
single argument to the MethodHandle.
This commit addresses this by updating the
executeFunctionViaMethodHandle(...) method in FunctionReference as
follows when the user supplies the varargs already packaged in an array.
- Creates a new array large enough to hold the non-varargs arguments
and the unpackaged varargs arguments.
- Adds the non-varargs arguments to the beginning of that array and
adds the unpackaged varargs arguments to the end of that array.
- Invokes the MethodHandle with the new arguments array.
Closes gh-33191
Previous to this change, the transactional aspect would supersed the
user-defined AspectJ aspect, shortcircuiting to calling the original
Kotlin suspending function.
This change simplifies the TransactionAspectSupport way of dealing with
transactional coroutines, thanks to the fact that lower level support
for AOP has been introduced in c8169e5c.
Closes gh-33095
Prior to this commit, the Spring Expression Language (SpEL) could not
invoke a varargs MethodHandle function with zero variable arguments,
even though the variable arguments are not required. Attempting to do
so resulted in a SpelEvaluationException with an
INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION message.
This commit addresses this by updating the
executeFunctionViaMethodHandle(...) method in FunctionReference so that
it properly checks the required number of arguments for both varargs
and non-varargs MethodHandle invocations.
This commit also improves the error message for varargs invocations
with too few arguments. For example, if the MethodHandle requires at
least 1 argument plus a variable number of additional arguments and 0
arguments were supplied, the error message now states:
"Incorrect number of arguments for function 'myFunc': 0 supplied but function takes 1 or more"
Instead of:
"Incorrect number of arguments for function 'myFunc': 0 supplied but function takes 2"
Closes gh-33190
This commit harmonizes the invocation of a bean supplier with what
SimpleInstantiationStrategy does. Previously, the current factory method
was set to `null` once the invocation completes. This did not take
into account recursive scenarios where an instance supplier triggers
another instance supplier.
For consistency, the thread local is removed now if we attempt to set
the current method to null. SimpleInstantiationStrategy itself uses
the shortcut to align the code as much as possible.
Closes gh-33180
Prior to this commit, the Spring Expression Language (SpEL) incorrectly
split single String arguments by comma for Object... varargs method and
constructor invocations.
This commit addresses this by checking if the single argument type is
already "assignable" to the varargs component type instead of "equal"
to the varargs component type.
Closes gh-33013
In preparation for releasing Spring Framework from GitHub actions, this
commit adds a `verify` workflow that validates that the released bits
are correct by running sample projects against them.
Closes gh-33178
This commit updates the CI workflow to build against Java 23-ea as
well, using the temurin distribution. For consistency, we're also
building against Java 22.
Closes gh-32090
This commit harmonizes our CI configuration with Spring Boot, in
particular the clever use of reusable custom actions that simplify
the workflow definition quite a bit.
One main difference compared to Spring Boot is that we can now
specify a different distribution for a Java version to test, in
preparation for the support of building against 23-ea
See gh-32090
Commit 84714fbae9 introduced usage of the
-Djava.locale.providers=COMPAT command-line argument for javac in order
to allow our JDK 20 builds to pass by using legacy locale data.
That was done to ensure that Date/Time formats using AM/PM produced a
standard space (" ") before the "AM" or "PM" instead of a narrow
non-breaking space (NNBSP "\u202F"), which was introduced in Java 20
due to adoption of Unicode Common Locale Data Repository (CLDR-14032).
This commit removes usage of the -Djava.locale.providers=COMPAT
command-line argument and updates all affected tests to:
- Use an NNBSP before "AM" or "PM" in input text when running on Java 20
or higher.
- Leniently match against any Unicode space character in formatted
values containing "AM" or "PM".
See https://jdk.java.net/20/release-notes#JDK-8284840
See https://unicode-org.atlassian.net/browse/CLDR-14032
See gh-30185
Closes gh-33144
When a response fails to be completely emitted by the remote (connection
termination during the transmission of the response for example), a
WebClientResponseException can be propagated with a confusing message
which mainly reflects the status code and reason phrase, leading to
messages like "200 OK" in such an exception.
This change improves the situation by appending a hint at the underlying
cause whenever getMessage() is called on a WebClientResponseException
which was created with a non-error status code.
Closes gh-33127
This change ensures that the cache error handler is used in case of
future-based or publisher-based asynchronous caching completing with an
exception.
Closes gh-33073
Prior to this commit, the fix for gh-32730 disabled the involvment of
the osbervation filter for async dispatches. Instead of relying on ASYNC
dispatches to close the observation for async requests, this is now
using an async listener instead: async dispatches are not guaranteed to
happen once the async request is handled.
This change caused another side-effect: because async dispatches are not
considered anymore by this filter, the observation scope is not
reinstated for async dispatches. For example, `ResponseBodyAdvice`
implementations do not have the observation scope opened during their
execution.
This commit re-enables async dispatches for this filter, but ensures
that observations are not closed during such dispatches as this will be
done by the async listener.
Fixes gh-33091
Fix argument in call to applyReturnValueValidation()
method in MethodValidationInterceptor.java. Method
argument was passed instead of the return value of the
method that was being validated.
See gh-33105
Prior to this commit, the "Method Arguments" documentation for WebFlux
in the reference manual stated that WebFlux controller methods can
accept arguments of type Map, Model, or ModelMap to access the model.
However, ModelMap is actually not supported and results in exception
due to a type mismatch.
This commit updates the documentation to reflect this.
In addition, this commit updates related Javadoc and tests to avoid
mentioning or using ModelMap in WebFlux.
Closes gh-33107
Prior to this commit, the comment in the XML configuration example in
the Method Injection section of the reference manual referred to the
wrong bean names.
Closes gh-33096
Prior to this commit, the `ProtobufMessageConverter` used in messaging
would try and serialize the message payload by calling "toString()" on
it in order to pass it to the Protobuf JSON encoder.
While this works for `String` payloads, this fails for `byte[]` types.
This commit ensures that such `byte[]` are first converted to `String`
instances using the given charset first.
Fixes gh-27408
Prior to this commit, RequestMappingViewResolutionIntegrationTests
invoked the following:
configurer.setTemplateLoaderPath(
"classpath*:org/springframework/web/reactive/view/freemarker/");
However, that configuration is invalid since `classpath*:` is not
supported for a `templateLoaderPath`.
Despite that, the tests still passed since FreeMarkerConfigurer already
registers a new ClassTemplateLoader(FreeMarkerConfigurer.class, ""),
which automatically finds template files in the same package as
FreeMarkerConfigurer (for the "spring.ftl" macro library support) and
coincidentally RequestMappingViewResolutionIntegrationTests as well
(which resides in the same package).
This commit therefore removes the invalid configuration and adds a
comment to explain what's going on.
Prior to this commit, the fix for gh-32575 introduced cases where the
client observation would be stopped twice.
This commit ensures that `RestClient` observations are stopped only once
when the response is closed, or before throwing an unhanlded exception.
Fixes gh-33068
Prior to this commit, the isClientDisconnectedException() method in
DisconnectedClientHelper checked whether the message of the ultimate
exception in an exception chain contained one of the phrases "broken
pipe" or "connection reset by peer". However, that failed to match if
the exception message contained "Connection reset", which is the case
for the SocketException thrown by throwConnectionReset() in
sun.nio.ch.SocketChannelImpl.
This commit therefore replaces the "connection reset by peer" phrase
with "connection reset" in order to support all exception messages
containing "connection reset".
Closes gh-33064
This commit changes the use of HttpSessionRequiredException in
ModelFactory::initModel to an IllegalStateException, because the former
extends ServletException and cannot be used in WebFlux.
Closes gh-33043
Prior to this commit, the `ContentCachingRequestWrapper` could allocate
a `FastByteArrayOutputStream` block that was larger than the content
cache limit given as a consturctor argument. This was due to an
optimization applied in gh-31834 for allocating the right content cache
size when the request size is known.
Fixes gh-32987
Prior to this commit, the `ServerHttpObservationFilter` would support
async dispatches and would do the following:
1. start the observation
2. call the filter chain
3. if async has started, do nothing
4. if not in async mode, stop the observation
This behavior would effectively rely on Async implementations to
complete and dispatch the request back to the container for an async
dispatch. This is what Spring web frameworks do and guarantee.
Some implementations complete the async request but do not dispatch
back; as a result, observations could leak as they are never stopped.
This commit changes the support of async requests. The filter now
opts-out of async dispatches - the filter will not be called for those
anymore. Instead, if the application started async mode during the
initial container dispatch, the filter will register an AsyncListener to
be notified of the outcome of the async handling.
Fixes gh-32730
Commit d7970e4ab8 introduced support for JAXBElement in
Jaxb2XmlEncoder's encodeValue() method; however, canEncode() still
returned false for a JAXBElement element type.
This commit revises canEncode() so that it returns true for an element
type that is assignable from JAXBElement.
See gh-30552
See gh-32972
Closes gh-32977
Prior to this commit, #31870 added support for constraint annotations on
container elements for handler method argument validation. Supporting
this use case:
```
public void addNames(List<@NotEmpty String> names)
```
This commit does the same for `@Valid` annotation:
```
public void addPeople(List<@Valid Person> people)
```
Fixes gh-32964
This commit updates
PersistenceManagedTypesBeanRegistrationAotProcessor
in order to infer hints for Hibernate annotations meta
annotated with `@ValueGenerationType` (like `@CreationTimestamp`)
and `@IdGeneratorType`.
`@GenericGenerator` is not supported as it is deprecated as of
Hibernate 6.5.
Closes gh-32842
Prior to this commit, the Spring Expression Language (SpEL) failed to
compile an expression that indexed into a Map using a primitive literal
(boolean, int, long, float, or double).
This commit adds support for compilation of such expressions by
ensuring that primitive literals are boxed into their corresponding
wrapper types in the compiled bytecode.
Closes gh-32903
Prior to this commit, the Spring Expression Language (SpEL) failed to
compile an expression that indexed into any array or list using an
Integer.
This commit adds support for compilation of such expressions by
ensuring that an Integer is unboxed into an int in the compiled
bytecode.
See gh-32694
Closes gh-32908
Prior to this commit, the Gradle build issued the following warning.
- The deprecated "gradleEnterprise.buildScan.value" API has been
replaced by "develocity.buildScan.value"
- Use same playbook as docs-build
- Use Env Variables to cause partial build (same as docs-build)
- Use package.json so that dependencies can be updated with dependabot
Includes JAXBContext locking revision (avoiding synchronization) and consistent treatment of DocumentBuilderFactory (in terms of caching as well as locking).
Closes gh-32851
This commit updates Spring AOT to suppress a deprecation warning for
a generic type that has a deprecated element. Previously we only were
checking for the raw class.
Closes gh-32850
This commit avoids several instances of MockHttpServletRequest to
have a common reader for empty content as closing it will have an
unwanted side effect on the others.
Closes gh-32820
Prior to this commit, the `ReactiveTypeHandler` would handle `Flux`-like
return types from controller methods and adapt them to SSE streams using
the `SseEmitter`/`ResponseBodyEmitter` APIs. In case an `IOException` is
thrown while writing to the HTTP response stream, the
`ReactiveTypeHandler` would rely on the Servlet container to call
`AsyncListener#onError` - this would be the signal for Spring MVC to
complete the async exchange. To prevent racing issues between this
signal and the actual handling of the exception, changes like gh-20173
were applied. Since then, robust checks were added with gh-32340 in
`StandardServletAsyncWebRequest.LifecycleHttpServletResponse`.
With Jetty 12, `AsyncListener#onError` would not be called as the error
would happen while writing in blocking mode to the response (so, not
using the Servlet WriteListener contract). But still, such `IOException`
would still result in the closing of the HTTP connection. As of Jetty
12.0.4, this is no longer the case and the party managing the async
lifecycle is in charge of completing the exchange, as it should. This
means that the current behavior leaks HTTP connections for these cases
and causes memory issues.
This commit ensures that such exceptions happening during response
writes are caught and result in the completion of the `SSEEmitter` and
the closing of the exchange. Even if other Servlet containers still
propagate the error `AsyncListener#onError`, competing signals are still
managed with gh-32340.
Closes gh-32629
This commit fixes links from Spring Framework's Dokka HTML to Javadoc
for Spring Framework and Servlet APIs by explicitly configuring the
`element-list` page as the `package-list` in the Dokka Gradle plugin.
Closes gh-32797
A bug has existed in Spring's MergedAnnotations support since it was
introduced in Spring Framework 5.2. Specifically, if the
MergedAnnotations API is used to search for annotations with "standard
repeatable annotation" support enabled (which is the default), it's
possible to search for a repeatable annotation but not for the
repeatable annotation's container annotation.
The reason is that MergedAnnotationFinder.process(Object, int, Object,
Annotation) does not process the container annotation and instead only
processes the "contained" annotations, which prevents a container
annotation from being included in search results.
In #29685, we fixed a bug that prevented the MergedAnnotations support
from recognizing an annotation as a container if the container
annotation declares attributes other than the required `value`
attribute. As a consequence of that bug fix, since Spring Framework
5.3.25, the MergedAnnotations infrastructure considers such an
annotation a container, and due to the aforementioned bug the container
is no longer processed, which results in a regression in behavior for
annotation searches for such a container annotation.
This commit addresses the original bug as well as the regression by
processing container annotations in addition to the contained
repeatable annotations.
See gh-29685
Closes gh-32731
Prior to this commit, HTTP requests sent with the
`HttpComponentsClientHttpRequestFactory` would not set a
"Content-Length" header for empty request bodies. Setting a request
entity is the expected behavior for unsafe HTTP methods, and this would
align the behavior with other HTTP clients.
Developers would often rely on `BufferingClientHttpRequestFactory` to
set this information on the request.
This commit ensures that a `NullEntity` is used for unsafe HTTP methods,
when no body has been set for the request. This result in a
"Content-Length:0" request header.
Fixes gh-32678
This commit changes the guard against multiple subscriptions, as the
previously used doOnSubscribe hook could not function as guard in
certain scenarios.
Closes gh-32727
This commit counterbalances the retain in the MessagingRSocket
handleConnectionSetupPayload method with a conditional release on SETUP
frame type in handleNoMatch, preventing Netty buffer leaks.
Closes gh-32424
This commit refines the preDetermineBeanTypes algorithm that AOT uses
to approximate the order of preInstantiateSingletons more closely.
Previously, the algorithm assumed that all beans where non-lazy
singletons in terms of initialization order, which led to inconsistent
order in CGLIB proxy generation.
We now explicitly park lazy beans so that their types are determined
during a second phase, matching the order of regular initialization
order.
Closes gh-32669
Co-authored-by: Juergen Hoeller <juergen.hoeller@broadcom.com>
Previously, a UriComponents build based on a method would require the
given method to be the annotated one as method parameter resolution only
applied locally. This was a problem when a controller was specified on
a method whose mapping is defined in a parent.
This commit harmonies the lookup using AnnotatedMethod who provides
support for a synthesized method parameter that takes annotations from
parent parameter into account.
Closes gh-32553
Previously, a BeanDefinition that has an instance supplier would be
used irrespective of custom arguments being provided. This commit only
applies the instance supplier if no arguments are provided. With
custom arguments, the regular lookup takes place based on the
information provided in the bean factory.
Closes gh-32657
Previously, if a factory method is defined on a parent, the generated
code would blindly use the method's declaring class for both the target
of the generated code, and the signature of the method.
This commit improves the resolution by considering the factory metadata
in the BeanDefinition.
Closes gh-32609
Prior to this commit, `RestClientException` thrown by status handlers
would not be registered as observation errors. This commit ensures that
such exceptions are first caught, registered in the observation and
rethrown as expected.
Closes gh-32575
Prior to this commit, the `RestClient` observations would be stopped as
soon as the exchange function was called. This means that all errors
related to response decoding or mapping would not be recorded by the
obsevations.
This commit extends the observation recording to the `ResponseSpec` DSL
calls as well as custom exchange functions.
Fixes gh-32575
Prior to this commit, the `BufferingClientHttpRequestFactory`, through
the `AbstractBufferingClientHttpRequest`, would set a "Content-Length"
header value, even if the buffered body was empty.
This behavior is invalid since no request body would be set by the
client code in the first place.
This commit ensures that this header is only set if a request body has
been buffered and is about to be written to the request.
Fixes gh-32650
This commit rephrases the `DefaultTransactionDefinition#setTimeout`
exception message to better reflect the fact that 0 is a valid input
value.
Even though this often leads to a transaction immediately timing out
after opening, there is one notable case where this has another
meaningful effect: in Jakarta transactions (`UserTransaction`), when
passing 0 "the transaction service restores the default value".
Closes gh-32635
This change improves the message of several parsing-related exceptions
that would previously entirely swallow the original exception's message
and sometimes have a slightly misleading message as a result.
This is done by appending the cause's `toString` representation to the
IllegalArgumentException messages instead of an hardcoded "cause".
Closes gh-32636
Before this change temporary files would not consistently be deleted
when the connection which uploads the multipart files closes naturally.
This change uses the usingWhen Reactor operator to ensure that the
termination of the connection doesn't prevent individual file parts
from being deleted due to a cancellation signal.
Closes gh-31217
This commit refines the expressions for the scheme, user info, host and
port parts of the URL in UriComponentsBuilder to better conform to
RFC 3986.
Fixes gh-32616
Prior to this commit, `BufferingClientHttpRequestWrapper` would always
write to the actual client request body, even if the buffered content
was empty (empty byte array).
This would cause issues with specific client request factories,
especially the OkHttp variant, that would consider empty byte arrays as
non-empty body and would reject such cases for GET requests with an
"IllegalArgumentException: method GET must not have a request body".
This commit only writes to the request if the buffered content is not
empty.
Fixes gh-32612
Prior to this commit, MethodIntrospector failed to properly detect
bridge methods for subsequent invocations of selectMethods() with the
same targetType and MetadataLookup, if such subsequent invocations
occurred after the ApplicationContext had been refreshed.
The reason this occurs is due to the following.
- Class#getDeclaredMethods() always returns "child copies" of the
underlying Method instances -- which means that `equals()` should be
used instead of `==` whenever the compared Method instances can come
from different sources (such as the static caches mentioned below).
- BridgeMethodResolver caches resolved bridge methods in a static cache
-- which is never cleared.
- ReflectionUtils caches declared methods in a static cache
-- which gets cleared when an ApplicationContext is refreshed.
Consequently, if you attempt to load an ApplicationContext twice in the
same ClassLoader, the second attempt uses the existing, populated cache
for bridged methods but a cleared, empty cache for declared methods.
This results in new invocations of Class#getDeclaredMethods(), and
identity checks with `==` then fail to detect equivalent bridge methods.
This commit addresses this by additionally comparing bridge methods
using `equals()` in MethodIntrospector.selectMethods().
Note that the `==` checks remain in place as an optimization for when
`equals()` is unnecessary.
Closes gh-32586
Prior to this commit, the `JmsTemplate#sendAndReceive` method would not
instrument the JMS session. This means that no metric would be recorded
when sending the message and no trace would be propagated downstream.
This commit ensures that the JMS session is instrumented in this case as
well. Note, the reception of the response message does not create a
`"jms.message.process"` observation as the session is only receiving the
message, no listener has been configured on the message consumer.
Fixes gh-32606
This commit ensures that the response body is drained and closed when
the response itself is closed, instead of disposing the connection, as
this will disable the connection pool.
Closes gh-32528
This commit reverts some null-safety changes which make sense
on main but are too impactful for 6.1.x for Kotlin developers
using -Xjsr305=strict.
See gh-32475
This commit ensures that `InvocableHandlerMethod` executes the method
on the desired thread if a non-blocking thread is specified, even in the
case where arguments resolution happens on a different thread. This is
notably the case if the method body is resolved as an input argument to
the controller method (`@RequestBody`).
Closes gh-32502
Prior to this commit, SpEL's CompoundExpression omitted the null-safe
syntax in AST string representations of the selection and projection
operators.
To address this, this commit implements isNullSafe() in Projection and
Selection.
Closes gh-32515
Prior to this commit, MethodReference and PropertyOrFieldReference
already defined local isNullSafe() methods, but we need identical
methods in Selection, Projection, and Indexer, and we may potentially
need null-safe support for additional operators in the future.
To address the common need for an is-null-safe check, this commit
introduces an isNullSafe() method in SpelNodeImpl with a default
implementation that returns false.
Closes gh-32516
The fix for #31254 resulted in an InvalidMimeTypeException being thrown
by MimeTypeUtils.sortBySpecificity() instead of an
IllegalArgumentException. However, InvalidMimeTypeException extends
IllegalArgumentException. Consequently, the change from
IllegalArgumentException to InvalidMimeTypeException did not result in
the desired effect in HeaderContentNegotiationStrategy.
HeaderContentNegotiationStrategy.resolveMediaTypes() still allows the
InvalidMimeTypeException to propagate as-is without wrapping it in an
HttpMediaTypeNotAcceptableException.
To address this issue, this commit catches InvalidMediaTypeException
and InvalidMimeTypeException in HeaderContentNegotiationStrategy and
wraps the exception in an HttpMediaTypeNotAcceptableException.
See gh-31254
See gh-31769
Closes gh-32483
There is no way to consistently test this use case because listener
container implementations have different behavior for unhandled errors
and might retry or close the container altogether.
See gh-32458
Prior to this commit, when using the `DefaultMessageListenerContainer`
as a backing listener container for JMS messages, the instrumentation
would not record JMS exceptions as observation errors when they were not
handled by configured `ErrorHandler`.
This commit ensures that this is the case.
Fixes gh-32458
Prior to this commit, gh-31609 added the current observation context as
a request attribute for `WebClient` calls. While it was not confirmed as
the main cause, this feature was linked to several reports of memory
leaks. This would indeed attach more memory to the request object graph
at runtime - although it shouldn't prevent its collection by the GC.
This commit removes this feature and instead developers should get the
current observation from the reactor context if they wish to interact
with it.
Closes gh-32198
Prior to this commit, error signals flowing from the client response
publisher in `WebClient` would be set on the `Observation.Context`. This
is enough for the observation convention to collect data about the error
but observation handlers are not notified of this error.
This commit sets the error instead on the observation directly to fix
this issue.
Fixes gh-32389
webmvc.fn now also uses the StandardServletAsyncWebRequest wrapped response
to enforce lifecycle rules from Servlet spec (section 2.3.3.4).
See gh-32340
KClass instantiation in CoroutinesUtils is suboptimal, and should be
replaced by KTypes#isSubtypeOf checks using pre-instantiated types for
Flow, Mono and Publisher.
This commit impact on performances is significant since a throughput
increase between 2x and 3x has been measured on basic endpoints.
Closes gh-32390
This commit fixes an issue where a Cacheable method which returns a
Flux (or multi-value publisher) will be invoked once, but the returned
publisher is actually subscribed twice.
The previous fix 988f3630c would cause the cached elements to depend on
the first usage pattern / request pattern, which is likely to be too
confusing to users. This fix reintroduces the notion of exhausting the
original Flux by having a second subscriber dedicated to that, but uses
`refCount(2)` to ensure that the original `Flux` returned by the cached
method is still only subscribed once.
Closes gh-32370
Also fix a couple of related issues:
- add AsyncRequestNotUsableException to the list of exceptions
that imply response issues.
- handle exceptions from @ExceptionHandler regardless of whether
thrown immediately or via Publisher.
Closes gh-32359
This commit fixes an issue where a Cacheable method which returns a
Flux (or multi-value publisher) will be invoked once, but the returned
publisher is actually subscribed twice.
By using the Reactor `tap` operator, we ensure that we can emit values
downstream AND accumulate emitted values into the List with a single
subscription.
The SignalListener additionally handles scenarios involving cancel,
for instance in case of a `take(1)` in the chain. In that case values
emitted up until that point will have been stored into the List buffer,
so we can still put it in the cache. In case of error, no caching occurs
and the internal buffer is cleared. This implementation also protects
against competing onComplete/onError signals and cancel signals.
Closes gh-32370
The following adjustments are also made as a result:
- Use int to check if lock is held and unlock is needed, given that
for non-async requests we don't need to obtain a lock.
- Protect access methods getOutputStream and getWriter with the
same locking and state checks.
Closes gh-32340
ServletResponseHttpHeaders#get should be annotated with `@Nullable` and
return null instead of a singleton list containing null when there is no
content type header.
Closes gh-32362
In addition to using the ServletOutputStream, it's also possible to call
ServletResponse#flushBuffer, so the ServletOutputStream wrapper logic needs
to apply there as well.
See gh-32340
The wrapped response prevents use after AsyncListener onError or completion
to ensure compliance with Servlet Spec 2.3.3.4.
The wrapped response is applied in RequestMappingHandlerAdapter.
The wrapped response raises AsyncRequestNotUsableException that is now
handled in DefaultHandlerExceptionResolver.
See gh-32340
Prior to this commit, if a Spring Expression Language (SpEL) expression
referenced the root context object via the #root or #this variable, we
inserted a checkcast in the generated byte code that cast the object to
its concrete type. However if the root context object's type was
non-public, that resulted in an IllegalAccessError when the compiled
byte code was executed.
VariableReference.getValueInternal() already contains a solution for
global variables which inserts a checkcast to Object in the generated
byte code instead of to the object's concrete non-public type.
This commit therefore applies the same logic to #root (or #this when
used to reference the root context object) that is already applied to
global variables.
Closes gh-32356
This commit refines WebMVC and WebFlux argument resolution in order to
convert properly Kotlin value class arguments by using the type of the
value instead of the type of the value class.
Closes gh-32353
The HttpHeaders.getAcceptLanguageAsLocales was incurring overhead from
using a Stream, as well as calling the fairly expensive
Locale.getDisplayName method.
Switch to using an ArrayList, and skipping over wildcard ranges to avoid
needing to check the display name.
Closes gh-32318
This commit fixes a performance regression caused by gh-31698,
and more specifically by KClass#isValue invocations which are slow since
they load the whole module to find the class to get the descriptor.
After discussing with the Kotlin team, it has been decided that only
checking for the presence of `@JvmInline` annotation is enough for
Spring use case.
As a consequence, this commit introduces a new
KotlinDetector#isInlineClass method that performs such check, and
BeanUtils, CoroutinesUtils and WebMVC/WebFlux InvocableHandlerMethod
have been refined to leverage it.
Closes gh-32334
For consistency with other examples, this commit omits `method` parameter
names in the "Migrating from RestTemplate to RestClient" section of the
reference docs.
Closes gh-32335
Based on feedback from several members of the community, we have
decided to revert the caching of the Content-Type header that was
introduced in ContentCachingResponseWrapper in 375e0e6827.
This commit therefore completely removes Content-Type caching in
ContentCachingResponseWrapper and updates the existing tests
accordingly.
To provide guards against future regressions in this area, this commit
also introduces explicit tests for the 6 ways to set the content length
in ContentCachingResponseWrapper and modifies a test in
ShallowEtagHeaderFilterTests to ensure that a Content-Type header set
directly on ContentCachingResponseWrapper is propagated to the
underlying response even if content caching is disabled for the
ShallowEtagHeaderFilter.
See gh-32039
Closes gh-32317
Prior to this commit, getHeaderNames() returned duplicates for the
Content-Type and Content-Length headers if they were set in the wrapped
response as well as in ContentCachingResponseWrapper.
This commit fixes that by returning a unique set from getHeaderNames().
In addition, this commit introduces a new test in
ContentCachingResponseWrapperTests to verify the expected behavior for
Content-Type and Content-Length headers that are set in the wrapped
response as well as in ContentCachingResponseWrapper.
See gh-32039
See gh-32317
Commit 375e0e6827 introduced a regression in
ContentCachingResponseWrapper (CCRW). Specifically, CCRW no longer
honors Content-Type and Content-Length headers that have been set on
the wrapped response and returns null for those header values if they
have not been set directly on the CCRW.
This commit fixes this regression as follows.
- The Content-Type and Content-Length headers set in the wrapped
response are honored in getContentType(), containsHeader(),
getHeader(), and getHeaders() unless those headers have been set
directly on the CCRW.
- In copyBodyToResponse(), the Content-Type in the wrapped response is
only overridden if the Content-Type has been set directly on the CCRW.
See gh-32039
Closes gh-32317
This commit adapts Hibernate native support to handle
the changes performed as part of HHH-17643 which impacts
Hibernate versions 6.4.3+ and 6.2.21+.
It ignores the BytecodeProvider services loaded by the
service loader feature in order to default to the
"no-op" provider with native, and makes the substitutions
more lenient when a substituted field or method does not
exist.
gh-32314 is expected to remove the need for such
substitutions which are not great for maintainability
by design.
Closes gh-32311
This commit revisits the improved detection algorithm for stored
procedure as, unfortunately, certain JDBC drivers do not support
the documented pattern for schema and procedure name.
To work around this limitation, this commit applies the escaping of
wildcard characters to the case where multiple procedures have been
found for a given search.
Closes gh-32295
Delegate to the spliterator method of the underlying collection in
MutablePropertyValues and MutablePropertySources. In both cases, those
collection types have specialized Spliterator implementations.
Delegating to these Spliterators also means the characteristics of the
Spliterator are properly set.
See gh-32281
Prior to this commit, the SseBuilder API in WebMvc.fn would only allow
to send Server-Sent Events with `data:` items in them. The spec doesnn't
disallow this and other specifications rely on such patterns to signal
the completion of a stream, like:
```
event:next
data:some data
event:complete
```
This commit adds a new `send()` method without any argument that sends
the buffered content (id, event comment and retry) without data.
Fixes: gh-32270
Although EvaluationContext defines the API for setting and looking up
variables, the internals of the Spring Expression Language (SpEL)
actually provide explicit support for registering functions as
variables.
This is self-evident in the two registerFunction() variants in
StandardEvaluationContext; however, functions can also be registered as
variables when using the SimpleEvaluationContext.
Since custom functions are also viable in use cases involving the
SimpleEvaluationContext, this commit documents that functions may be
registered in a SimpleEvaluationContext via setVariable().
This commit also explicitly documents the "function as a variable"
behavior in the class-level Javadoc for both StandardEvaluationContext
and SimpleEvaluationContext, as well as in the reference manual.
Closes gh-32258
This notably enables Jackson to reflectively call a user-provided
builder class and invoke its declared methods (setters and build) in
a native app.
Closes gh-32238
The cancellation of read and write inactivity tasks was done via
WebSocketHandler#afterConnectionClosed, relying on the WebSocket
library to always invoke the callback.
This change moves the cancellation to the `close` method instead
that in turn is called from DefaultStompSession#resetConnection,
in effect making the cancellation more proactive and aligned with
connection cleanup in DefaultStompSession vs relying on a
subsequent call from the WebSocket library after the connection
is closed.
Closes gh-32195
ConnectionLostException was applies only after the WebSocket library
notified us of a session close. However, read inactivity and heartbeat
send failures are also cases of the connection being lost rather than
closed intentionally.
This commit also ensures resetConnection is called after a heartbeat
write failure, consistent with other places where a transport error
is handled that implies the connection is lost.
See gh-32195
This commit focuses on improving the AOT section on programmatic
registration of additional beans. This makes it more clear that a
`BeanDefinitionRegistry` must be used and that singletons are not
processed.
Closes gh-32240
Closes gh-32241
This commit introduces new HTTP method, Content-Type, and Accept header
request predicates that handle single values. Previously, these
predicates were always dealt with as single-value collections, which
introduced computational overhead.
Closes gh-32244
Previously, RestClientAdapter claimed that it supports request
attributes when, in fact, it does not. This commit updates the
implementation accordingly.
See gh-32232
Schedulers remain strict, just plain executors are lenient on shutdown now.
An early shutdown for executors can be enforced via setStrictEarlyShutdown.
Closes gh-32226
Fix another instance where a LinkedHashMap was initialized with an initial
capacity that would always cause a resize / rehash to occur. Switch to
CollectionUtils.newLinkedHashMap to size the map appropiately for the expected
number of items.
Closes gh-32215
Prior to this commit, the `RequestPredicates` would add new attributes
to the existing request attributes by creating a new `LinkedHashMap`
with the total number of elements as its new initial capacity.
This would not achieve optimal performance as initial resize or rehash
operations could be expected. Consistently using
`CollectionUtils#newLinkedHashMap` avoids this problem.
Closes gh-32201
ServletAttributesMap inherited default implementations of the size
and isEmpty methods from AbstractMap which delegates to the Set returned
by entrySet. ServletAttributesMap's entrySet method made this fairly
expensive, since it would copy the attributes to a List, then use a
Stream to build the Set. To avoid the cost, add implementations of
isEmpty / size that don't need to call entrySet at all.
Additionally, change entrySet to return a Set view that simply lazily
delegates to the underlying servlet request for iteration.
Closes gh-32189
This commit ensures that, when creating a RestClient.Builder from a
RestTemplate, the UriBuilderFactory is only copied if it has been
changed from the default values.
Before this commit, the UriBuilderFactory was effectively alway copied,
resulting in not being able to use a baseUrl.
This commit also introduces a small memory optimization in
DefaultUriBuilderFactory, so that default environment variables are
created lazily.
Closes gh-32180
This commit replaces occurrences of modelAttribitePredicate with modelAttributePredicate
in HandlerMethodValidationException and the associated validator.
Closes gh-32183
As a bit of trivia, Jakarta EL was originally Unified EL, which was
originally JSP EL, which was originally SPEL.
SPEL: Simplest Possible Expression Language
SpEL: Spring Expression Language
So one could say that SPEL inspired SpEL.
This commit introduces a globally applied Checkstyle rule which
enforces the use of class literals for primitive types and void by
forbidding the use of the TYPE constants in Boolean, Character, Byte,
Short, Integer, Long, Float, Double, and Void.
For example, if MyClass uses one of the TYPE constants, the build will
now fail with a message similar to the following.
[ERROR] <...>/MyClass.java:39: Please use class literals for primitives and void -- for example, int.class instead of Integer.TYPE.
This commit improves PersistenceManagedTypesBeanRegistrationAotProcessor
so that it does not attempt to load JPA classes when checking for the
presence of a PersistenceManagedTypes bean. To make it more clear a
check on the presence for JPA has been added to prevent the nested
classes to be loaded regardless of the presence of the bean.
Closes gh-32155
To improve consistency and avoid confusion regarding primitive types
and their wrapper types, this commit ensures that we always use class
literals for primitive types.
For example, instead of using the `Void.TYPE` constant, we now
consistently use `void.class`.
Prior to this commit, SpEL's Indexer incorrectly requested conversion
to wrappers instead of primitives when setting an element in a
primitive array.
This commit addresses this by requesting primitive conversion -- for
example, conversion to `int.class` instead of `Integer.class` when
setting a value in an `int[]` array.
For greater clarity, this commit also switches from using `TYPE`
constants in wrapper classes to primitive class literals -- for
example, from `Integer.TYPE` to `int.class`.
Closes gh-32147
Since SpEL is no longer "in progress", this commit removes the obsolete
InProgressTests class and moves all non-duplicated test cases to other
test classes.
This commit harmonizes SimpleJdbcCall and SimpleJdbcInsert to
consistently use a catalog name if one is set. Previously,
SimpleJdbcInsert only used the catalog name to retrieve database
metadata.
Closes gh-32124
Prior to this commit, only the MethodFilter and ConstructorResolver
functional SPIs in the org.springframework.expression package were
annotated with @FunctionalInterface.
For consistency, this commit designates each of the following
functional SPIs in that package as a @FunctionalInterface as well.
- BeanResolver
- ConstructorExecutor
- MethodExecutor
- MethodResolver
Closes gh-32135
This commit introduces a new method to configure an existing
TaskExecutor in ChannelRegistration. Contrary to
TaskExecutorRegistration, a ThreadPoolTaskExecutor is not necessary,
and it can't be further configured. This includes the thread name
prefix.
Closes gh-32081
Before this commit, the JDK and Jetty connectors do not have any
safeguards against multiple body subscriptions. Such as check has now
been added.
Closes gh-32100
Since the bug in JDK 22-ea builds has been fixed [1], this commit
re-enables the disabled tests.
Verified using: OpenJDK Runtime Environment (build 22-ea+31-2314)
[1] https://bugs.openjdk.org/browse/JDK-8322214
The behavior for the toString() implementation for annotations changed
in JDK 19, per my request to the JDK team (see link below).
Specifically, since JDK 19, the toString() implementation for annotation
proxies created by the JDK started using canonical names instead of
binary names for types.
See https://bugs.openjdk.org/browse/JDK-8281462
Prior to this commit, the `RestTemplate` observation instrumentation
would only record `RestClientException` and `IOException` as errors in
the observation. Other types of errors can be thrown by custom
components, such as `ResponseErrorHandler` and in this case they aren't
recorded with the observation.
Also, the current instrumentation does not create any observation scope
around the execution. While this would have a limited benefit as no
application code is executed there, developers could set up custom
components (such as, again, `ResponseErrorHandler`) that could use
contextual logging with trace ids.
This commit ensures that all `Throwable` are recorded as errors with the
observations and that an observation `Scope` is created around the
execution of the client exchange.
Fixes gh-32060
This commit revises the RequestMappingHandlerMapping implementations in
Spring MVC and Spring WebFlux to ensure that a @Controller class which
implements an interface annotated with @HttpExchange annotations can
inherit the @HttpExchange declarations from the interface or
optionally override them locally with @HttpExchange or
@RequestMapping annotations.
Closes gh-32065
This commit updates the RequestMappingHandlerMapping implementations in
Spring MVC and Spring WebFlux so that mixed @RequestMapping and
@HttpExchange declarations on the same element are rejected.
Note, however, that a @Controller class which implements an interface
annotated with @HttpExchange annotations can still inherit the
@HttpExchange declarations from the interface or optionally override
them locally with @HttpExchange or @RequestMapping annotations.
See gh-31962
See gh-32049
Closes gh-32065
This commit makes sure that, when building a RestClient based on the
configuration of a RestTemplate, the request factory is unwrapped if it
is a InterceptingClientHttpRequestFactory.
Closes gh-32038
This commit ensures that setting the Content-Length through
setHeader("Content-Length", x") has the same effect as calling
setContentLength in the ShallowEtagHeaderFilter. It also filters out
Content-Type headers similarly to Content-Length.
Closes gh-32039
This commit updates the RequestMappingHandlerMapping implementations in
Spring MVC and Spring WebFlux so that multiple @HttpExchange
declarations on the same element are rejected.
Closes gh-32049
If multiple request mapping annotations are discovered, Spring MVC and
Spring WebFlux now log a warning similar to the following (without
newlines).
Multiple @RequestMapping annotations found on
void org.example.MyController.put(), but only the first will be used:
[
@org.springframework.web.bind.annotation.PutMapping(consumes={}, headers={}, name="", params={}, path={"/put"}, produces={}, value={"/put"}),
@org.springframework.web.bind.annotation.PostMapping(consumes={}, headers={}, name="", params={}, path={"/put"}, produces={}, value={"/put"})
]
Closes gh-31962
Prior to this commit, the alias resolution error message in
SimpleAliasRegistry was misleading.
When a resolution conflict is detected, the IllegalStateException
thrown by resolveAliases(...) now states that the resolved alias is
already registered for an `existingName` instead of the `registeredName`.
See gh-31353
Closes gh-32025
This commit improves SimpleAliasRegistryTests in the following ways.
- Some existing methods have been split up into smaller test methods
which focus on a single use case.
- The use of Mockito mocks has been replaced by a hand-crafted
StubStringValueResolver which ensures that existing aliases and names
are not accidentally replaced by null thereby removing their removing
there mappings inadvertently.
- Several test methods now include inline comments that document the
current state of the aliasMap in order to clarify what is happening
behind the scenes in the ConcurrentHashMap.
- Several test methods warn that the current expectations are based on
ConcurrentHashMap iteration order!
- New @ParameterizedTest which is currently @Disabled but
demonstrates that complex use cases involving placeholder replacement
can be supported consistently -- regardless of the values of the
aliases involved -- but only if alias registration order is honored.
Closes gh-31353
This commit documents the following Spring properties in the reference
manual.
- spring.aot.enabled
- spring.cache.reactivestreams.ignore
- spring.classformat.ignore
- spring.context.checkpoint
- spring.context.exit
Closes gh-31987
This commit updates ContentRequestMatchers#multipartData
Javadoc to mention Tomcat fork of Commons FileUpload library
instead of the original variant.
It also adds a similar note to
ContentRequestMatchers#multipartDataContains.
Closes gh-31988
ResponseEntityExceptionHandler should not set the exception attribute
when there is a response body, and the response is fully handled.
Closes gh-31541
This commit introduces support for a Spring property named
`spring.context.expression.maxLength`. When set, the value of that
property is used internally in StandardBeanExpressionResolver to
configure the SpelParserConfiguration used when evaluating String
values in bean definitions, @Value, etc.
Closes gh-31952
This change moves container element properties from ParameterErrors
to base class ParameterValidationResult, and makes that support
independent of whether violations are nested within a container
element bean or through constraints on container elements, e.g.
`List<@NotBlank String>`.
Closes gh-31887
This is able to resolve the original method even if no bridge method has been generated at the same class hierarchy level (a known difference between the Eclipse compiler and regular javac).
Closes gh-21843
Includes TypeVariable bypass for reflection-free annotation retrieval.
Includes info log message for annotation attribute retrieval failure.
Closes gh-27182
This commit adds CORS support for Private Network Access
by adding an Access-Control-Allow-Private-Network response
header when the preflight request is sent with an
Access-Control-Request-Private-Network header and that
Private Network Access has been enabled in the CORS
configuration.
See https://developer.chrome.com/blog/private-network-access-preflight/
for more details.
Closes gh-28546
This commit makes sure to resolve placeholders in request mappings
using the EmbeddedValueResolver of the current WebApplicationContext.
To avoid retrieving the context too often, we check for the presence of
the standard placeholder prefix.
Closes gh-26795
To align with the existing processInjection() method in
AutowiredAnnotationBeanPostProcessor, this commit introduces an analogous
method in CommonAnnotationBeanPostProcessor.
Closes gh-31956
This commit implements Cookie support in WebFlux without any workaround
as now all supported servers have the SameSite feature enabled.
Closes gh-31954
Includes differentiation between lenient and fixed execution.
Includes default time zone resolution from scheduler-wide Clock.
Closes gh-19475
Closes gh-31948
Prior to this commit, the `HandlerMappingIntrospector` would comparea
request with a cached request by using `String#matches` on their String
URI. This could lead to `PatternSyntaxException` exceptions at runtime
if the request URI contained pattern characters.
This commit fixes this typo to use `String#equals` instead.
Fixes gh-31937
This commit updates the description of RequestHandledEvent to avoid
providing a misleading status as the absence of a failure logs OK which
can be inaccurate.
Closes gh-27595
This commit adds Javadoc to the `getContentLength` method of
`MockHttpServletResponse` to reflect that it gets its value from the
HTTP response header.
Closes gh-31833
This commit adds a functional style registration of an application
listener for a particular event. Rather than introducing another method
at the ConfigurableApplicationContext interface level, this commit
provides a factory method in GenericApplicationListener.
Closes gh-21411
Prior to this commit, the `DefaultScheduledTaskObservationConvention`
would fail as it tried to add a `KeyValue` to the observation context
that is `null`. This is rejected by the observation registry and should
be prevented. This happened when registered scheduled methods were
lambdas or part of anonymous classes. Those types do not have a
canonical name and return `null` as a value there.
This commit ensures that for these cases, the default convetion uses a
`"ANONYMOUS"` value as the `"code.namespace"` keyvalue.
Fixes gh-31918
Upgrading leads to to WebClientIntegrationTests to fail with Jetty and
the build does not complete properly. This commit reverts the upgrade.
See gh-31931
* pr/31916:
Upgrade copyright year of changed files
Polish "Replace if with switch where feasible"
Replace if with switch where feasible
Use Map.computeIfAbsent() where feasible
Polish "Use Object.equals() where feasible"
Use Object.equals() where feasible
Polish "Use diamond operator where feasible"
Use diamond operator where feasible
Use auto boxing and unboxing where feasible
Use enhanced for loop where feasible
Polish "Use text block where feasible"
Use text block where feasible
Polish "Use String.repeat() where feasible"
Use String.repeat() where feasible
Polish "Remove unnecessary final modifier"
Remove unnecessary final modifier
Closes gh-31916
This commit fixes the Hibernate dialect lookup for SQLServer as it was
previously using a dialect that has been deprecated. In recent
versions, the standard SQLServerDialect is the one we should be using.
Closes gh-31896
Prior to this commit, the `ForwardedHeaderFilter` and the forwarded
header utils would throw `IllegalArgumentException` and
`IllegalStateException` when request headers are invalid and cannot be
parsed for Forwarded handling.
This commit aligns the behavior with the WebFlux counterpart by
rejecting such requests with HTTP 400 responses directly.
Fixes gh-31842
This commit fixes the Hibernate dialect lookup for Oracle as it was
previously using a dialect that has been moved and deprecated to a
separate project. In recent versions, the standard OracleDialect is the
one we should be using.
Closes gh-31892
This commit fixes the Hibernate dialect lookup for MySQL as it was
previously using a deprecated dialect that has been removed in the most
recent Hibernate version.
Closes gh-31889
After the updates to MethodValidationAdapter in commit d7ce13 related
to method validation on element containers, we also need to adjust
the checks in HandlerMethod when method validation applies.
See gh-31746
This commit restores support for Kotlin extensions in
web handlers, and adds support for invoking reflectively
suspending extension functions, as well as the other
features supported as of Spring Framework 6.1 like
value classes and default value for parameters.
Closes gh-31876
The goal for #31530 was to support bean validation on Set and other
method parameters that are containers of value(s) for which there is
a registered Jakarta Validation ValueExtractor.
Unfortunately, bean validation does not expose the unwrapped value
for a Path.Node, which we need for a method parameter in order to
create a BindingResult for the specific bean within the container,
and the leafBean that we tried to use is really the node at the
very bottom of the property path (i.e. not what we need).
This change removes the use of beanLeaf, restores the logic as it
was before, adds support for arrays, and a new test class for
scenarios with cascaded violations.
See gh-31746
Prior to this commit, the `WebHttpHandlerBuilder` would only configure
a custom observation convention if there is a single convention in the
application context. It would other wise use the default.
This commit aligns with the previous Spring Boot behavior where multiple
conventions setups are rejected as invalid with
`NoUniqueBeanDefinitionException`.
Fixes gh-31864
This commit refines InvocableHandlerMethod (both Servlet and
Reactive variants) in order to support annotated property
accessors as they translate into regular Java methods, instead
of throwing a NullPointerException.
Closes gh-31856
DataBinder should skip any jakarta.validation.Validator yielding
to method validation when that is expected. This change improves
the check to skip by unwrapping the validator from in a
SmartValidator before checking if it is for bean validation.
Closes gh-31711
Method validation needs to be used for a container such as a List or
Map, but until now we were only checking for a List container.
Moreover, in gh-31530 we improved method validation to also cover
any Collection.
This change aligns with HandlerMethod check for when method validation
applies with the underlying ability of method validation.
This commit improves JettyWebSocketHandlerAdapter::copyByteBuffer so
that it allocates a buffer large enough for the remaining bytes
contained in the source, instead of allocating one with the capacity of
the source.
Closes gh-31857
This commit updates the JSON writers to use a deterministic order for
arrays. Previously, the order could change with the same content,
breaking caching.
Closes gh-31852
This commit ensures that the capacity of the remainder buffer after a
split operation is set directly on the field. Calling capacity(int)
caused a new buffer to be allocated.
Closes gh-31848
This commit builds on top of changes made in gh-29775 and gh-31737.
Before this change, we would allocate several byte arrays even in cases
of known request size. This could decrease performance when getting the
cached content as it requires merging several arrays and data is not
colocated in memory.
This change ensures that we create a `FastByteArrayOutputStream`
instance with the known request size so that the first allocated segment
can contain the entire content.
If the request size is not know, we will default back on the default
allocation size for the `FastByteArrayOutputStream`.
Closes gh-31834
Refining the change from 43700302c6 so that
we consistently pick a PathPatternParser (a) if it is provided, and (b)
if both PathPatternParser and PathMatcher are not provided. Also applying
the same in the mutate builder.
See gh-31662
This commits allows ValueCodeGenerator$Delegate implementations to be
loaded from `META-INF/spring/aot.factories` and considered for code
generation of bean definition property values. This default behavior
in DefaultBeanRegistrationCodeFragments can be customized as usual.
Closes gh-31427
This commit introduces ValueCodeGenerator and its Delegate interface
as a way to generate the code for a particular value. Implementations
in spring-core provides support for common value types such a String,
primitives, Collections, etc.
Additional implementations are provided for code generation of bean
definition property values.
Closes gh-28999
Prior to this commit, the AnnotationsScanner used in the
MergedAnnotations infrastructure found duplicate annotations on methods
within multi-level interface hierarchies.
This commit addresses this issue by scanning methods at a given level
in the interface hierarchy using ReflectionUtils#getDeclaredMethods
instead of Class#getMethods, since the latter includes public methods
declared in super-interfaces which will anyway be scanned when
processing super-interfaces recursively.
Closes gh-31803
This commit matches the behavior of the core container when it
invokes a custom init or destroy method. If the custom method is an
interface implementation, the core container attempts to invoke the
method that's defined on the interface. This commit makes sure to also
register a hint for the interface method.
Closes gh-31819
Prior to this commit, the WebClient observations would have a specific
lifecycle where the observation context is build with a
`ClientRequest.Builder` as tracing needs to add an outgoing request
header before the request is made immutable.
With this setup, the metrics observation handler processes the start
event by increasing the "http.client.requests.active" counter and
collecting tags at this point. Because then the immutable request is not
yet fully built or set on the context, the keyvalues collected by the
observation convention at that point can be incomplete.
This commit ensures that a request is always made available in the
context, even if it is updated right after the observation start. The
only difference between the two should be additional tracing headers and
a request attribute holding the current observation context.
Closes gh-31702
This commit documents the fact that any (Unchecked)IOExceptions or
HttpMessageNotReadableExceptions thrown from the error handler will be
wrapped in a RestClientException.
Closes gh-31783
Prior to this commit, the `ConcurrentReferenceHashMap#restructure`
operation would null out the entire references array before starting the
restructuring operation (in case resizing is not necessary).
This could cause at runtime race conditions where a lookup operation
would return null, when the value is actually cached but not accesible
during the restructuring phase.
This commit ensures that, when resizing is not required, a new reference
list is built (purged of null entries) and then assigned to the
reference array. This way, concurrent reads will not return null for
existing entries and there are less chances of re-calculating cache
entries during the restructuring phase.
Closes gh-31008
Required by Spring Security to complete work on
https://github.com/spring-projects/spring-security/issues/14128
The setCache and resetCache methods used from createCacheFilter are now
public. Generally they don't need to be used outside of the Filter if
only making checks against the current request. Spring Security, however,
makes additional checks against requests with alternative paths.
Commit 33454a4007 introduced a regression in Comparators.nullsLow() and
Comporators.nullsHigh().
This commit updates the code so that nullsLow() sorts null values lower
than non-null values and nullsHigh sorts null values higher than
non-null values.
See gh-25478
Closes gh-31808
This commit adds ahead of time support for @Resource on fields and
methods. Lookup elements are discovered and code is generated to replace
that introspection at runtime.
Closes gh-29614
Introduce ShardingKeyDataSourceAdapter to get shard connections.
This commit introduces a DataSource proxy, that changes the behavior of the getConnection method to use the `createConnectionBuilder()` api to acquire direct shard connections. The shard connection is acquired by specifying a `ShardingKey` that is correspondent to the wanted shard.
While it is not easily possible to create a ConcurrentTaskScheduler
with no scheduled executor, DefaultManagedTaskScheduler has a default
constructor that does that as the JNDI lookup happens in the regular
afterPropertiesSet callback. If such an instance is created manually,
it can throw an unhelpful NullPointerException if one attempts to
schedule a task.
This commit updates ConcurrentTaskScheduler to flag that the scheduled
executor could be `null` and check if that's the case before using it.
This now throws a dedicated exception that should hopefully provide
better context for those upgrading.
See gh-27914
Closes gh-31751
This file is incomplete and has outdated content. Given that several
core committers are not even listed, it does not seem to serve a
valid purpose anymore.
Closes gh-31740
Previously, if an annotation processors was present in the classpath
it was executed as part of tests using `TestCompiler`.
This commit updates `TestCompiler` to always set the annotation
processors to use. By default, this sets an empty list which does not
use annotation processing.
Closes gh-31791
Includes special support for a read-only DataSource in addition to the regular target DataSource, avoiding the overhead of switching the Connection's read-only flag at the beginning and end of every transaction.
Closes gh-29931
Closes gh-31785
Closes gh-19688
Closes gh-21415
In gh-30549 we applied changes to the `DefaultPersistenceUnitManager` to
use the `ValidationMode.CALLBACK` to better detect invalid validation
setup and enforce bootstrap failures in those cases.
Unfortunately, doing so disables the detection of validation annotation
on entities during the schema creation phase. This is a known Hibernate
issue. This commit reverts this change until HHH-12287 is fixed.
Fixes gh-31726
This commit fixes a bug in DefaultPartHttpMessageReader's
MultipartParser, due to which the last token in a part window was not
properly indicated.
Closes gh-30953
Work performed in conjunction with gh-30941 resulted in a regression.
Specifically, prior to Spring Framework 6.1 a locally declared
@ComponentScan annotation took precedence over @ComponentScan
meta-annotations, which allowed "local" configuration to override
"meta-present" configuration.
This commit modifies the @ComponentScan search algorithm so that
locally declared @ComponentScan annotations are once again favored
over @ComponentScan meta-annotations (and, indirectly, composed
annotations).
See gh-30941 Closes gh-31704
Search for : assertThat\((.+).isEmpty\(\)\).isTrue\(\)
Replace with : assertThat($1).isEmpty()
Search for : assertThat\((.+).isEmpty\(\)\).isFalse\(\)
Replace with : assertThat($1).isNotEmpty()
Closes gh-31758
Search for : assertThat\((.+)\.equals\((\w+)\)\)\.isTrue\(\)
Replace with : assertThat($1).isEqualTo($2)
Search for : assertThat\((.+)\.equals\((\w+)\)\)\.isFalse\(\)
Replace with : assertThat($1).isNotEqualTo($2)
Closes gh-31763
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isTrue\(\)
Replace with : assertThat($1).contains($2)
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isFalse\(\)
Replace with : assertThat($1).doesNotContain($2)
Closes gh-31762
This commit partially reverts 39786e4790
and c5c843696b, as the approach taken did
not take into account request predicates that query request attributes,
including path variables.
Closes gh-31732
This commit introduces a toString() overload in
FastByteArrayOutputStream that accepts a Charset in order to mirror the
method that was introduced in ByteArrayOutputStream in JDK 10,
including a special case for when a single buffer is in use internally
to avoid the need to resize.
This commit also updates getContentAsString() in
ContentCachingRequestWrapper to use this new toString(Charset) method.
Closes gh-31737
This commit ensures that the RestClient uses the
IntrospectingClientHttpResponse to verify whether the response has a
body, and return null if it does not.
See gh-12671
Closes gh-31719
The getContentAsString method was originally added in d9b8826 to avoid
the extra copying inherent to calling ByteArrayOutputStream.toByteArray;
however, in f83c609 the class was updated to instead use
FastByteArrayOutputStream, and in the process the extra copy was brought
back when getContentAsString was changed to call toByteArray.
Switch to calling toByteArrayUnsafe, a method provided by
FastByteArrayOutputStream, which avoids the extra copy; since we
immediately pass the byte array to the String constructor, and it isn't
accessed anywhere else, the usage is safe.
See gh-31731
This commit allows to define a bean order programmatically
at bean definition level (functional equivalent of
`@Order`).
If specified, the order attribute defined at bean
definition level overrides potential values set with
`@Order`.
See gh-30849
Prior to this commit, regressions were introduced with gh-31417:
1. the observation keyvalues would be inconsistent with the HTTP response
2. the observation scope would not cover all controller handlers, causing
traceIds to be missing
The first issue is caused by the fact that in case of error signals, the
observation was stopped before the response was fully committed, which
means further processing could happen and update the response status.
This commit delays the stop event until the response is committed in
case of errors.
The second problem is caused by the change from a `contextWrite`
operator to using the `tap` operator with a `SignalListener`. The
observation was started in the `doOnSubscription` callback, which is too
late in some cases. If the WebFlux controller handler is synchronous
non-blocking, the execution of the handler is performed before the
subscription happens. This means that for those handlers, the
observation was not started, even if the current observation was
present in the reactor context. This commit changes the
`doOnSubscription` to `doFirst` to ensure that the observation is
started at the right time.
Fixes gh-31703
Fixes gh-31706
This commit updates MetadataNamingStrategy to quote an ObjectName
attribute value if necessary. For now, only the name attribute is
handled as it is usually a bean name, and we have no control over
its structure.
Closes gh-23608
This commit moves the condition used by `@DisabledInAotMode` to a
concrete implementation rather than using `@DisabledIf` as it causes
build initialization in a native image.
Closes gh-31705
This commit removes a list of hardcoded servers and version as this is
bound to get outdated and the reference guide/wiki is a more suitable
place for this.
This changes ensures RequestMappingInfo uses PathPatternParser by default
as all AbstractHandlerMapping implementations do as of 6.0.
RequestMappingInfo instances are typically created internally and aligned with
the RequestMappingHandlerMapping in terms of path mapping options.
If a RequestMappingInfo is registered programmatically, the caller needs to also
ensure they are aligned. However, if the two should be aligned by default.
Closes gh-31662
Prior to this commit, the TestContextManager logged an exception from a
TestExecutionListener at WARN level except in prepareTestInstance()
where such an exception was logged at ERROR level (except for a skipped
exception which is logged at INFO level).
For consistency, this commit modifies TestContextManager so that it
always logs non-skipped exceptions from TestExecutionListeners at WARN
level.
Closes gh-31688
This commit supports the scroll() and scroll(ScrollMode) methods from
Hibernate's Query API in SharedEntityManagerCreator's query-terminating
methods set.
Closes gh-31682
This commit makes sure to initialize any HandlerMapping defined in the
context when searching for resource handlers. Previously, the detection
algorithm was looking up for `SimpleUrlHandlerMapping` while the
declared target type in WebMvcConfigurationSupport is HandlerMapping.
If the application uses lazy initialization, the lookup algorithm would
not force that bean to be initialized.
Closes gh-25488
Prior to this commit, any time an aborted/skipped exception was thrown
by a TestExecutionListener, the TestContextManager unconditionally
logged the exception at WARN level -- or ERROR level for
prepareTestInstance() callbacks.
Regarding the latter, an aborted/skipped exception is certainly not an
ERROR, and in general the associated log output is very verbose
(including a stack trace) and not something the user should be warned
about it.
To improve the user experience, this commit revises TestContextManager
so that it logs such exceptions at INFO level.
Specifically, the following types of exceptions are considered
aborted/skipped exceptions.
- JUnit Jupiter: org.opentest4j.TestAbortedException
- JUnit 4 org.junit.AssumptionViolatedException
- TestNG: org.testng.SkipException
Closes gh-31479
The documentation currently states that Inversion of Control (IoC) and
Dependency Injection (DI) are the same thing. Although the two terms
are related, they are not synonymous: DI is a type of IoC.
I believe this change is important because using the terms
interchangeably really muddies the water about the meaning of these two
fundamental concepts of software frameworks.
Closes gh-31679
Prior to this commit, `ExchangeFilterFunction` could only get the
current observation from the reactor context. This is particularly
useful when such filters want to add KeyValues to the observation
context.
This commit makes this use case easier by adding the context of the
current observation as a request attribute. This also aligns the
behavior with other instrumentations.
Fixes gh-31609
The JDBC API that retrieves a proedure or a function allows to specify
patterns for the schema and the procedure name. So far, we've called
this API with the value as is, which does not work if either contains
a wildcard characters that need to be escaped.
This commit updates GenericCallMetadataProvider to escape, if necessary,
the schema or procedure name using the search string escape from the
database metadata.
Closes gh-22725
Prior to this commit, AspectJExpressionPointcut doesn't fall back to original method if `!@annotation()` is used, it can cause false positive result.
Fix GH-27119
Prior to this commit, the Jackson 2.x encoders, in case of encoding a
stream of data, would first release the `ByteArrayBuilder` and then the
`JsonGenerator`. This order is inconsistent with the single value
variant (see `o.s.h.codec.json.AbstractJackson2Encoder#encodeValue`) and
invalid since the `JsonGenerator` uses internally the
`ByteArrayBuilder`.
In case of a CSV Encoder, the codec can buffer data to write the column
names of the CSV file. Writing an empty Flux with this Encoder would not
fail but still log a NullPointerException ignored by the reactive
pipeline.
This commit fixes the order and avoid such issues at runtime.
Fixes gh-30493
This commit fixes a regression introduced by gh-21139
via the usage of Kotlin reflection to invoke HTTP
handler methods. It ensures that kotlin.Unit is treated
as void by returning null.
It also polishes CoroutinesUtils to have a consistent
handling compared to the regular case, and adds related
tests to prevent future regressions.
Closes gh-31648
Includes removal of evict step on pipeline exception, retaining a previous cache value and avoiding an incomplete key (for consistency with non-reactive caching).
Closes gh-31626
This commit extract spring-related links and recurring external links
into asciidoctor attributes to be used by the Antora toolchain.
It notably homogenizes links to:
- IETF RFCs
- Java Community Process JSRs
- the Java API Documentation (on the Java 17 version)
- Kotlin documentations (on the Kotlinlang.org version)
- the Spring Boot reference guide (on the `html` version)
This commit also reworks most link attributes to follow a
Project-Category-Misc syntax. For example, `spring-boot-docs` rather
than `docs-spring-boot`.
Finally, it makes an effort to clean up remainders from the previous
documentation toolchain, namely the `docs/asciidoc` folder and
`modules/ROOT/pages/attributes.adoc` file.
Closes gh-26864
Closes gh-31619
In order to prevent leaks of large amounts of non-heap
memory (and potential other efficiency and performance side
effects), this commit updates ResourceUtils#useCachesIfNecessary
to leave the caching flag to its JVM default value for instances
of JarURLConnection.
The previous behavior was originally introduced via gh-9316 and
gh-13755 to avoid I/O failure during webapp hot reloading in
Servlet containers. This is not a popular deployment mode anymore
and we have not been able to reproduce the original issue with
a Java 17 JVM and Tomcat 10.
Closes gh-30955
Legacy EJB attributes are ignored since 6.0 due to being bound to a plain JndiObjectFactoryBean - but can still be declared now, e.g. when validating against the common versions of spring-jee.xsd out there.
Closes gh-31627
The description is for WebFlux, but the link points to WebFlux unit
testing support.
This commit changes the link to point the the WebFlux chapter.
Closes gh-31632
Adding generated code in the default package is not supported as we
intend to import it, most probably from another package, and that is
not supported. While this situation is hard to replicate with Java,
Kotlin is unfortunately more lenient and users can end up in that
situation if they forget to add a package statement.
This commit checks for the presence of a valid package, and throws
a dedicated exception if necessary.
Closes gh-31628
Prior to this commit, the getResource() methods in PathResourceResolver
implementations allowed an exception thrown from Resource#getURL() to
propagate instead of logging a warning about the missing resource as
intended.
This commit modifies the getResource() methods in PathResourceResolver
implementations so that the log messages include the output of the
toString() implementations of the underlying resources instead of their
getURL() implementations, which may throw an exception.
Furthermore, logging the toString() output of resources aligns with the
existing output for "allowed locations" in the same log message.
Note that the toString() implementations could potentially also throw
exceptions, but that is considered less likely.
Closes gh-31623
This commit makes sure that the per-operation execution context for
caching and event listening does not recreate the default internal
delegates, but rather get initialized with a shared state.
This reduces the number of instances created per operation execution,
reducing the GC pressure as a result. This also makes sure that any
cache, such as the one in StandardTypeLocator, is reused.
Closes gh-31617
Expose methods to set and reset cache to use from a Filter instead
of a method to create such a Filter. Also use cached results only
if they match by dispatcher type and requestURI.
See gh-31588
This commit updates PathMatchingResourcePatternResolver to avoid
returning duplicate resources on MS Windows when searching using the
`classpath*:` prefix and a wildcard pattern that matches resources
which are directly present in a JAR as well as present via classpath
manifest entries.
Closes gh-31598
This commit introduces a ConvertibleClientHttpResponse type that
extends ClientHttpResponse, and that can convert the body to a desired
type. Before this commit, it was not easy to use the configured HTTP
message converters in combination with RestClient::exchange.
Closes gh-31597
This commit allows to terminate the JVM when the
-Dspring.context.exit=onRefresh property is set,
which can be useful for AppCDS training run in order
to get most of the AppCDS cache without starting the
beans.
Closes gh-31595
This commit adds a link in the package-overview pages of KDoc and
Javadoc, pointing to the other documentation's own page.
In order for local tests to work, the build has been slightly modified
to align with the directory structure in the distributed documentation
zip (and consequently with that of the deployed documentation website).
Lastly, the javadoc build was fixed to include the `overview.html` again
in the resulting HTML index, since this is where the KDoc link is added.
See gh-28055
Closes gh-31587
This commit clarifies that the annotation is used to capture events that
are fired from the test `Thread` or descendant threads, since the test
framework uses `InheritableThreadLocal` to store captured events now.
See gh-31079
See gh-30020
This commit ensures that not every OutputStream.write gets written as a
separate chunk, by buffering the written data in a BufferedOutputStream.
In some cases, a large quantity of small writes would result in many
sent chunks.
Closes gh-31361
Prior to this commit, the JMS listener observations would only cover the
actual listener invocation, but not the error handling phase. This means
that all errors (including the handled ones) are marked as errors in the
observation and that the observation is not current anymore when error
handling happens.
This commit aligns the behavior with the other Spring Framework
instrumentations and ensures that the error handling phase is fully part
of the observation recording.
Closes gh-31559
This commit updates PersistenceManagedTypesBeanRegistrationAotProcessor
to register reflection hints for `@EmbeddableInstantiator` annotations
available as of Hibernate 6.0 when needed.
Related tests will be added in
https://github.com/spring-projects/spring-aot-smoke-tests.
Closes gh-31534
Allows Kotlin caller to get a non-nullable property,
using a default value when the property is not set.
A method already exists on PropertyResolver which does this,
but takes a Class parameter.
The extension method can eliminate the parameter via reified type,
similar to the other extension methods which exist already.
Closes gh-31523
This commit documents that the "error" key in Micrometer Observations
should be preferred over the legacy "exception" one. Right now the
information is duplicated but we might remove the deprecated one in the
future.
Closes gh-31514
This commit ensures that the StreamingHttpOutputMessage.Body.repeatable
flag is set in message converters for bodies that can be written
repeatedly.
Closes gh-31516
See gh-31449
This reverts commit 93206c3f6e and updates
the related test to only rely on the fact the compiler fails. Relying
on a message will not work and the status code can be implementation
independent according to its javadoc.
Closes gh-31536
The me.champeau.mrjar Gradle plugin causes non-existent libraries to be
added to the Eclipse classpath, such as:
<classpathentry kind="lib" path="/workspaces/spring-framework/spring-core/build/classes/kotlin/java21">
<attributes>
<attribute name="gradle_used_by_scope" value="java21"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
This results in build errors in Eclipse IDE like the following.
Project 'spring-core' is missing required library:
'/workspaces/spring-framework/spring-core/build/classes/kotlin/java21'
This commit filters those and removes them.
Commit d3fba6d49b introduced built-in pattern matching support for
method names in ControlFlowPointcut; however, it was still cumbersome
to extend ControlFlowPointcut with support for regular expressions
instead of simple pattern matching.
To address that, this commit introduces a variant of isMatch() that
accepts the pattern index instead of the pre-resolved method name
pattern. The default implementation retrieves the method name pattern
from the methodNamePatterns field and delegates to isMatch(String, String).
Subclasses can override the new isMatch(String, int) method to support
regular expressions, as can be seen in the example
RegExControlFlowPointcut class in ControlFlowPointcutTests.
See gh-31435
This commit fixes code generation when an indexed constructor argument
value is null as the method is overloaded and need the value to be
cast to `Object`.
Closes gh-31508
Prior to this commit, ControlFlowPointcut supported a single method
name which was matched exactly. Although it was possible to extend
ControlFlowPointcut to add support for pattern matching, it was a bit
cumbersome.
To address that, this commit introduces built-in pattern matching
support for method names in ControlFlowPointcut, analogous to the
pattern matching support in NameMatchMethodPointcut.
Specifically, a user can provide one or more method name patterns, and
the patterns will be matched against candidate method names using OR
semantics.
By default, the matching algorithm delegates to
PatternMatchUtils.simpleMatch(), but this can be overridden in
subclasses by overriding the new protected isMatch() method.
Closes gh-31435
Previously, ConstructorResolver would reject any candidate if the
parameter is `null`. The reason for that is that null does not carry
any type and the matching algorithm would systematically fail for that
argument.
This commit adds an extra check, and several tests, to validate that
a null value is taken into account.
Closes gh-31495
Prior to this commit, @SpringJUnitConfig and @SpringJUnitWebConfig
did not declare `loader` attributes that alias @ContextConfiguration's
`loader` attribute. Consequently, it was not possible to configure a
custom ContextLoader via those annotations.
The lack of those `loader` attributes was an oversight, and this commit
introduces them to support custom ContextLoader configuration directly
via the @SpringJUnitConfig and @SpringJUnitWebConfig annotations.
Closes gh-31498
This commit surfaces the ETag generation feature for both
`ResourceHttpRequestHandler` and `ResourceWebHandler` on their
respective `ResourceHandlerRegistration` for easier configuration.
See gh-29031
This commit makes ControlFlowPointcut more open to subclasses by:
1. Making the ControlFlowPointcut#clazz field protected.
2. Making the ControlFlowPointcut#methodName field protected.
3. Introducing a protected incrementEvaluationCount() method.
Closes gh-27187
This commit introduces the maxParts and maxPartSize properties to
PartEventHttpMessageReader, which can be used to limit the amount of
parts, and maximum part size respectively.
Closes gh-31343
Previously the documentation assumed that the readers knew how to use
the X-Forwarded-* headers. This commit documents details & examples
of how to use the X-Forwarded-* headers.
See gh-31491
Since we do not yet have support for registering resource hints for
classpath location patterns, we have decided to explicitly skip such
resources and log a warning to inform users that they need to manually
supply resource hints for the exact resources needed by their
application.
This commit applies this change for @PropertySource and
@TestPropertySource.
See gh-31162
Closes gh-31429
This commit harmonizes AnnotationDrivenBeanDefinitionParser so that it
does not instantiate a property value while parsing the element. Rather,
it creates an inner bean definition so that the property is created
during the refresh phase.
Closes gh-31472
This commit refines MaxUploadSizeExceededException
handling in order to translate to a "413 Payload Too Large"
status code instead of "500 Internal Server Error", with
related ProblemDetail body.
Closes gh-27170
Prior to this commit, the `ResourceHttpRequestHandler` would support
HTTP caching when serving resources, but only driving it through the
`Resource#lastModified()` information.
This commit introduces an ETag generator function that can be configured
on the `ResourceHttpRequestHandler` to dynamically generate an ETag
value for the Resource that is going to be served.
Closes gh-29031
This commit improves the exception that is thrown when a particular
source class cannot be parsed. Previously, the message would include
the root configuration class, which may not be the class that
actually failed as parsing can trigger component scan. There's now
a dedicated catch that generates an exception message that includes the
class that is currently parsed.
Closes gh-31146
We can't upgrade to Eclipselink 4 as it would change the baseline that
this generation uses. However, there is a recent release in the current
line that adds compatibility with recent JDKs.
See gh-31078
This commit removes the "plain old class" bit of the documentation as
it may be confusing. The gist of it is that it must be a bean but not
annotated with `@Configuration` so the updated sentence states exactly
that.
Closes gh-29957
This commit introduces additional tests for "quoted identifier" support
in SimpleJdbcInsert when the schema itself is defined using quoted
identifiers -- for example, to use keywords as column names.
See gh-31208
This commit improves the handling of IllegalArgumentException in
SimpleInstantiationStrategy. Previously, only arguments mismatch were
handled but the exception can also be thrown if the factory instance
does not match the target method.
Closes gh-28897
This commit adds a test and polishing for a change in
AbstractNamedValueMethodArgumentResolver erroneously committed
with (unrelated) commit e57b942b.
If an argument becomes null after conversion and a default value is
applied, that default value should also pass through conversion.
Closes gh-31336
This commit adds a repeatable property to
StreamingHttpOutputMessage.Body, indicating that the body can be written
multiple times. In HttpComponentsClientHttpRequest, this property is
exposed via org.apache.hc.core5.http.HttpEntity.isRepeatable, to allow
for redirects.
Closes gh-31449
Prior to this commit, configuring a Servlet filter in MockMvc with a
defined mapping would only consider "/*" as a catch-all pattern.
This commit relaxes this rule by also accepting "*" mappings.
Closes gh-28041
This commit re-generates the protobuf Java classes with a recent version
of the protoc binary and adds JMH benchmarks that exercise the message
converter for both the reading and writing cases.
See gh-29496
Prior to this commit, the `ConcurrentReferenceHashMap#Segment` would
recalculate its element count during the restructure phase by
subtracting the number of polled elements from the queue to the current
count.
Later, the newly restructured `references` array would only contain
references that 1) are not in the set of elements to purge and
2) that hold a non-null value.
The issues with this approach are multiple. The newly calculated count
is only an estimate, as some situations can make it invalid, even
temporarily.
* since we initially collected all elements to be purged from the queue,
the GC might have collected new values. This means that we might
filter out more references that we initially intended to
* because the restructure operation re-creates new references for all
elements in the original array, we might later get references from the
queue that are not in the array anymore. This could lead to
"duplicate" removals for the same value
Because several methods in the Segment class have special no-op behavior
when `count == 0`, an invalid count can lead to keys appearing missing
when they are actually still present. In some scenarios, this can
decrease the performance of the cache since values need to be
recalculated.
This commit fixes this inconsistency count issue by first using an
estimate in order to decide whether the array needs a resize and then by
counting the actual numbers of elements inserted in the restructured
array as the new count.
Fixes gh-31373
This commit adds a warning in the reference guide to address the
use cases where users might be tempted to use several property
placeholder configurers.
Closes gh-14623
Use the helper to reduce logging when an @ExceptionHandler fails
to write to the response due to a network failure where the client
has gone away.
Closes gh-26181
Prior to this commit, the NestedTestCase resulted in errors during our
AOT end-to-end integration tests since it did not comply to our "*Tests"
naming convention.
See gh-29122
This commit applies @DisabledInAotMode to test classes in the
spring-test module that will never be able to be processed for AOT
optimizations.
Test classes that fail for reasons that can potentially be addressed in
a future version of the framework have not been annotated with
@DisabledInAotMode.
See gh-29122
Although it should not happen in theory, sometimes a test class is
discovered more than once via the TestClassScanner in our integration
tests. When it does happen in our tests, the two Class objects have the
same fully-qualified class name but represent different classes which
leads to failures due to incorrect associations between test class
names and their MergedContextConfiguration.
To address this, this commit modifies TestContextAotGenerator so that
it skips duplicate test class names.
This commit adds Coroutines support for `@Cacheable`.
It also refines SimpleKeyGenerator to ignore Continuation
parameters (Kotlin does not allow to have the same method
signature with both suspending and non-suspending variants)
and refines
org.springframework.aop.framework.CoroutinesUtils.awaitSingleOrNull
in order to wrap plain value to Mono.
Closes gh-31412
This commit introduces @DisabledInAotMode in the TestContext
framework to support the following use cases.
- Disabling AOT build-time processing of a test ApplicationContext --
applicable to any testing framework (JUnit 4, JUnit Jupiter, etc.).
- Disabling an entire test class or a single test method at run time
when the test suite is run with AOT optimizations enabled -- only
applicable to JUnit Jupiter based tests.
Closes gh-30834
This commits makes sure that a bean that produces an array can be
processed ahead of time. If the request target type is an array, its
component type is used.
Closes gh-31426
This commit improves compatibility with the core container when running
in AOT mode by adding support for generic constructor argument values.
Previously, these were ignored altogether. We now have code generation
support for them as well as resolution that is similar to what
AbstractAutowiredCapableBeanFactory does in a regular runtime.
This commit also improves AOT support for XML bean configurations by
adding more support for TypedStringValue and inner bean definitions.
Closes gh-31420
Since the Spring WebFlux HTTP server instrumentation has been moved from
the `WebFilter` to the `HttpWebHandlerAdapter`, we need to apply similar
changes there.
See gh-31417
Prior to this commit, HTTP server observations for Spring WebFlux could
be recorded twice for a single request in some cases. The "COMPLETE" and
"CANCEL" signals would race in the reactive pipeline and would trigger
both the `doOnComplete()` and ` `doOnCancel()` operators, each calling
`observation.stop()` on the current observation.
This would in fact publish two different observations for the same
request.
This commit ensures that the instrumentation uses the `Mono#tap`
operator to guard against this case and only call `Observation#stop`
once for each request.
Fixes gh-31417
This commit adds support for TypeStringValue when generating AOT code.
If the value does not specify an explicit type, it's specified as is.
Otherwise, the TypeStringValue instance is restored via the appropriate
code generation.
Closes gh-29074
Prior to this commit, a cancelled exchange would always result in an
`"status":"UNKNOWN"` KeyValue. This only applied to reactive variants,
as cancelled exchanges are not currently detected for Servlet
implementations.
In some cases, exchanges can be cancelled by clients before they are
completed, but the response was actually received by the client. The
response status information has been set by the application and the
response has been committed. For those cases, we shouldn't assume an
"UNKNOWN" value.
This commit assumes that committed responses have a response status set
by the application and that the observations should reflect that. From
now on, we only assume an "UNKNOWN" status if the response has not been
commited.
Fixes gh-31388
This commit reintroduces a deprecated ReactorResourceFactory in
org.springframework.http.client.reactive package that extends
the one in org.springframework.http.client package to avoid an
API breaking change and to provide a smoother upgrade experience.
Closes gh-31399
This commit is a best effort attempt at identifying the members that
code generation invokes and might be deprecated. It introduces
a CodeWarnings helper class that records warnings, with special
handling for `@Deprecated`.
See gh-29597
This commit is a prerequisite to help suppressing deprecating warnings
by allowing tests to validate that the compiler does not encounter them.
See gh-29597
In AbstractApplicationEventMulticaster.retrieveApplicationListeners,
despite best efforts to avoid it, unwrapped proxies (singleton targets)
can end up in the list of programmatically registered listeners. In
order to avoid duplicates, we need to find and replace them by their
proxy counterparts, because if both a proxy and its target end up in
'allListeners', listeners will fire twice.
Fixes#28283.
This commit adds a constructor with externally managed
Reactor Netty resources to ReactorNettyClientRequestFactory
and makes it lifecycle-aware in order to support Project CRaC.
Closes gh-31280
Closes gh-31281
Prior to this commit, the bean definition properties code generator
would register hints for invoking the setter methods of registered
property values defined for the bean definition.
The internal algorithm is also reflecting on the Field to discover
annotations. Doing so actually calls `getDeclaredFields` to iterate on
the available fields. This is done recursively up the type hierarchy
until the field is found.
This commit registers the required reflection metadata.
Closes gh-31390
This commit revises the previous commit as follows.
- Remove hasTestMethod() from TestContext and instead introduce a new
variant of createDelegatingTransactionAttribute() in
TestContextTransactionUtils which accepts a boolean
`includeMethodName` flag.
- Add missing @TestMethodOrder declaration to
AfterTestClassSqlScriptsTests to ensure that the test methods are
always executed in the required order.
- Polish Javadoc and add missing @since tags.
Closes gh-27285
This commit replaces uses of onErrorResume() with
- onErrorMap() in places where onErrorResume() is just used to map to a
different exception.
- onErrorComplete() where onErrorResume() just maps to Mono.empty().
- onErrorReturn() where onErrorResum() just maps to Mono.just().
Closes gh-31352
This commit removes the previously introduced reflection hints that were
working around known issues in GraalVM.
Spring Framework 6.1 will require recent maintenance versions of GraalVM
and should not contribute such hints anymore.
Closes gh-30394
Prior to this commit, the bean registration AOT contributions would
register introspection and invocation hints on both declared and public
methods for bean types. The bean introspection algorithm also looks at
default methods implemented by interfaces when collecting bean property
information.
This commit ensures that introspection hints are registered for all
implemented interfaces when registering beans.
Closes gh-31350
Due to the changes in gh-31341, if the repeat count in a SpEL
expression (using the repeat operator '*') is negative, we throw a
SpelEvaluationException with the MAX_REPEATED_TEXT_SIZE_EXCEEDED
message which is incorrect and misleading.
Prior to gh-31341, a negative repeat count resulted in an
IllegalArgumentException being thrown by String#repeat(), which was
acceptable in terms of diagnostics, but that did not make it
immediately clear to the user what the underlying cause was.
In light of the above, this commit improves diagnostics for a negative
repeated text count in SpEL expressions by throwing a
SpelEvaluationException with a new NEGATIVE_REPEATED_TEXT_COUNT error
message.
Closes gh-31342
If the resulting size of repeated text in a SpEL expression (using the
repeat operator '*') would exceed MAX_REPEATED_TEXT_SIZE, we currently
throw a SpelEvaluationException with the
MAX_REPEATED_TEXT_SIZE_EXCEEDED message.
However, if the calculation of the repeated text size results in
integer overflow, our max size check fails to detect that, and
String#repeat(int) throws a preemptive OutOfMemoryError from which the
application immediately recovers.
To improve diagnostics for users, this commit ensures that we
consistently throw a SpelEvaluationException with the
MAX_REPEATED_TEXT_SIZE_EXCEEDED message when integer overflow occurs.
Closes gh-31341
Prior to this commit the Spring Expression Language (SpEL) was able to
properly parse an expression that uses the safe navigation operator
(?.) with a method that has a `void` return type (for example,
"myObject?.doSomething()"); however, SpEL was not able to evaluate or
compile such expressions.
This commit addresses the evaluation issue by selectively not boxing
the exit type descriptor (for inclusion in the generated bytecode) when
the method's return type is `void`.
This commit addresses the compilation issue by pushing a null object
reference onto the stack in the generated byte code when the method's
return type is `void`.
Closes gh-27421
This commit partially reverts 3b8dd0a5, which introduced a strict
validation in JmsAccessor#setSessionAcknowledgeMode that prevents use
of vendor-specific acknowledge modes.
See gh-31328
Prior to this commit, if a Spring Expression Language (SpEL) expression
contained property, field, or method references using the null-safe
navigation operator (?.), the generated AST String representation
incorrectly omitted the '?' characters.
For example, 'myProperty?.myMethod()' had a generated AST string
representation of 'myProperty.myMethod()'.
This commit addresses this by introducing isNullSafe() in
MethodReference and reworking the logic in
CompoundExpression.toStringAST().
Closes gh-31326
Since the rewrite of ConcurrentLruCache in Spring Framework 6.0, an
attempt to create a ConcurrentLruCache with zero capacity results in an
IllegalArgumentException even though the documentation states that zero
capacity indicates "no caching, always generating a new value".
This commit restores the ability to configure a ConcurrentLruCache with
zero capacity and introduces corresponding tests (which were first
verified against the 5.3.x branch to ensure backward compatibility).
See gh-26320
Closes gh-31317
This commit introduces initialize() methods in
AbstractRoutingDataSource and AbstractRoutingConnectionFactory as an
alternative to invoking afterPropertiesSet().
Closes gh-31248
Previously, MessagingMessageListenerAdapter or any adapter relying on
the default MessagingMessageConverter would log an incoming message
with a toString of the Message that does not provide any extra
information. This is due to the default implementation providing a
lazy resolution message that only attempts to extract the payload
when necessary.
This commit implements a toString method that uses the raw JMS message
if the payload is not available. If it is, the payload is used instead.
Closes gh-21265
Given a @Configuration class named org.example.AppConfig which
contains @Bean methods, in Spring Framework 5.3.x and previous
versions, the following classes were created when generating the CGLIB
proxy.
org.example.AppConfig$$EnhancerBySpringCGLIB$$fd7e9baa
org.example.AppConfig$$FastClassBySpringCGLIB$$3fec86e
org.example.AppConfig$$EnhancerBySpringCGLIB$$fd7e9baa$$FastClassBySpringCGLIB$$82534900
Those class names indicate that 1 class was generated for the proxy for
the @Configuration class itself and that 2 additional FastClass
classes were generated to support proxying of @Bean methods in
superclasses.
However, since Spring Framework 6.0, the following classes are created
when generating the CGLIB proxy.
org.example.AppConfig$$SpringCGLIB$$0
org.example.AppConfig$$SpringCGLIB$$1
org.example.AppConfig$$SpringCGLIB$$2
The above class names make it appear that 3 proxy classes are generated
for each @Configuration class, which is misleading.
To address that and to align more closely with how such generated
classes were named in previous versions of the framework, this commit
modifies SpringNamingPolicy so that generated class names once again
include "FastClass" when the generated class is for a CGLIB FastClass
as opposed to the actual proxy for the @Configuration class.
Consequently, with this commit the following classes are created when
generating the CGLIB proxy.
org.example.AppConfig$$SpringCGLIB$$0
org.example.AppConfig$$SpringCGLIB$$FastClass$$0
org.example.AppConfig$$SpringCGLIB$$FastClass$$1
Closes gh-31272
For equivalence, we only need to compare the preInstantiationPointcut
fields since they include the declaredPointcut fields. In addition, we
should not compare the aspectInstanceFactory fields since
LazySingletonAspectInstanceFactoryDecorator does not implement equals().
See gh-31238
This commit expands the scope of equality checks in the implementation
of equals() for PerTargetInstantiationModelPointcut to include all
fields instead of just the pointcut expression for the declared
pointcut.
See gh-31238
Prior to this commit, DefaultJdbcClient updated the supplied KeyHolder
when using named parameters but not for positional parameters.
This commit refactors the creation of the
PreparedStatementCreatorFactory so that the PreparedStatementCreator
properly creates a PreparedStatement which returns generated keys.
Closes gh-31297
Prior to this commit, the `BeanRegistrationsAotContribution` would only
contribute introspection hints for declared methods. This does not cover
inherited public methods.
This commit adds the missing hint on public methods.
Fixes gh-31293
This commit configures the Foojay resolver plugin in the Gradle build in
order to auto-provision a required JDK distribution if it's not present
already on the host.
Currently the Spring Framework build requires both a JDK 17 and a JDK 21
distribution to build artifacts.
Closes gh-30474
The introduction of AdvisedSupport.AdvisorKeyEntry in Spring Framework
6.0.10 resulted in a regression regarding caching of CGLIB generated
proxy classes. Specifically, equality checks for the proxy class cache
became based partially on identity rather than equivalence. For
example, if an ApplicationContext was configured to create a
class-based @Transactional proxy, a second attempt to create the
ApplicationContext resulted in a duplicate proxy class for the same
@Transactional component.
On the JVM this went unnoticed; however, when running Spring
integration tests within a native image, if a test made use of
@DirtiesContext, a second attempt to create the test
ApplicationContext resulted in an exception stating, "CGLIB runtime
enhancement not supported on native image." This is because Test AOT
processing only refreshes a test ApplicationContext once, and the
duplicate CGLIB proxy classes are only requested in subsequent
refreshes of the same ApplicationContext which means that duplicate
proxy classes are not tracked during AOT processing and consequently
not included in a native image.
This commit addresses this regression as follows.
- AdvisedSupport.AdvisorKeyEntry is now based on the toString()
representations of the ClassFilter and MethodMatcher in the
corresponding Pointcut instead of the filter's and matcher's
identities.
- Due to the above changes to AdvisorKeyEntry, ClassFilter and
MethodMatcher implementations are now required to implement equals(),
hashCode(), AND toString().
- Consequently, the following now include proper equals(), hashCode(),
and toString() implementations.
- CacheOperationSourcePointcut
- TransactionAttributeSourcePointcut
- PerTargetInstantiationModelPointcut
Closes gh-31238
Prior to this commit, `DisposableBeanAdapter` supported reactive bean
destroy methods by detected if `Publisher` is available on the
classpath. The AOT engine did not contribute a reflection hint for this
call.
This commit ensures that this reflection hint is registered in all
cases, even if there are no destroy methods detected on beans.
Fixes gh-31278
`PathMatchingResourcePatternResolver` is reflecting on
`org.eclipse.core.runtime.FileLocator` and invoking methods on it for
OSGi support. While this use case is highly unlikely in native images,
registering the reflection entry by itself should be enough.
Fixes gh-31271
This commit adds the relevant reflection hints required by
`KotlinDetector`; this class is trying to detect both `kotlin.Metadata`
and `kotlin.reflect.full.KClasses`.
Fixes gh- 31269
This commit adds reflection hints for `jakarta.inject.Provider` and
ensures that hints are always contributed even if jakarta classes are
not on the classpath.
Fixes gh-31259
Prior to this commit, `ClassUtils#forName` would always attempt to
resolve the given class name as a nested type. For example, searching
for `org.example.Spring` would try to resolve:
* `org.example.Spring`
* if not available, try `org.example$Spring` as well
Java classes usually start with uppercase letters, so this additional
lookup can be costly and not very useful.
This commit only attempts nested class lookups when the previous segment
starts with an uppercase. So `org.example.Spring.Issue` will look for
`org.example.Spring$Issue`, but `org.example.Spring` will not.
Closes gh-31258
This commit reviews when an AOT-generated bean definition defines a
beanClass or targetType. Previously, a beanClass was not consistently
set which could lead to issues.
Closes gh-31242
Except for meaningful double spaces (for example, to align the
indentation of comments), this commit replaces all unnecessary double
spaces with single spaces in the spring-webmvc module.
Closes gh-31245
Prior to this commit, the `RuntimeHintsPredicates` would assume that
registering introspection or invocation hints for "all declared methods"
on a type would also include "all public methods". This is not true, as
the Java reflection API itself behaves differently.
`getDeclaredMethods()` does not return a superset of `getMethods()`, as
the latter can return inherited methods, but not the former.
Same reasoning applies to fields.
This commit fixes the hints predicates to only match if the correct hint
has been registered.
Fixes gh-31224
Prior to this commit in the message converters it was possible
to set a pre-configured ObjectMapper. However the constructor
would still create and configure an ObjectMapper.
With the added constructor it is now possible to directly
construct the message converter with the proper ObjectMapper.
This prevents the this additional ObjectMapper to be constructed.
send(..) -methods of JavaMailSenderImpl which is only delegating to
other methods are pulled up as default methods in the interfaces
JavaMailSender and MailSender, to make these interfaces require fewer
methods to implement.
See gh-23651
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://github.com/spring-projects/spring-framework/actions/workflows/build-and-deploy-snapshot.yml?query=branch%3A6.1.x) [](https://ge.spring.io/scans?search.rootProjectNames=spring)
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
@@ -6,7 +6,7 @@ Spring provides everything required beyond the Java programming language for cre
## Code of Conduct
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@spring.io.
## Access to Binaries
@@ -31,7 +31,7 @@ Information regarding CI builds can be found in the [Spring Framework Concourse
## Stay in Touch
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [releases feed](https://spring.io/blog/category/releases).
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on 𝕏. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [releases feed](https://spring.io/blog/category/releases).
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x[Spring Framework 6.0.x].
=== Setting up your development environment
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
You can then login with the instance using:
[source]
----
$ fly -t spring login -n spring-framework -c https://ci.spring.io
----
Once logged in, you should get something like:
[source]
----
$ fly ts
name url team expiry
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
----
=== Pipeline configuration and structure
The build pipelines are described in `pipeline.yml` file.
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
You'll find in this folder the following resources:
* `pipeline.yml` the build pipeline
* `parameters.yml` the build parameters used for the pipeline
* `images/` holds the container images definitions used in this pipeline
* `scripts/` holds the build scripts that ship within the CI container images
* `tasks` contains the task definitions used in the main `pipeline.yml`
=== Updating the build pipeline
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
The pipeline can be deployed using the following command:
For this to work, the annotated types must be woven with the AspectJ weaver. You can
either use a build-time Ant or Maven task to do this (see, for example, the
https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development
{aspectj-docs-devguide}/antTasks.html[AspectJ Development
Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The
`AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain
a reference to the bean factory that is to be used to configure new objects). If you
@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex
Spring Framework. This section is not a general introduction to LTW. For full details on
the specifics of LTW and configuring LTW with only AspectJ (with Spring not being
involved at all), see the
https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ
{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ
Development Environment Guide].
The value that the Spring Framework brings to AspectJ LTW is in enabling much
@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch
Now that the sales pitch is over, let us first walk through a quick example of AspectJ
LTW that uses Spring, followed by detailed specifics about elements introduced in the
@@ -15,10 +15,13 @@ Applying such optimizations early implies the following restrictions:
* The classpath is fixed and fully defined at build time.
* The beans defined in your application cannot change at runtime, meaning:
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
** `@Profile`, in particular profile-specific configuration, needs to be chosen at build time and is automatically enabled at runtime when AOT is enabled.
** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).
* Make sure that the bean type is as precise as possible.
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time.
* Beans registered as singletons (using `registerSingleton`, typically from
`ConfigurableListableBeanFactory`) cannot be transformed ahead-of-time either.
* As we cannot rely on the instance, make sure that the bean type is as precise as
possible.
TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.
@@ -27,7 +30,7 @@ A Spring AOT processed application typically generates:
* Java source code
* Bytecode (usually for dynamic proxies)
* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.
* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies
NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.
We intend to support more JVM-based use cases in future generations.
@@ -35,7 +38,7 @@ We intend to support more JVM-based use cases in future generations.
[[aot.basics]]
== AOT engine overview
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:
The entry point of the AOT engine for processing an `ApplicationContext` is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:
* Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
In this mode, xref:core/beans/factory-extension.adoc#beans-factory-extension-factory-postprocessors[`BeanFactoryPostProcessor` implementations] are invoked as usual.
This includes configuration class parsing, import selectors, classpath scanning, etc.
Such steps make sure that the `BeanRegistry` contains the relevant bean definitions for the application.
If bean definitions are guarded by conditions (such as `@Profile`), these are discarded at this stage.
If bean definitions are guarded by conditions (such as `@Profile`), these are evaluated,
and bean definitions that don't match their conditions are discarded at this stage.
If custom code needs to register extra beans programmatically, make sure that custom
registration code uses `BeanDefinitionRegistry` instead of `BeanFactory` as only bean
definitions are taken into account. A good pattern is to implement
`ImportBeanDefinitionRegistrar` and register it via an `@Import` on one of your
configuration classes.
Because this mode does not actually create bean instances, `BeanPostProcessor` implementations are not invoked, except for specific variants that are relevant for AOT processing.
These are:
@@ -81,15 +91,15 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a
[[aot.bean-factory-initialization-contributions]]
== Bean Factory Initialization AOT Contributions
Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
Each implementation can return an AOT contribution, based on the state of the bean factory.
An AOT contribution is a component that contributes generated code that reproduces a particular behavior.
An AOT contribution is a component that contributes generated code which reproduces a particular behavior.
It can also contribute `RuntimeHints` to indicate the need for reflection, resource loading, serialization, or JDK proxies.
A `BeanFactoryInitializationAotProcessor` implementation can be registered in `META-INF/spring/aot.factories` with a key equal to the fullyqualified name of the interface.
A `BeanFactoryInitializationAotProcessor` implementation can be registered in `META-INF/spring/aot.factories` with a key equal to the fully-qualified name of the interface.
A `BeanFactoryInitializationAotProcessor` can also be implemented directly by a bean.
The `BeanFactoryInitializationAotProcessor` interface can also be implemented directly by a bean.
In this mode, the bean provides an AOT contribution equivalent to the feature it provides with a regular runtime.
Consequently, such a bean is automatically excluded from the AOT-optimized context.
@@ -111,7 +121,7 @@ This interface is used as follows:
* Implemented by a `BeanPostProcessor` bean, to replace its runtime behavior.
For instance xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp-examples-aabpp[`AutowiredAnnotationBeanPostProcessor`] implements this interface to generate code that injects members annotated with `@Autowired`.
* Implemented by a type registered in `META-INF/spring/aot.factories` with a key equal to the fullyqualified name of the interface.
* Implemented by a type registered in `META-INF/spring/aot.factories` with a key equal to the fully-qualified name of the interface.
Typically used when the bean definition needs to be tuned for specific features of the core framework.
WARNING: Kotlin class names with backticks that use invalid Java identifiers (not starting with a letter, containing spaces, etc.) are not supported.
Since there isn't any particular condition on this class, `dataSourceConfiguration` and `dataSource` are identified as candidates.
The AOT engine will convert the configuration class above to code similar to the following:
@@ -156,6 +181,7 @@ Java::
/**
* Bean definitions for {@link DataSourceConfiguration}
*/
@Generated
public class DataSourceConfiguration__BeanDefinitions {
/**
* Get the bean definition for 'dataSourceConfiguration'
@@ -190,11 +216,25 @@ Java::
NOTE: The exact code generated may differ depending on the exact nature of your bean definitions.
TIP: Each generated class is annotated with `org.springframework.aot.generate.Generated` to
identify them if they need to be excluded, for instance by static analysis tools.
The generated code above creates bean definitions equivalent to the `@Configuration` class, but in a direct way and without the use of reflection if at all possible.
There is a bean definition for `dataSourceConfiguration` and one for `dataSourceBean`.
When a `datasource` instance is required, a `BeanInstanceSupplier` is called.
This supplier invokes the `dataSource()` method on the `dataSourceConfiguration` bean.
[[aot.running]]
== Running with AOT optimizations
AOT is a mandatory step to transform a Spring application to a native executable, so it
is automatically enabled when running in this mode. It is possible to use those optimizations
on the JVM by setting the `spring.aot.enabled` System property to `true`.
NOTE: When AOT optimizations are included, some decisions that have been taken at build-time
are hard-coded in the application setup. For instance, profiles that have been enabled at
build-time are automatically enabled at runtime as well.
[[aot.bestpractices]]
== Best Practices
@@ -203,11 +243,33 @@ However, keep in mind that some optimizations are made at build time based on a
This section lists the best practices that make sure your application is ready for AOT.
[[aot.bestpractices.bean-registration]]
== Programmatic bean registration
The AOT engine takes care of the `@Configuration` model and any callback that might be
invoked as part of processing your configuration. If you need to register additional
beans programmatically, make sure to use a `BeanDefinitionRegistry` to register
bean definitions.
This can typically be done via a `BeanDefinitionRegistryPostProcessor`. Note that, if it
is registered itself as a bean, it will be invoked again at runtime unless you make
sure to implement `BeanFactoryInitializationAotProcessor` as well. A more idiomatic
way is to implement `ImportBeanDefinitionRegistrar` and register it using `@Import` on
one of your configuration classes. This invokes your custom code as part of configuration
class parsing.
If you declare additional beans programmatically using a different callback, they are
likely not going to be handled by the AOT engine, and therefore no hints are going to be
generated for them. Depending on the environment, those beans may not be registered at
all. For instance, classpath scanning does not work in a native image as there is no
notion of a classpath. For cases like this, it is crucial that the scanning happens at
build time.
[[aot.bestpractices.bean-type]]
=== Expose The Most Precise Bean Type
While your application may interact with an interface that a bean implements, it is still very important to declare the most precise type.
The AOT engine performs additional checks on the bean type, such as detecting the presence of `@Autowired` members, or lifecycle callback methods.
The AOT engine performs additional checks on the bean type, such as detecting the presence of `@Autowired` members or lifecycle callback methods.
For `@Configuration` classes, make sure that the return type of the factory `@Bean` method is as precise as possible.
Consider the following example:
@@ -258,10 +320,37 @@ If you are registering bean definitions programmatically, consider using `RootBe
[[aot.bestpractices.constructors]]
=== Avoid Multiple Constructors
The container is able to choose the most appropriate constructor to use based on several candidates.
However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.
In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.
In case you are working on a code base that you cannot modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.
[[aot.bestpractices.comlext-data-structure]]
=== Avoid Complex Data Structure for Constructor Parameters and Properties
When crafting a `RootBeanDefinition` programmatically, you are not constrained in terms of types that you can use.
For instance, you may have a custom `record` with several properties that your bean takes as a constructor argument.
While this works fine with the regular runtime, AOT does not know how to generate the code of your custom data structure.
A good rule of thumb is to keep in mind that bean definitions are an abstraction on top of several models.
Rather than using such structure, decomposing to simple types or referring to a bean that is built as such is recommended.
As a last resort, you can implement your own `org.springframework.aot.generate.ValueCodeGenerator$Delegate`.
To use it, register its fully qualified name in `META-INF/spring/aot.factories` using the `Delegate` as the key.
[[aot.bestpractices.custom-arguments]]
=== Avoid Creating Bean with Custom Arguments
Spring AOT detects what needs to be done to create a bean and translates that in generated code using an instance supplier.
The container also supports creating a bean with {spring-framework-api}++/beans/factory/BeanFactory.html#getBean(java.lang.String,java.lang.Object...)++[custom arguments] that leads to several issues with AOT:
. The custom arguments require dynamic introspection of a matching constructor or factory method.
Those arguments cannot be detected by AOT, so the necessary reflection hints will have to be provided manually.
. By-passing the instance supplier means that all other optimizations after creation are skipped as well.
For instance, autowiring on fields and methods will be skipped as they are handled in the instance supplier.
Rather than having prototype-scoped beans created with custom arguments, we recommend a manual factory pattern where a bean is responsible for the creation of the instance.
public class ClientFactoryBean<T extends AbstractClient> implements FactoryBean<T> {
// ...
}
----
======
@@ -376,10 +465,10 @@ Java::
Running an application as a native image requires additional information compared to a regular JVM runtime.
For instance, GraalVM needs to know ahead of time if a component uses reflection.
Similarly, classpath resources are not shipped in a native image unless specified explicitly.
Similarly, classpath resources are not included in a native image unless specified explicitly.
Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.
The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.
The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.
The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:
If at all possible, `@ImportRuntimeHints` should be used as close as possible to the component that requires the hints.
This way, if the component is not contributed to the `BeanFactory`, the hints won't be contributed either.
It is also possible to register an implementation statically by adding an entry in `META-INF/spring/aot.factories` with a key equal to the fullyqualified name of the `RuntimeHintsRegistrar` interface.
It is also possible to register an implementation statically by adding an entry in `META-INF/spring/aot.factories` with a key equal to the fully-qualified name of the `RuntimeHintsRegistrar` interface.
[[aot.hints.reflective]]
=== `@Reflective`
{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.
By default, only Spring beans are considered and an invocation hint is registered for the annotated element.
By default, only Spring beans are considered, and an invocation hint is registered for the annotated element.
This can be tuned by specifying a custom `ReflectiveProcessor` implementation via the
`@Reflective` annotation.
@@ -431,7 +520,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia
[[aot.hints.register-reflection-for-binding]]
=== `@RegisterReflectionForBinding`
{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.
`@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.
With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.
This approach works well for unit tests but implies that the runtime behavior of a component is well known.
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.
For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `"org.springframework:spring-core-test"`.
.Are annotations better than XML for configuring Spring?
****
The introduction of annotation-based configuration raised the question of whether this
approach is "`better`" than XML. The short answer is "`it depends.`" The long answer is
that each approach has its pros and cons, and, usually, it is up to the developer to
decide which strategy suits them better. Due to the way they are defined, annotations
provide a lot of context in their declaration, leading to shorter and more concise
configuration. However, XML excels at wiring up components without touching their source
code or recompiling them. Some developers prefer having the wiring close to the source
while others argue that annotated classes are no longer POJOs and, furthermore, that the
configuration becomes decentralized and harder to control.
Spring provides comprehensive support for annotation-based configuration, operating on
metadata in the component class itself by using annotations on the relevant class,
method, or field declaration. As mentioned in
xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp-examples-aabpp[Example: The `AutowiredAnnotationBeanPostProcessor`],
Spring uses `BeanPostProcessors` in conjunction with annotations to make the core IOC
container aware of specific annotations.
No matter the choice, Spring can accommodate both styles and even mix them together.
It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets
annotations be used in a non-invasive way, without touching the target components'
source code and that, in terms of tooling, all configuration styles are supported by
https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.
****
An alternative to XML setup is provided by annotation-based configuration, which relies
on bytecode metadata for wiring up components instead of XML declarations. Instead of
using XML to describe a bean wiring, the developer moves the configuration into the
component class itself by using annotations on the relevant class, method, or field
declaration. As mentioned in xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp-examples-aabpp[Example: The `AutowiredAnnotationBeanPostProcessor`], using a
`BeanPostProcessor` in conjunction with annotations is a common means of extending the
Spring IoC container. For example, the xref:core/beans/annotation-config/autowired.adoc[`@Autowired`]
annotation provides the same capabilities as described in xref:core/beans/dependencies/factory-autowire.adoc[Autowiring Collaborators] but
For example, the xref:core/beans/annotation-config/autowired.adoc[`@Autowired`]
annotation provides the same capabilities as described in
xref:core/beans/dependencies/factory-autowire.adoc[Autowiring Collaborators] but
with more fine-grained control and wider applicability. In addition, Spring provides
support for JSR-250 annotations, such as `@PostConstruct` and `@PreDestroy`, as well as
support for JSR-330 (Dependency Injection for Java) annotations contained in the
@@ -36,13 +19,16 @@ can be found in the xref:core/beans/standard-annotations.adoc[relevant section].
[NOTE]
====
Annotation injection is performed before XML injection. Thus, the XML configuration
overrides the annotations for properties wired through both approaches.
Annotation injection is performed before external property injection. Thus, external
configuration (e.g. XML-specified bean properties) effectively overrides the annotations
for properties when wired through mixed approaches.
====
As always, you can register the post-processors as individual bean definitions, but they
can also be implicitly registered by including the following tag in an XML-based Spring
configuration (notice the inclusion of the `context` namespace):
Technically, you can register the post-processors as individual bean definitions, but they
are implicitly registered in an `AnnotationConfigApplicationContext` already.
In an XML-based Spring setup, you may include the following configuration tag to enable
mixing and matching with annotation-based configuration:
[source,xml,indent=0,subs="verbatim,quotes"]
----
@@ -62,11 +48,11 @@ configuration (notice the inclusion of the `context` namespace):
The `<context:annotation-config/>` element implicitly registers the following post-processors:
class for the configuration details involved in RAR deployment.
For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:
@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif
file extension).
. Add all required library JARs into the root of the RAR archive.
. Add a
`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])
`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])
and the corresponding Spring XML bean definition file(s) (typically
javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].
and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on
xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].
[NOTE]
@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop
However, you can only set this property if the `BeanFactoryPostProcessor` implements the
`Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should
consider implementing the `Ordered` interface, too. See the javadoc of the
The following example shows how one bean can be autowired to another bean:
@@ -333,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec
still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do
you know exactly where the `@Autowired AccountRepository` bean is declared? It is not
explicit in the code, and this may be just fine. Remember that the
https://spring.io/tools[Spring Tools for Eclipse] provides tooling that
{spring-site-tools}[Spring Tools for Eclipse] provides tooling that
can render graphs showing how everything is wired, which may be all you need. Also,
your Java IDE can easily find all declarations and uses of the `AccountRepository` type
and quickly show you the location of `@Bean` methods that return that type.
@@ -514,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro
for details).
The `@Profile` annotation is actually implemented by using a much more flexible annotation
called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].
called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].
The `@Conditional` annotation indicates specific
`org.springframework.context.annotation.Condition` implementations that should be
consulted before a `@Bean` is registered.
@@ -565,7 +570,7 @@ Kotlin::
----
======
See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]
See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]
javadoc for more detail.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.