Read the respective fields only once in the values(), entrySet(), and
keySet() methods.
Closes gh-35822
Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
(cherry picked from commit 3b6be3d4d3)
The Spliterators returned by values, entrySet, and keySet incorrectly
reported the SIZED characteristic, instead of CONCURRENT. This could
lead to bugs when the map is concurrently modified during a stream
operation.
For keySet and values, the incorrect characteristics are inherited from
AbstractMap, so to rectify that the respective methods are overridden,
and custom collections are provided that report the correct Spliterator
characteristics.
Closes gh-35817
Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
(cherry picked from commit ed75906834)
Prior to this commit, the `ReactorClientHttpRequestFactory` and the
`ReactorClientHttpRequest` would use the `Executor` from the current
event loop for performing write operations.
Depending on I/O demand, this work could be blocked and would result in
blocked Netty event loop executors and the HTTP client hanging.
This commit ensures that the client uses a separate Executor for such
operations. If the application does not provide one on the request
factory, a `Schedulers#boundedElastic` instance will be used.
Fixes gh-34707
Prior to this commit, Spring Framework's JSP form tags supported the
response encoding in most places; however, <form:select> and
<form:options> still did not support the response character encoding.
To address that, this commit updates SelectTag, OptionsTag, and
OptionWriter to provide support for response character encoding in the
`select` and `options` JSP form tags.
See gh-33023
Closes gh-35783
This commit ensures that both `VirtualThreadDelegate` implementations
expose the same public API. If not, JAR verification fails with the
following message:
```
jar --validate --file spring-core-6.2.13-SNAPSHOT.jar
entry: META-INF/versions/21/org/springframework/core/task/VirtualThreadDelegate.class, contains a class with different api from earlier version
```
Fixes gh-35773
Prior to this commit, gh-35213 allowed wildcard path elments at the
start of path patterns. This came with an additional constraint that
rejected such patterns if the pattern segment following the wildcard one
was not a literal:
* `/**/{name}` was rejected
* `/**/something/{name}` was accepted
The motivation here was to make the performance impact of wildard
patterns as small as possible at runtime.
This commit relaxes this constraint because `/**/*.js` patterns are very
popular in the security space for request matchers.
Closes gh-35686
This commit improves the reference document to better reflect the
different between `*` or `{name}` on one side, and `**` or `{*path}` on
the other.
The former patterns only consider a single path segment and its content,
while the latter variants consider zero or more path segments. This
explains why `/test/{*path}` can match `/test`.
Closes gh-35727
Prior to this commit, the `MappingMediaTypeFileExtensionResolver` would
resolve file extensions for a given media type by using a direct lookup
using the given media type provided by the request.
If the request contains a quality parameter like
"application/json;q=0.9", this would not resolve configured file
extensions for this media type.
While other media type parameters can be meaningful, the quality
parameter should not be used for lookups. This commit ensures that the
quality parameter is dropped before performing lookups.
Fixes gh-35754
Prior to this commit, the `HttpComponentsClientHttpRequestFactory` would
set the connection timeout on the request configuration. This has been
deprecated by the client itself and this value should be set while
creating the client on the connection manager itself.
This commit deprecates this method, as there is no way for the factory
to set this value anymore.
Closes gh-35748
Replace obsolete Concourse pipeline reference with GitHub Actions.
The Concourse link returns 404.
See gh-35746
Signed-off-by: Moad ELFATIHI <elfatihi.moad@gmail.com>
When JAR manifest Class-Path entries contain absolute paths (as Gradle
creates on Windows for long classpaths), PathMatchingResourcePatternResolver
incorrectly rejected them.
Fixes#35730
Signed-off-by: Artur Signell <artur@vaadin.com>
When concurrency limiting is enabled via setConcurrencyLimit() and
thread creation fails in doExecute() (e.g., OutOfMemoryError from
Thread.start()), the concurrency permit acquired by beforeAccess()
is never released because TaskTrackingRunnable.run() never executes.
This causes the concurrency count to permanently remain at the limit,
causing all subsequent task submissions to block forever in
ConcurrencyThrottleSupport.onLimitReached().
Root cause:
- beforeAccess() increments concurrencyCount
- doExecute() throws Error before thread starts
- TaskTrackingRunnable.run() never executes
- afterAccess() in finally block never called
- Concurrency permit permanently leaked
Solution:
Wrap doExecute() in try-catch block in the concurrency throttle path
and call afterAccess() in catch block to ensure permit is always
released, even when thread creation fails.
The fix only applies to the concurrency throttle path. The
activeThreads-only path does not need fixing because it never calls
beforeAccess(), so there is no permit to leak.
Test approach:
The test simulates thread creation failure and verifies that a
subsequent execution does not deadlock. The first execution should
fail with some exception (type doesn't matter), and the second
execution should complete within timeout if the permit was properly
released.
Signed-off-by: Park Juhyeong <wngud5957@naver.com>
Previous commit 81ea35c726 in main for 7.0
should have been applied in 6.2.x first for 6.2.1.
This commit applies the changes in 6.2.x as intended,
effective as of 6.2.13.
Closes gh-33974
Although gh-35680 introduced support for JUnit Jupiter's TEST_METHOD
ExtensionContextScope in the SpringExtension and
BeanOverrideTestExecutionListener, those were internal changes that are
not directly visible by TestExecutionListener authors.
However, in order to be compatible with a test-method scoped
TestContext (which takes its values from the current Jupiter
ExtensionContext), existing third-party TestExecutionListener
implementations may need to be modified similar to how
BeanOverrideTestExecutionListener was modified in commit d24a31d469.
To raise awareness of how to deal with such issues, this commit
documents test-method TestContext semantics for TestExecutionListener
authors.
Closes gh-35716
Cache resource URLs before sorting to eliminate repeated I/O calls
during comparator operations. The previous implementation called
getURL() multiple times per resource during sorting (O(n log n)
calls), and silently swallowed IOExceptions by returning 0,
potentially causing unstable sort results.
This change:
- Caches URLs once per resource before sorting (O(n) I/O calls)
- Removes unnecessary ArrayList conversions
- Provides clear exception handling with context
- Improves performance by ~70% for typical use cases
Signed-off-by: Park Juhyeong <wngud5957@naver.com>
Prior to this commit, getPubliclyAccessibleMethodIfPossible() in
ClassUtils incorrectly returned a hidden static method as an
"equivalent" method for a static method with the same signature;
however, a static method cannot be overridden and therefore has no
"equivalent" method in a super type.
To fix that bug, this commit immediately aborts the search for an
"equivalent" publicly accessible method when the original method is a
static method.
See gh-33216
See gh-35189
See gh-35556
Closes gh-35667
Since we now officially support the TEST_METHOD ExtensionContextScope
(see gh-35676 and gh-35680), this commit introduces tests which
demonstrate that the issue raised in gh-34576 is no longer an "issue" if
the user indirectly configures the SpringExtension to use the TEST_METHOD
scope via the "junit.jupiter.extensions.testinstantiation.extensioncontextscope.default"
configuration parameter.
Historically, @Autowired fields in an enclosing class of a @Nested
test class have been injected from the ApplicationContext for the
enclosing class. If the enclosing test class and @Nested test class
share the same ApplicationContext configuration, things work as
developers expect. However, if the enclosing class and @Nested test
class have different ApplicationContexts, that can lead to
difficult-to-debug scenarios. For example, a bean injected into the
enclosing test class will not participate in a test-managed transaction
in the @Nested test class (see gh-34576).
JUnit Jupiter 5.12 introduced a new ExtensionContextScope feature which
allows the SpringExtension to behave the same for @Autowired fields as
it already does for @Autowired arguments in lifecycle and test
methods. Specifically, if a developer sets the ExtensionContextScope to
TEST_METHOD — for example, by configuring the following configuration
parameter as a JVM system property or in a `junit-platform.properties`
file — the SpringExtension already supports dependency injection from
the current, @Nested ApplicationContext in @Autowired fields in an
enclosing class of the @Nested test class.
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method
However, there are two scenarios that fail as of Spring Framework
6.2.12.
1. @TestConstructor configuration in @Nested class hierarchies.
2. Field injection for bean overrides (such as @MockitoBean) in
@Nested class hierarchies.
Commit 82c34f7b51 fixed the SpringExtension to support scenario #2
above.
To fix scenario #1, this commit revises
BeanOverrideTestExecutionListener's injectField() implementation to
look up the fields to inject for the "current test instance" instead of
for the "current test class".
This commit also introduces tests for both scenarios.
See gh-34576
See gh-35676
Closes gh-35680
Prior to this commit, a regexp path segment ending with a double wilcard
(like "/path**") would be incorrectly parsed as a double wildcard
segment ("/**").
This commit fixes the incorrect parsing.
See gh-35679
Prior to this commit, the `PathPattern` and `PathPatternParser` would
allow multiple-segments matching and capturing with the following:
* "/files/**" (matching 0-N segments until the end)
* "/files/{*path}" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This would be only allowed as the last path element in the pattern and
the parser would reject other combinations.
This commit expands the support and allows multiple segments matching at
the beginning of the path:
* "/**/index.html" (matching 0-N segments from the start)
* "/{*path}/index.html" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This does come with additional restrictions:
1. "/files/**/file.txt" and "/files/{*path}/file.txt" are invalid,
as multiple segment matching is not allowed in the middle of the
pattern.
2. "/{*path}/files/**" is not allowed, as a single "{*path}" or "/**"
element is allowed in a pattern
3. "/{*path}/{folder}/file.txt" "/**/{folder:[a-z]+}/file.txt" are
invalid because only a literal pattern is allowed right after
multiple segments path elements.
Closes gh-35679
This commit introduces a new isAutowirableConstructor(Executable, PropertyProvider)
overload in TestConstructorUtils and deprecates all other existing variants
for removal in 7.1.
Closes gh-35676
Thanks to a proposal from @wilkinsona, this commit introduces a
try-catch block in loadBeanDefinitions(...) which throws an
IllegalStateException that provides context regarding the configuration
class and cause of the failure.
Closes gh-35631
Co-authored-by: Andy Wilkinson <andy.wilkinson@broadcom.com>
As reported in gh-34651, `DataBuffer#getByte` can be inefficient for
some implementations, as bound checks are performed for each call.
This commit introduces a new `forEachByte` method that helps with
traversing operations without paying the bound check cost for each byte.
Closes gh-35623
Prior to this commit, a NoUniqueBeanDefinitionException was thrown when
multiple primary beans were detected within a given set of beans, but
nothing was logged. For use cases where the exception is handled by
infrastructure code, it may not be obvious to the developer what the
problem is.
To address that, a TRACE message is now logged whenever multiple
competing primary beans are detected in DefaultListableBeanFactory.
Closes gh-35550
This commit adds a reproducer for the change of behavior introduced via
https://youtrack.jetbrains.com/issue/KT-76667. The test is only broken
with Kotlin 2.2.20+ without the related fix (see previous commit).
Closes gh-35487
Prior to this commit, AbstractTestNGSpringContextTests was not
thread-safe with regard to tracked exceptions.
To address that, AbstractTestNGSpringContextTests now tracks the test
exception via a ThreadLocal.
Closes gh-35528
Prior to this commit, the `IntrospectingClientHttpResponse` would try
and read the HTTP response stream in order to check for the presence of
a non-empty message body.
Developers reported that in some cases, an `EOFException` is thrown
instead of returning -1 from the `read()` method. This commit ensures
that this case is taken into account and that we report the response as
an empty body in these cases.
Closes gh-35361
This commit fixes code generation for a bean produced by a protected
factory method. Previously only the code generated for public methods,
i.e. without a dedicated instance supplier method, was handled.
Closes gh-35486
Prior to this commit, annotations were not found on parameters in an
overridden method unless the method was public. Specifically, the
search algorithm in AnnotatedMethod did not consider a protected or
package-private method in a superclass to be a potential override
candidate. This affects parameter annotation searches in
spring-messaging, spring-webmvc, spring-webflux, and any other
components that use or extend AnnotatedMethod.
To address that, this commit revises the search algorithm in
AnnotatedMethod to consider all non-final declared methods as potential
override candidates, thereby aligning with the search logic in
AnnotationsScanner for the MergedAnnotations API.
Closes gh-35349
Prior to this commit, gh-32097 added native support for Jetty for both
client and server integrations. The `JettyDataBufferFactory` was
promoted as a first class citizen, extracted from a private class in the
client support. To accomodate with server-side requirements, an extra
`buffer.retain()` call was performed.
While this is useful for server-side support, this introduced a bug in
the data buffer factory, as wrapping an existing chunk means that this
chunk is already retained.
This commit fixes the buffer factory implementation and moved existing
tests from mocks to actual pooled buffer implementations from Jetty.
The extra `buffer.retain()` is now done from the server support, right
before wrapping the buffer.
Fixes gh-35319
This commit reorders and clarifies the usage instructions for
ApplicationEvents to:
1. Recommend method parameter injection as the primary approach, since
ApplicationEvents has a per-method lifecycle
2. Clarify that ApplicationEvents is not a general Spring bean and
cannot be constructor-injected
3. Explicitly state that field injection is an alternative approach
This addresses confusion where developers expect ApplicationEvents to
behave like a regular Spring bean eligible for constructor injection.
See gh-35297
Closes gh-35335
Signed-off-by: khj68 <junthewise@gmail.com>
Prior to this commit, the MergedAnnotations support (specifically
AnnotationsScanner) and AnnotatedMethod did not find annotations on
overridden methods in type hierarchies with unresolved generics.
The reason for this is that ResolvableType.resolve() returns null for
such an unresolved type, which prevents the search algorithms from
considering such methods as override candidates.
For example, given the following type hierarchy, the compiler does not
generate a method corresponding to processOneAndTwo(Long, String) for
GenericInterfaceImpl. Nonetheless, one would expect an invocation of
processOneAndTwo(Long, String) to be @Transactional since it is
effectively an invocation of processOneAndTwo(Long, C) in
GenericAbstractSuperclass, which overrides/implements
processOneAndTwo(A, B) in GenericInterface, which is annotated with
@Transactional.
However, the MergedAnnotations infrastructure currently does not
determine that processOneAndTwo(Long, C) is @Transactional since it is
not able to determine that processOneAndTwo(Long, C) overrides
processOneAndTwo(A, B) because of the unresolved generic C.
interface GenericInterface<A, B> {
@Transactional
void processOneAndTwo(A value1, B value2);
}
abstract class GenericAbstractSuperclass<C> implements GenericInterface<Long, C> {
@Override
public void processOneAndTwo(Long value1, C value2) {
}
}
static GenericInterfaceImpl extends GenericAbstractSuperclass<String> {
}
To address such issues, this commit changes the logic in
AnnotationsScanner.hasSameGenericTypeParameters() and
AnnotatedMethod.isOverrideFor() so that they use
ResolvableType.toClass() instead of ResolvableType.resolve(). The
former returns Object.class for an unresolved generic which in turn
allows the search algorithms to properly detect method overrides in
such type hierarchies.
Closes gh-35342
Prior to this commit, ScriptUtils.executeSqlScript() treated every
statement within the script as if it were a single insert/update/delete
statement. This disregarded the fact that the execution of a JDBC
Statement can result in multiple individual statements, some of which
result in a ResultSet and others that result in an update count.
For example, when executing a stored procedure on Sybase, ScriptUtils
did not execute all statements within the stored procedure.
To address that, this commit revises the implementation of
ScriptUtils.executeSqlScript() so that it handles multiple results and
differentiates between result sets and update counts.
Closes gh-35248
Handle CancellationException in order to throw an HttpTimeoutException
when the timeout handler caused the cancellation.
See gh-34721
Signed-off-by: giampaolo <giampaorr@gmail.com>
fix: use timeoutHandler with a flag isTimeout
Closes gh-33973
Signed-off-by: giampaolo <giampaorr@gmail.com>
Refine the StringUtils#uriDecode method in the following ways:
- Use a StringBuilder instead of ByteArrayOutputStream, and only decode
%-encoded sequences.
- Use HexFormat.fromHexDigits to decode hex sequences.
- Decode to a byte array that is only allocated if encoded sequences are
encountered.
This commit adds another optimization mainly for the use case where
there is no encoded sequence, and updates the Javadoc of both
StringUtils#uriDecode and UriUtils#decode to match the implementation.
Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
Co-Authored-by: Sebastien Deleuze <sebastien.deleuze@broadcom.com>
Closes gh-35253
Prior to this commit, subclasses of AbstractBeanFactoryBasedTargetSource
referenced the targetBeanName via getTargetBeanName() which throws an
IllegalStateException if the targetBeanName has not yet been set.
This commit changes the visibility of the targetBeanName field from
private to protected in order to facilitate direct access through
this.targetBeanName where no assertion is needed.
By doing so, we avoid exceptions in logging and toString()
implementations in subclasses.
Closes gh-35172
Signed-off-by: chenggwang <90715678+chenggwang@users.noreply.github.com>
Co-authored-by: Sam Brannen <104798+sbrannen@users.noreply.github.com>
If an application depends on automatic type conversion from
java.time.Instant to java.sql.Timestamp, the ObjectToObjectConverter
performs the conversion based on convention, by using reflection to
invoke Timestamp.from(Instant).
However, when running in a native image a user needs to explicitly
register runtime hints for that particular use of reflection.
To assist users who are running their applications in a native image,
this commit automatically registers the necessary runtime hints for
Timestamp.from(Instant) so that users do not have to.
See gh-35175
Closes gh-35156
In order to avoid unnecessary use of reflection and to simplify native
image deployments, this commit introduces explicit support for
automatic conversions from java.util.Date to java.time.Instant and vice
versa.
To achieve that, this commit introduces an InstantToDateConverter and a
DateToInstantConverter and registers them automatically in
DefaultConversionService.
See gh-35156
Closes gh-35175
The @CacheConfig section of the reference manual provides an example
that declares @CacheConfig("books").
However, unlike the @Cacheable, @CachePut, and @CacheEvict
annotations, @CacheConfig currently does not have a `value` alias for
the `cacheNames` attribute. Thus, the example in the reference manual
does not compile, and @CacheConfig(cacheNames = "books") would be the
supported way to declare that.
The driving factor for this commit is therefore to provide a simplified
and consistent programming model for users that only need to define
default cache names at the type level (like in the existing example in
the reference manual).
To address that, this commit introduces a `value` alias for
`cacheNames` in @CacheConfig.
See gh-35096
Closes gh-35152
(cherry picked from commit 6091453feb)
Update `SpringFactoriesLoader` so that the cache stores only the
factories and not the complete loader.
Prior to this commit, if a cache entry was added with the thread
context classloader, the loader instance would be added and the
classloader stored. If the thread context classloader subsequently
changes, and a call is made to `forDefaultResourceLocation` with
`null` for the classloader, the cached entry would be used which
contains the older classloader.
Closes gh-34732
The compiler has a constants pool limit of 65536 entries per source file
which can be hit with a very large amount of beans to register in the
bean factory.
This commit makes sure to create separate source files if the number
of beans to register is very large. The main generated source file
delegate to those.
Closes gh-35044
This commit simplifies our dependency management for JUnit artifacts by
making use of the junit-jupiter and junit-platform-suite aggregator
artifacts.
Closes gh-35127
This commit allows RestClient to handle StreamingHttpOutputMessage
properly by checking the type of the request and invoking setBody()
when appropriate. This improves interoperability with components that
expect streamed output.
A new integration test has been added to verify the functionality.
See gh-35102
Signed-off-by: Daniil Razorenov <daniltmb@gmail.com>
This commit fixes a regression introduced in gh-34971 where GET and
DELETE requests would not allow request bodies anymore for
`JdkClientHttpRequest`.
We are now using `builder.GET()` and `builder.DELETE()` methods only if
the provided body is null.
Fixes gh-35068
Historically, we have used `<introduction year>-<modification year>` as
the pattern for copyright headers.
For example: `Copyright 2002-2025 the original author or authors.`
However, we have been encouraged to use `present` as the modification
year.
In light of that, this commit updates the following to enforce the new
pattern.
- The patterns in our SpringHeaderCheck Checkstyle rules
- The `Copyright 2002-${year}` template in org.eclipse.jdt.ui.prefs
- The update_copyright_headers.sh script
See gh-35070
Prior to this commit, the `DefaultServerWebExchange` would attempt to
decode request bodies as form-data or multipart of the request
content-type was compatible with the expected media types.
If requests are sent with an invalid wildcard content-type such as "*/*"
or "multipart/*", we should not attempt to decode here.
Fixes gh-34660
Prior to this commit, the `ResourceHttpRequestHandler` would detect
invalid range requests and reply with a 416 response status and the
relevant range header. Because this was triggering an error dispatch,
the error handling would collect error metadata and produce an error
response with the original content-type.
This would most likely fail because the content-type is most likely a
file-related media type which cannot be used for error responses.
This commit resets the response content type in these cases and let the
error handling pick the most sensible media type for the error response.
Fixes gh- 34490
Prior to this commit, the WebFlux server support would try reading
form-data from the request by:
* first, checking that request content-type is compatible with a
form-data content-type
* then by selecting a message reader that is compatible with the given
request content-type
This approach is flawed because if the content-type provided by the
request is too broad, another message reader could be selected that's
not meant to be used for reading form-data. Typically, a JSON message
reader could be selected and would fail when reading the request.
This problem was previously hidden because message readers would not
support `MultiValueMap` as a target type. Now that some readers support
this type, this can lead to deserialization errors.
This commit now ensures that in all cases, we attempt to read form-data
with a message reader that supports the
"application/x-www-form-urlencoded" media type.
Fixes gh-34660
Prior to this commit, the "filename" parameter value for the
"Content-Disposition" header would contain non-printable characters,
causing parsing issues for HTTP clients.
This commit ensures that all non-printable characters are encoded.
Fixes gh-35034
Previously, when saving a WebSession, the system did not check whether
the session ID already existed. As a result, even if the session being
saved was an update to an existing one, it was incorrectly treated as a
new session, and a "maximum sessions exceeded" error was triggered.
This fix ensures that if a WebSession with the same ID already exists,
it will be updated rather than counted as a new session, thereby
preventing unnecessary session limit violations.
Closes gh-35013
Signed-off-by: Mohammad Saeed Nouri <msnsaeed71@gmail.com>
This commit adds `ProblemDetail` and `ErrorResponse` to the list of
supported return types for `@ExceptionHandler` methods.
Closes gh-34554
Signed-off-by: Vedran Pavic <vedran@vedranpavic.com>
AbstractKotlinSerializationHttpMessageConverter#getSupportedMediaTypes(Class<?>)
currently invokes transitively supports(Class<?>) which always return false
with generic types.
This commit adds an override that just invokes getSupportedMediaTypes().
Closes gh-34992
per https://www.rfc-editor.org/rfc/rfc7232#section-4.1
The server generating a 304 response MUST generate any of the
following header fields that would have been sent in a 200 (OK)
response to the same request: Cache-Control, Content-Location, Date,
ETag, Expires, and Vary.
Closes gh-34614
Signed-off-by: James Yuzawa <jtyuzawa@gmail.com>
Prior to this commit, combining the "/*" and "/x/y" path patterns
would result in a `StringIndexOutOfBoundsException`.
This commit fixes this problem and revisits the implementation for
better consistency:
* "/*" + "/x/y" is now "/x/y"
* "/x/*.html" + "/y/file.*" is now rejected because they don't share the
same prefix.
This change also adds the relevant Javadoc to the `PathPattern#combine`
method.
Fixes gh-34986
Add optimized DataBufferInputStream overrides for readNBytes, skip, and transferTo; all of them
allocate byte buffers which we can either avoid (in the case of skip) or size more precisely since
the number of remaining bytes is known.
Closes gh-34799
Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
Prior to this commit, we would use the
`java.net.http.HttpRequest.Builder#method(String, BodyPublisher)` to
create HTTP requests for the JDK HttpClient. This method requires a
non-null body publisher; providing an empty publisher writes a
"Content-Length: 0" header to all requests.
As of Java 19, this behavior changes for `HttpRequest.Builder#GET` and
similar methods, where the body publisher is considered as null and no
"Content-Length" header is written.
This commit aligns with this behavior and favors dedicated HTTP methods
whenever available.`
Closes gh-34971
Prior to this commit, argument index handling in
AutowiredArgumentsCodeGenerator suffered from an off-by-one error when
generating code for an autowired inner class constructor.
Since the startIndex is already properly calculated for an inner class in
InstanceSupplierCodeGenerator.buildGetInstanceMethodForConstructor(...),
there is no need to adjust the argument indexes within
AutowiredArgumentsCodeGenerator.generateCode(...).
Closes gh-34974
Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
Prior to this commit, the verifyType() method in MessageHeaderAccessor
checked if REPLY_CHANNEL ended with the given header name which does
not make much sense and is inconsistent with the ERROR_CHANNEL check.
This commit therefore checks if the REPLY_CHANNEL is equal to the given
header name, analogous to the ERROR_CHANNEL check.
See gh-34881
Closes gh-34949
Signed-off-by: Mengqi Xu <2663479778@qq.com>
This commit fixes a regression in PropertySourcesPlaceholderConfigurer
that was introduced in Spring Framework 6.2.7.
Specifically, this commit reinstates automatic String-conversion of
values from PropertySources in the Environment using the
ConversionService configured in the Environment.
See gh-34861
Closes gh-34936
This commit introduces a @Disabled "regression test" which demonstrates
that PropertySourcesPlaceholderConfigurer uses the ConversionService
from the Environment.
See gh-34936
The setProperty() and withProperty() methods in MockEnvironment were
originally introduced with (String, String) signatures; however, they
should have always had (String, Object) signatures in order to comply
with the MockPropertySource and PropertySource APIs.
To address that, this commit changes the signatures of these methods so
that they only accept Object values for properties.
NOTE: this commit only affects the internal MockEnvironment used as a
test fixture. This commit does not affect the official, public
MockEnvironment implementation in spring-test.
See gh-34947
See gh-34948
The setProperty() and withProperty() methods in MockEnvironment were
originally introduced with (String, String) signatures; however, they
should have always had (String, Object) signatures in order to comply
with the MockPropertySource and PropertySource APIs.
To address that, this commit introduces variants of these methods that
accept Object values for properties.
Closes gh-34947
Prior to this commit, a BeanDefinitionReader registered via
@ImportResource was required to be public and have a public
constructor that accepts a single BeanDefinitionRegistry. However, the
public visibility requirements are not necessary, and the requirements
for the constructor's formal parameter list is not documented.
To address those issues, this commit removes the public visibility
restrictions and documents that a BeanDefinitionReader registered via
@ImportResource must declare a constructor that accepts a single
BeanDefinitionRegistry.
In addition, this commit includes the cause of the instantiation
failure in case the registered BeanDefinitionReader cannot be
instantiated.
Closes gh-34928
Prior to this commit, the JAXB message converters would only rely on the
encoding declaration inside the XML document for reading the document.
This would then use the default UTF-8 encoding, even if the HTTP message
has the `"application/xml;charset=iso-8859-1"` Content-Type.
This commit ensures that both `Jaxb2CollectionHttpMessageConverter` and
`Jaxb2RootElementHttpMessageConverter` use the encoding declared in the
HTTP Content-Type, if present.
Fixes gh-34745
After the bootstrap phase (and with spring.locking.strict=true during the bootstrap phase), getSingletonFactoryBeanForTypeCheck always locks. In a background bootstrap thread, it never locks. Otherwise, it tries locking and explicitly resolves the bean class for subsequent type-based resolution (even for a component-scanned class) when it fails to acquire the lock. Furthermore, getObjectFromFactoryBean follows the same locking algorithm for post-processing.
Closes gh-34902
NonClosingInputStream extends FilterInputStream, which does not forward some
newer InputStream methods such as transferTo and readAllBytes. Specific InputStream
implementations may have more optimized methods (e.g., FileInputStream).
Closes gh-34893
Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
Spring Framework 6.2 introduced support for an escape character for
property placeholders (by default '\'). However, as of Spring Framework
6.2.6, there was no way to either escape the escape character or disable
escape character support.
For example, given a `username` property configured with the value of
`Jane.Smith` and a `DOMAIN\${username}` configuration string, property
placeholder replacement used to result in `DOMAIN\Jane.Smith` prior to
6.2 but now results in `DOMAIN${username}`. Similarly, an attempt to
escape the escape character via `DOMAIN\\${username}` results in
`DOMAIN\${username}`.
In theory, one should be able to disable use of an escape character
altogether, and that is currently possible by invoking
setEscapeCharacter(null) on AbstractPropertyResolver and
PlaceholderConfigurerSupport (the superclass of
PropertySourcesPlaceholderConfigurer).
However, in reality, there are two hurdles.
- As of 6.2.6, an invocation of setEscapeCharacter(null) on a
PropertySourcesPlaceholderConfigurer applied to its internal
top-level PropertySourcesPropertyResolver but not to any nested
PropertySourcesPropertyResolver, which means that the `null` escape
character could not be effectively applied.
- Users may not have an easy way to explicitly set the escape character
to `null` for a PropertyResolver or
PropertySourcesPlaceholderConfigurer. For example, Spring Boot
auto-configures a PropertySourcesPlaceholderConfigurer with the
default escape character enabled.
This first issue above has recently been addressed by gh-34861.
This commit therefore addresses the second issue as follows.
- To allow developers to easily revert to the pre-6.2 behavior without
changes to code or configuration strings, this commit introduces a
`spring.placeholder.escapeCharacter.default` property for use with
SpringProperties which globally sets the default escape character that
is automatically configured in AbstractPropertyResolver and
PlaceholderConfigurerSupport.
- Setting the property to an empty string sets the default escape
character to `null`, effectively disabling the default support for
escape characters.
spring.placeholder.escapeCharacter.default =
- Setting the property to any other character sets the default escape
character to that specific character.
spring.placeholder.escapeCharacter.default = ~
- Setting the property to a string containing more than one character
results in an exception.
- Developers are still able to configure an explicit escape character
in AbstractPropertyResolver and PlaceholderConfigurerSupport if they
choose to do so.
- Third-party components that wish to rely on the same feature can
invoke AbstractPropertyResolver.getDefaultEscapeCharacter() to obtain
the globally configured default escape character.
See gh-9628
See gh-34315
See gh-34861
Closes gh-34865
This commit overrides containsProperty() in
FallbackEnvironmentPropertySource for consistency with the
implementation of ConfigurableEnvironmentPropertySource.
See gh-34861
Although it's unlikely that the implementation of getPropertySources()
in a ConfigurableEnvironment would be overridden to return a different
MutablePropertySources instance than the one that the
ConfigurableEnvironment typically acts on, it is in fact possible.
In light of that possibility, this commit refactors
ConfigurableEnvironmentPropertySource so that it always obtains a fresh
PropertySources reference.
See gh-34861
Commit 3295289e17 fixed a number issues with placeholder resolution in
PropertySourcesPlaceholderConfigurer. However, in doing so, it replaced
a raw PropertySource with a CompositePropertySource which implements
EnumerablePropertySource.
Consequently, all property sources registered in the Environment must
now implement EnumerablePropertySource (which is not an actual
requirement). Otherwise, invocations of getPropertyNames() on the
CompositePropertySource result in an IllegalStateException, and that is
a breaking change which resulted in numerous build failures within the
Spring portfolio.
To address that regression, this commit introduces a private
ConfigurableEnvironmentPropertySource in
PropertySourcesPlaceholderConfigurer which is a "raw" PropertySource
that delegates directly to the PropertySources in a
ConfigurableEnvironment.
This commit also extracts the raw PropertySource for direct Environment
delegation into a new FallbackEnvironmentPropertySource.
See gh-17385
Closes gh-34861
Currently, the placeholder resolution algorithm in
PropertySourcesPlaceholderConfigurer fails in several scenarios, and
the root cause for this category of failures has actually existed since
PropertySourcesPlaceholderConfigurer was introduced in Spring Framework
3.1.
Specifically, PropertySourcesPlaceholderConfigurer creates its own
PropertySourcesPropertyResolver that indirectly delegates to another
"nested" PropertySourcesPropertyResolver to interact with
PropertySources from the Environment, which results in double
placeholder parsing and resolution attempts, and that behavior leads to
a whole category of bugs.
For example, #27947 was addressed in Spring Framework 5.3.16, and due
to #34315 and #34326 we have recently realized that additional bugs
exist with placeholder resolution: nested placeholder resolution can
fail when escape characters are used, and it is currently impossible
to disable the escape character support for nested resolution.
To address this category of bugs, we no longer indirectly use or
directly create a "nested" PropertySourcesPropertyResolver in
PropertySourcesPlaceholderConfigurer. Instead, properties from property
sources from the Environment are now accessed directly without
duplicate/nested placeholder resolution.
See gh-27947
See gh-34326
See gh-34862
Closes gh-34861
The last assertion of the new test method currently fails since "foo"
is only bound once.
java.lang.AssertionError:
Expected size: 2 but was: 1 in:
{0="foo"}
See gh-34768
This commit introduces a new constructor for CompositePropertySource
that accepts a `String name` and an Iterable<PropertySource<?>>, which
allows a CompositePropertySource to be constructed from existing
property sources, such as an instance of MutablePropertySources.
Closes gh-34862
As of gh-33806, the HttpComponents client request factory is forward
compatible with the 5.4+ versions of that library for configuring HTTP
request configuration.
This change would not tkae into account configuration set at the Spring
level because it would consider the default `RequestConfig` instance as
a custom one. This commit ensures that Spring sets its own configuration
if no custom configuration was set for all supported HttpComponents
generations.
Fixes gh-34851
Prior to this commit, bean overrides (such as @MockitoBean, etc.) were
discovered multiple times if they were declared:
- at the type-level on an interface that is implemented at more than
one level in the type hierarchy, the enclosing class hierarchy, or a
combination of the type and enclosing class hierarchies.
or
- on a field declared in a class which can be reached multiple times
while traversing the type and enclosing class hierarchies in
scenarios such as the following: the class (X) in which the field is
declared is a supertype of an enclosing type of the test class, and X
is also an enclosing type of a supertype of the test class.
Such scenarios resulted in an IllegalStateException stating that a
duplicate BeanOverrideHandler was discovered.
To address that, this commit revises the search algorithm in
BeanOverrideHandler so that all types (superclasses, enclosing classes,
and implemented interfaces) are only visited once while traversing the
type and enclosing class hierarchies in search of bean override
handlers.
See gh-33925
See gh-34324
Closes gh-34844
To ensure that failures in javadoc tasks do not result in documentation
silently not being generated/published, this commit sets
`failOnError = true` for all javadoc tasks.
See gh-27497
See gh-34774
Closes gh-34837
In 49e5c84928 I unfortunately overlooked
several JUnit 4 based tests in the `junit4` package that should be
migrated to JUnit Jupiter.
This commit address those remaining test classes.
See gh-23451
See gh-34794
Closes gh-34813
This commit revises the implementation of TestConventions so that
existing JUnit Platform options from a pre-configured `test` task are
copied instead of overridden.
Closes gh-34827
In commit 05ebca8677, the `public` modifier was removed from the
SpringAtInjectTckTests class, which prevents it from being run as a
JUnit 3 test class.
To address that, this commit adds the missing `public` modifier as well
as a a code comment to help prevent this from happening again.
In addition, this commit updates spring-context.gradle to ensure that
the JUnit Vintage test engine is always applied. However, that Gradle
configuration is unfortunately ignored due to how our TestConventions
class has been implemented. Thus, that issue will have to be addressed
separately.
Closes gh-34800
In Spring Framework 5.2, we migrated most of the test suite from JUnit
4 to JUnit Jupiter; however, prior to this commit, several tests in the
spring-test module were still based on JUnit 4 unnecessarily.
Since we are now planning to deprecate our JUnit 4 support in 7.0, this
commit migrates our remaining JUnit 4 based tests to JUnit Jupiter
whenever feasible. In the process, test classes that previously resided
under the "junit4" package have been moved to new packages directly
under the "org.springframework.text.context" package, and several
classes have been renamed for greater clarity of purpose.
Consequently, the only remaining tests based on JUnit 4 are those tests
that are required to run with JUnit 4 in order to test our JUnit 4
support.
This commit also greatly simplifies exclusions for Checkstyle rules
pertaining to JUnit usage.
See gh-23451
See gh-34794
Closes gh-34813
This commit makes AbstractJackson2HttpMessageConverter#getObjectMappersForType
return value non nullable as an empty map is returned in case of no
registrations.
Closes gh-34811
Specifically, the documentation update reflects that:
- Initially, it was mentioned that only the `BeanFactoryAware`
interface is ignored by default.
- The updated documentation now correctly states that `BeanNameAware`,
`BeanFactoryAware`, and `BeanClassLoaderAware` interfaces are all
ignored by default.
This change ensures a more accurate representation of the default
behavior regarding which dependency interfaces are automatically
ignored during autowiring in the context of Spring's bean factory
mechanism.
Closes gh-34747
Signed-off-by: lituizi <2811328244@qq.com>
Includes spring.locking.strict revision to differentiate between true, false, not set.
Includes checkFlag accessor on SpringProperties, also used in StatementCreatorUtils.
Closes gh-34729
See gh-34303
This commit provides first-class support for Bean Overrides
(@MockitoBean, @MockitoSpyBean, @TestBean, etc.) with
@ContextHierarchy.
Specifically, bean overrides can now specify which ApplicationContext
they target within the context hierarchy by configuring the
`contextName` attribute in the annotation. The `contextName` must match
a corresponding `name` configured via @ContextConfiguration.
For example, the following test class configures the name of the second
hierarchy level to be "child" and simultaneously specifies that the
ExampleService should be wrapped in a Mockito spy in the context named
"child". Consequently, Spring will only attempt to create the spy in
the "child" context and will not attempt to create the spy in the
parent context.
@ExtendWith(SpringExtension.class)
@ContextHierarchy({
@ContextConfiguration(classes = Config1.class),
@ContextConfiguration(classes = Config2.class, name = "child")
})
class MockitoSpyBeanContextHierarchyTests {
@MockitoSpyBean(contextName = "child")
ExampleService service;
// ...
}
See gh-33293
See gh-34597
See gh-34726
Closes gh-34723
Signed-off-by: Sam Brannen <104798+sbrannen@users.noreply.github.com>
For bean override support (@MockitoBean, @TestBean, etc.), the logic
for field injection previously resided in the BeanOverrideRegistry
which resulted in a strange mixture of concerns.
To address that, this commit moves the field injection logic to the
BeanOverrideTestExecutionListener, and the BeanOverrideRegistry now
serves a single role, namely the role of a registry.
Closes gh-34726
- ClassUtils.isAssignable(): Avoid Map lookup when the type is not a
primitive.
- AnnotationsScanner: Perform low cost array length check before String
comparisons.
- BeanFactoryUtils: Use char comparison instead of String comparison.
The bean factory prefix is '&', so we can use a char comparison
instead of more heavyweight String.startsWith("&").
- AbstractBeanFactory.getMergedBeanDefinition(): Perform the low cost
check first. Map lookup, while cheap, is still more expensive than
instanceof.
Closes gh-34717
Signed-off-by: Olivier Bourgain <olivierbourgain02@gmail.com>
Prior to this commit, the `DefaultWebClient` observability
instrumentation would create the observation context before the reactive
pipeline is fully materialized. In case of errors and retries (with the
`retry(long)` operator), the observation context would be reused for
separate observations, which is incorrect.
This commit ensures that a new observation context is created for each
subscription.
Fixes gh-34671
This commit is a follow-up to gh-34592. It introduces
recursive boxing of Kotlin nested value classes in CoroutinesUtils.
Signed-off-by: Dmitry Sulman <dmitry.sulman@gmail.com>
Closes gh-34682
Historically, @Configuration classes that did not declare @Bean
methods were allowed to be abstract. However, the changes made in
76a6b9ea79 introduced a regression that prevents such classes from
being abstract, resulting in a BeanInstantiationException. This change
in behavior is caused by the fact that such a @Configuration class is
no longer replaced by a concrete subclass created dynamically by CGLIB.
This commit restores support for abstract @Configuration classes
without @Bean methods by modifying the "no enhancement required" check
in ConfigurationClassParser.
See gh-34486
Closes gh-34663
This commit fixes a minor typo in the "Java Bean Validation - Customizing
Validation Errors" section of the reference manual.
Closes gh-34686
Signed-off-by: Tobias Hänel <contact@tobias-haenel.de>
Prior to this commit, the Test Bean Override feature provided support
for overriding beans based on qualifier annotations in several
scenarios; however, qualifier annotations got lost if they were
declared on the return type of the @Bean method for the bean being
overridden and the @BeanOverride (such as @MockitoBean) was based on
a supertype of that return type.
To address that, this commit sets the @BeanOverride field as the
"qualified element" in the RootBeanDefinition to ensure that qualifier
annotations are available for subsequent autowiring candidate
resolution.
Closes gh-34646
This commit updates the tests of property values code generated to
invoke the generated code from a `static` context. This ensures that
the test fails if that's not the case.
This commit also updated LinkedHashMap handling that did suffer from
that problem.
Closes gh-34659
Before RfcUriParser we expected opaque URI's to not have ":/"
after the scheme while the new parser expect opaque URI's to
not have a slash anywhere after the scheme. This commit
restores the previous behavior.
Closes gh-34588
This commit replaces use of the deprecated Gradle `task` method with
the new `tasks.register` method.
Closes gh-34617
Signed-off-by: Dmitry Sulman <dmitry.sulman@gmail.com>
This commit removes the BDDMockito Checkstyle rule, since it did not
actually enforce the use of BDDMockito.
This commit also updates static imports to use Mockito instead of
BDDMockito where appropriate (automated via the Eclipse IDE Organize
Imports clean-up task).
Closes gh-34616
FormHttpMessageConverter could throw a more specific
HttpMessageNotReadableException instead of an IllegalArgumentException
when the http form data is invalid.
See gh-34594
Signed-off-by: Russell Bolles <rbolles@netflix.com>
Prior to this commit, MockCookie.parse() failed with an
IllegalArgumentException when attempting to parse a custom attribute
with a value, such as "Version=1". This is a regression that was
inadvertently introduced in 7fc4937199
when adding support for the "Partitioned" attribute which does not
support a value.
This commit addresses this regression by parsing both the name and the
value from an optional, custom attribute.
See gh-31454
Closes gh-34575
This commit introduces a new loadContextForAotProcessing(...) variant
in AotContextLoader which accepts a RuntimeHints argument. This new
method is an interface default method which delegates to the existing
loadContextForAotProcessing(MergedContextConfiguration) variant for
backward compatibility.
In addition, the original loadContextForAotProcessing(...) variant is
now deprecated and has been converted to an interface default method
which throws an UnsupportedOperationException.
Note, however, that the framework now only invokes the new
loadContextForAotProcessing(...) variant within TestContextAotGenerator.
Closes gh-34513
This commit adds support for the Partitioned cookie attribute in the
reactive HTTP clients that support this: Reactor and HttpComponents.
Closes gh-34521
Signed-off-by: Rhett CfZhuang <dark.momo985@gmail.com>
[brian.clozel@broadcom.com: rework tests and support HttpComponents]
Signed-off-by: Brian Clozel <brian.clozel@broadcom.com>
Prior to this commit, `MockHttpServletResponse` would only support
adding a `Content-Language` once. Adding multiple header values would
always replace the content-language property in the response and the
entire header value.
This commit ensures that this behavior is supported.
Fixes gh-34488
Prior to this commit, the `DispatcherServlet` would try and reset the
response buffer in case of errors, if the response is not committed
already. This allows for more flexible error handling, even if the
response was being handled already when it errored.
Resetting the response buffer clears the body but leaves HTTP response
headers intact. This is done on purpose as to not clear headers
previously added by Servlet Filters. By leaving in place some headers
like "Content-Type", this does not take into account the fact that the
response body was cleared and that error handling will perform another
round of content negotiation. While this isn't a problem for some
Servlet containers which enforce a single "Content-Type" header value,
this can cause multiple/duplicate values for some others.
This commit ensures that the "Content-Type" response header is removed
at the same time as we clear the "producible media types" attribute:
another pass of content negotiation will be performed for error
handling.
Fixes gh-34366
Prior to this commit, calling `setHeader` on the response wrapper would
have a separate code path for the "Content-Length" header. This did not
support calls with `null` values and would result in an exception.
This commit ensures that the cached content length value is reset in
this case and that the call is forwarded properly to the superclass.
Fixes gh-34460
Prior to this commit, `MockHttpServletResponse#setHeader` would not
remove the header entry when given a `null` value, as documented in the
Servlet API.
This commit ensures that this behavior is enforced.
Fixes gh-34464
This commit adds an onRequest() hook to request more data from
the source in order to avoid hung uploads in MultipartParser.
Closes gh-34388
Signed-off-by: Gang Cheng <chenggangpro@gmail.com>
This commit adds missing `@since` tags for formField() and formFields in
MockHttpServletRequestDsl. See gh-34412 related issue.
Closes gh-34448
Signed-off-by: Johnny Lim <izeye@naver.com>
In order to avoid Gradle build warnings about @SuppressFBWarnings, this
commit introduces a testCompileOnly dependency on `findbugs` in the
spring-webmvc module so that the class file for @SuppressFBWarnings is
available to the compileTestJava task.
Closes gh-34418
Prior to this commit, @MockitoSpyBean could only be declared on fields
within test classes, which prevented developers from being able to
easily reuse spy configuration across a test suite.
With this commit, @MockitoSpyBean is now supported at the type level
on test classes, their superclasses, and interfaces implemented by
those classes. @MockitoSpyBean is also supported on enclosing classes
for @Nested test classes, their superclasses, and interfaces
implemented by those classes, while honoring @NestedTestConfiguration
semantics.
In addition, @MockitoSpyBean:
- has a new `types` attribute that can be used to declare the type or
types to spy when @MockitoSpyBean is declared at the type level
- can be declared as a repeatable annotation at the type level
- can be declared as a meta-annotation on a custom composed annotation
which can be reused across a test suite (see the @SharedSpies
example in the reference manual)
To support these new features, this commit also includes the following
changes.
- MockitoSpyBeanOverrideProcessor has been revised to support
@MockitoSpyBean at the type level.
- The "Bean Overriding in Tests" and "@MockitoBean and
@MockitoSpyBean" sections of the reference manual have been fully
revised.
See gh-34408
Closes gh-33925
Prior to this commit, if an appropriate Converter was registered with
the ConversionService that converts from a POJO to an array and that
ConversionService was registered with the Spring Expression Language
(SpEL) TypeConverter, an attempt to invoke a varargs method in a SpEL
expression with such a POJO would fail because the ConversionService
was not used to convert the POJO to an array suitable for the varargs
method invocation.
This commit revises the implementations of convertArguments(...) and
convertAllMethodHandleArguments(...) in ReflectionHelper to support
such use cases.
Closes gh-34371
Prior to this commit, the order values of TestExecutionListener
implementations were hard-coded in their getOrder() methods.
To benefit users and integrators, this commit exposes those order values
as an ORDER constant in each TestExecutionListener.
See gh-34225
Closes gh-34404
Prior to this commit, if a String 'value' attribute of an annotation
was annotated with @AliasFor and explicitly configured to alias an
attribute other than @Component.value, the value was still used as the
@Component name, but the warning message that was logged stated that
the 'value' attribute should be annotated with
@AliasFor(annotation=Component.class). However, it is not possible to
annotate an annotation attribute twice with @AliasFor.
To address that, this commit revises the logic in
AnnotationBeanNameGenerator so that it issues a log message similar to
the following in such scenarios.
WARN o.s.c.a.AnnotationBeanNameGenerator - Although the 'value'
attribute in @example.MyStereotype declares @AliasFor for an
attribute other than @Component's 'value' attribute, the value is
still used as the @Component name based on convention. As of Spring
Framework 7.0, such a 'value' attribute will no longer be used as the
@Component name.
See gh-34346
Closes gh-34317
If the Servlet container delegates a disconnected client error via
AsyncListener#onError, wrap it as AsyncRequestNotUsableException
for more targeted and consistent handling of such errors.
Closes gh-34363
This commit ensures that `ContentDisposition` parses attributes like
"filename" and "filename*" in a case insensitive fashion, per RFC 6266.
Closes gh-34383
Signed-off-by: Andras Dobrosi <dobrosi@gmail.com>
[brian.clozel@broadcom.com: apply code conventions]
Signed-off-by: Brian Clozel <brian.clozel@broadcom.com>
Changes made to the Bean Override search algorithms in commit
9181cce65f resulted in a regression that caused tests to start failing
due to duplicate BeanOverrideHandlers under the following circumstances.
- An enclosing class (typically a top-level test class) declares a
@BeanOverride such as @MockitoBean.
- An inner class is declared in that enclosing class.
- A @Nested test class which extends that inner class is declared in
the same enclosing class.
The reason for the duplicate detection is that the current search
algorithm visits the common enclosing class twice.
To address that, this commit revises the search algorithm in
BeanOverrideHandler so that enclosing classes are only visited once.
See gh-33925
Closes gh-34324
Prior to this commit, test bean overrides (for example, @MockitoBean,
@TestBean, etc.) eagerly honored the name of the annotated field as a
fallback qualifier, effectively ignoring @Primary and @Fallback
semantics for certain use cases.
This led to situations where a bean override for a test would select a
different bean than the core container would for the same autowiring
metadata.
To address that, this commit revises the implementation of
BeanOverrideBeanFactoryPostProcessor so that @Primary and @Fallback
semantics are consistently honored before attempting to use the
annotated field's name as a fallback qualifier.
Closes gh-34374
Ensure the original instance is always the one returned no matter how
many times the HandlerMethod is re-created.
Make the constructor protected to allow subclasses to re-create the
HandlerMethod as the concrete subclass.
See gh-34375
Prior to this commit, `CronExpression` would support Quartz-style
expressions with "Nth occurence of a dayOfWeek" semantics by using the
`TemporalAdjusters.dayOfWeekInMonth` JDK support. This method will
return the Nth occurence starting with the month of the given temporal,
but in some cases will overflow to the next or previous month.
This behavior is not expected for our cron expression support.
This commit ensures that when an overflow happens (meaning, the
resulting date is not in the same month as the input temporal), we
should instead have another attempt at finding a valid month for this
expression.
Fixes gh-34360
Due to changes in gh-19118, classes that contain @Lookup methods are
no longer required to be concrete classes for use with component
scanning; however, the reference documentation still states that such
classes must not be abstract.
This commit therefore removes the outdated reference documentation and
updates the corresponding Javadoc.
See gh-19118
Closes gh-34367
As of Spring Framework 6.2, the `RestClient.retrieve()` method is a
no-op and developers must invoke a terminal operation on the returned
`ResponseSpec` to have any side effect.
This has been documented in the Javadoc and the wiki release notes, but
this commit highlights this as well in the reference documentation.
Closes gh-34334
The changes in commit c20a2e4763 introduced a regression with regard to
binding to a Map property when the Map also happens to implement
Iterable.
Although that is perhaps not a very common scenario, this commit
reorders the if-blocks in AbstractNestablePropertyAccessor's
getPropertyValue(PropertyTokenHolder) method so that a Map is
considered before an Iterable, thereby allowing an Iterable-Map to be
accessed as a Map.
See gh-907
Closes gh-34332
Prior to this commit, several common HTTP headers were ignored from the
data binding process when collecting property values, in gh-34039 and
gh-34182.
This commit completes the initial enhancement by ensuring that the
default header predicate is also considering cases where constructor
binding is applied and the Java type has a lowercase variant of the HTTP
header name to filter.
Fixes gh-34292
This test was already ignored as of Java 21 because of a Java behavior
change, and now it started failing as of 17.0.14.
This commit removes the test entirely.
This commit adds support for Kotlin properties in Spring WebMVC
controllers, supported for reasons explained in gh-31856, with
kotlinx.serialization converters.
Closes gh-34284
This commit adds support for Kotlin properties in Spring WebFlux
controllers, supported for reasons explained in gh-31856, with
kotlinx.serialization codecs.
See gh-34284
getFlag() returns true when the property is equal, ignoring case, to the
string "true", not just "true"; "TrUe" also means true.
Closes gh-34295
Signed-off-by: Mengqi Xu <2663479778@qq.com>
We now look for the target exception types in cause chain as well,
but return false if we encounter a RestClient or WebClient
exception in the chain.
Closes gh-34264
This commit harmonizes how a candidate value is parsed to extract its
key and default, if any. Rather than returning {@code null} if no
default is available, `splitKeyAndValue` now consistently returns a
non-null array.
This prevents an escaped separator character to be mistakenly identified
as a placeholder in certain cases.
Closes gh-34289
This commit adds a reference documentation section explaining how
applications can use custom `HttpServiceArgumentResolver`
implementations to support complex application types as method
parameters in HTTP interfaces.
Closes gh-34227
For ComandLineArgs, supplying the same option multiple times with
different values is valid, and the values will be stored in a List.
This commit also updates the Javadoc for SimpleCommandLineArgsParser.
See gh-34282
Signed-off-by: puppy4c <puppy4c@foxmail.com>
`@Around("com.xyz.CommonPointcuts.businessService()")` references the `businessService` named pointcut defined in xref:core/aop/ataspectj/pointcuts.adoc#aop-common-pointcuts[Sharing Named Pointcut Definitions].
`@Around("com.xyz.CommonPointcuts.businessService()")` references the `businessService` named pointcut defined in
xref:core/aop/ataspectj/pointcuts.adoc#aop-common-pointcuts[Sharing Named Pointcut Definitions].
Note that the aspect implements the `Ordered` interface so that we can set the precedence of
the aspect higher than the transaction advice (we want a fresh transaction each time we
The following example shows how to specify an argument name in XML:
[source,xml,indent=0,subs="verbatim"]
@@ -464,7 +456,8 @@ The following example shows how to specify an argument name in XML:
method="audit"
arg-names="auditable" />
----
<1> References the `publicMethod` named pointcut defined in xref:core/aop/ataspectj/pointcuts.adoc#aop-pointcuts-combining[Combining Pointcut Expressions].
<1> References the `publicMethod` named pointcut defined in
Spring ships with a small AspectJ aspect library, which is available stand-alone in your
distribution as `spring-aspects.jar`. You need to add this to your classpath in order
to use the aspects in it. xref:core/aop/using-aspectj.adoc#aop-atconfigurable[Using AspectJ to Dependency Inject Domain Objects with Spring] and xref:core/aop/using-aspectj.adoc#aop-ajlib-other[Other Spring aspects for AspectJ] discuss the
content of this library and how you can use it. xref:core/aop/using-aspectj.adoc#aop-aj-configure[Configuring AspectJ Aspects by Using Spring IoC] discusses how to
dependency inject AspectJ aspects that are woven using the AspectJ compiler. Finally,
xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework] provides an introduction to load-time weaving for Spring applications
that use AspectJ.
to use the aspects in it.
xref:core/aop/using-aspectj.adoc#aop-atconfigurable[Using AspectJ to Dependency Inject Domain Objects with Spring]
and xref:core/aop/using-aspectj.adoc#aop-ajlib-other[Other Spring aspects for AspectJ]
discuss the content of this library and how you can use it.
xref:core/aop/using-aspectj.adoc#aop-aj-configure[Configuring AspectJ Aspects by Using Spring IoC]
discusses how to dependency inject AspectJ aspects that are woven using the AspectJ compiler. Finally,
xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]
provides an introduction to load-time weaving for Spring applications that use AspectJ.
[[aop-atconfigurable]]
@@ -206,7 +208,6 @@ not use `@Configurable` on bean classes that are registered as regular Spring be
with the container. Doing so results in double initialization, once through the
container and once through the aspect.
[[aop-configurable-testing]]
=== Unit Testing `@Configurable` Objects
@@ -219,7 +220,6 @@ you can still unit test outside of the container as normal, but you see a warnin
message each time that you construct a `@Configurable` object indicating that it has
not been configured by Spring.
[[aop-configurable-container]]
=== Working with Multiple Application Contexts
@@ -249,7 +249,6 @@ is added only to the container-wide classpath (and hence loaded by the shared pa
not what you want).
[[aop-ajlib-other]]
== Other Spring aspects for AspectJ
@@ -302,7 +301,6 @@ fully qualified class names:
----
[[aop-aj-configure]]
== Configuring AspectJ Aspects by Using Spring IoC
@@ -357,7 +355,6 @@ results in the creation of Spring AOP proxies. The @AspectJ style of aspect
declaration is being used here, but the AspectJ runtime is not involved.
[[aop-aj-ltw]]
== Load-time Weaving with AspectJ in the Spring Framework
@@ -391,7 +388,6 @@ LTW that uses Spring, followed by detailed specifics about elements introduced i
example. For a complete example, see the
{petclinic-github-org}/spring-framework-petclinic[Petclinic sample application based on Spring Framework].
[[aop-aj-ltw-first-example]]
=== A First Example
@@ -677,7 +673,6 @@ nice example of a development-time aspect that developers can use during develop
and then easily exclude from builds of the application being deployed
into UAT or production.
[[aop-aj-ltw-the-aspects]]
=== Aspects
@@ -686,7 +681,6 @@ either the AspectJ language itself, or you can write your aspects in the @Aspect
Your aspects are then both valid AspectJ and Spring AOP aspects.
Furthermore, the compiled aspect classes need to be available on the classpath.
[[aop-aj-ltw-aop_dot_xml]]
=== `META-INF/aop.xml`
@@ -716,7 +710,6 @@ The structure and contents of this file is detailed in the LTW part of the
@@ -5,6 +5,7 @@ This chapter covers Spring's Ahead of Time (AOT) optimizations.
For AOT support specific to integration tests, see xref:testing/testcontext-framework/aot.adoc[Ahead of Time Support for Tests].
[[aot.introduction]]
== Introduction to Ahead of Time Optimizations
@@ -17,9 +18,9 @@ Applying such optimizations early implies the following restrictions:
* The beans defined in your application cannot change at runtime, meaning:
** `@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.
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed aheadoftime.
* Beans registered as singletons (using `registerSingleton`, typically from
`ConfigurableListableBeanFactory`) cannot be transformed ahead-of-time either.
`ConfigurableListableBeanFactory`) cannot be transformed aheadoftime either.
* As we cannot rely on the instance, make sure that the bean type is as precise as
possible.
@@ -35,6 +36,7 @@ A Spring AOT processed application typically generates:
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.
[[aot.basics]]
== AOT Engine Overview
@@ -51,6 +53,7 @@ The `RuntimeHints` instance can also be used to generate the relevant GraalVM na
Those steps are covered in greater detail in the sections below.
[[aot.refresh]]
== Refresh for AOT Processing
@@ -88,6 +91,7 @@ This makes sure to create any proxy that will be required at runtime.
Once this part completes, the `BeanFactory` contains the bean definitions that are necessary for the application to run. It does not trigger bean instantiation but allows the AOT engine to inspect the beans that will be created at runtime.
[[aot.bean-factory-initialization-contributions]]
== Bean Factory Initialization AOT Contributions
@@ -106,11 +110,10 @@ Consequently, such a bean is automatically excluded from the AOT-optimized conte
[NOTE]
====
If a bean implements the `BeanFactoryInitializationAotProcessor` interface, the bean and **all** of its dependencies will be initialized during AOT processing.
We generally recommend that this interface is only implemented by infrastructure beans such as `BeanFactoryPostProcessor` which have limited dependencies and are already initialized early in the bean factory lifecycle.
We generally recommend that this interface is only implemented by infrastructure beans, such as a `BeanFactoryPostProcessor`, which have limited dependencies and are already initialized early in the bean factory lifecycle.
If such a bean is registered using an `@Bean` factory method, ensure the method is `static` so that its enclosing `@Configuration` class does not have to be initialized.
====
[[aot.bean-registration-contributions]]
=== Bean Registration AOT Contributions
@@ -127,7 +130,7 @@ Typically used when the bean definition needs to be tuned for specific features
[NOTE]
====
If a bean implements the `BeanRegistrationAotProcessor` interface, the bean and **all** of its dependencies will be initialized during AOT processing.
We generally recommend that this interface is only implemented by infrastructure beans such as `BeanFactoryPostProcessor` which have limited dependencies and are already initialized early in the bean factory lifecycle.
We generally recommend that this interface is only implemented by infrastructure beans, such as a `BeanFactoryPostProcessor`, which have limited dependencies and are already initialized early in the bean factory lifecycle.
If such a bean is registered using an `@Bean` factory method, ensure the method is `static` so that its enclosing `@Configuration` class does not have to be initialized.
====
@@ -219,21 +222,23 @@ NOTE: The exact code generated may differ depending on the exact nature of your
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.
The generated code above creates bean definitions equivalent to the `@Configuration` class, but in a direct way and without the use of reflection at all if 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
is automatically enabled when running within a native image. However it is also possible to use AOT 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.
NOTE: When AOT optimizations are included, some decisions that have been made at buildtime
are hardcoded in the application setup. For instance, profiles that have been enabled at
buildtime are automatically enabled at runtime as well.
[[aot.bestpractices]]
== Best Practices
@@ -271,7 +276,7 @@ build time.
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.
For `@Configuration` classes, make sure that the return type of the factory `@Bean` method is as precise as possible.
For `@Configuration` classes, make sure that the return type of an `@Bean` factory method is as precise as possible.
Consider the following example:
[tabs]
@@ -305,11 +310,11 @@ Kotlin::
----
======
In the example above, the declared type for the `myInterface` bean is `MyInterface`.
None of the usual post-processing will take `MyImplementation` into account.
For instance, if there is an annotated handler method on `MyImplementation` that the context should register, it won’t be detected upfront.
In the example above, the declared type for the `myInterface` bean is `MyInterface`.
During AOT processing, none of the usual post-processing will take `MyImplementation` into account.
For instance, if there is an annotated handler method on `MyImplementation` that the context should register, it will not be detected during AOT processing.
The example above should be rewritten as follows:
The example above should therefore be rewritten as follows:
[tabs]
======
@@ -348,7 +353,7 @@ If you are registering bean definitions programmatically, consider using `RootBe
=== 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.
However, relying on that 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 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.
@@ -363,13 +368,13 @@ A good rule of thumb is to keep in mind that bean definitions are an abstraction
Rather than using such structures, 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 fullyqualified name in `META-INF/spring/aot.factories` using the `Delegate` as the key.
To use it, register its fully-qualified name in `META-INF/spring/aot.factories` using `org.springframework.aot.generate.ValueCodeGenerator$Delegate` as the key.
[[aot.bestpractices.custom-arguments]]
=== Avoid Creating Beans 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:
Spring AOT detects what needs to be done to create a bean and translates that into generated code that uses 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] which can lead 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.
@@ -396,7 +401,7 @@ for further information.
=== FactoryBean
`FactoryBean` should be used with care as it introduces an intermediate layer in terms of bean type resolution that may not be conceptually necessary.
As a rule of thumb, if the `FactoryBean` instance does not hold long-term state and is not needed at a later point in time at runtime, it should be replaced by a regular factory method, possibly with a `FactoryBean` adapter layer on top (for declarative configuration purposes).
As a rule of thumb, if a `FactoryBean` instance does not hold long-term state and is not needed at a later point at runtime, it should be replaced by a regular `@Bean` factory method, possibly with a `FactoryBean` adapter layer on top (for declarative configuration purposes).
If your `FactoryBean` implementation does not resolve the object type (i.e. `T`), extra care is necessary.
Consider the following example:
@@ -455,7 +460,7 @@ Kotlin::
----
======
If the `FactoryBean` bean definition is registered programmatically, make sure to follow these steps:
If a `FactoryBean` bean definition is registered programmatically, make sure to follow these steps:
1. Use `RootBeanDefinition`.
2. Set the `beanClass` to the `FactoryBean` class so that AOT knows that it is an intermediate layer.
@@ -469,20 +474,20 @@ Java::
+
[source,java,indent=0,subs="verbatim,quotes"]
----
RootBeanDefinition beanDefinition = new RootBeanDefinition(ClientFactoryBean.class);
on any Spring bean or `@Bean` factory method. `RuntimeHintsRegistrar` implementations are
detected and invoked at build time.
include-code::./SpellCheckService[]
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.
This way, if the component is not contributed to the `BeanFactory`, the hints will not 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 fully-qualified name of the `RuntimeHintsRegistrar` interface.
[[aot.hints.reflective]]
=== `@Reflective`
{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.
Out-of-the-box, only Spring beans are considered but you can opt-in for scanning using `@ReflectiveScan`.
In the example below, all types of the package `com.example.app` and their subpackages are considered:
Out-of-the-box, only Spring beans are considered, but you can opt-in for scanning using
{spring-framework-api}/context/annotation/ReflectiveScan.html[`@ReflectiveScan`]. In the
example below, all types in the `com.example.app` package and its subpackages are
considered:
include-code::./MyConfiguration[]
Scanning happens during AOT processing and the types in the target packages do not need to have a class-level annotation to be considered.
This performs a "deep scan" and the presence of `@Reflective`, either directly or as a meta-annotation, is checked on types, fields, constructors, methods, and enclosed elements.
Scanning happens during AOT processing, and the types in the target packages do not need to have a class-level annotation to be considered.
This performs a _deep scan_, and the presence of `@Reflective`, either directly or as a meta-annotation, is checked on types, fields, constructors, methods, and enclosed elements.
By default, `@Reflective` registers an invocation hint for the annotated element.
This can be tuned by specifying a custom `ReflectiveProcessor` implementation via the `@Reflective` annotation.
@@ -634,13 +643,12 @@ This can be tuned by specifying a custom `ReflectiveProcessor` implementation vi
Library authors can reuse this annotation for their own purposes.
An example of such customization is covered in the next section.
[[aot.hints.register-reflection]]
=== `@RegisterReflection`
{spring-framework-api}/aot/hint/annotation/RegisterReflection.html[`@RegisterReflection`] is a specialization of `@Reflective` that provides a declarative way of registering reflection for arbitrary types.
{spring-framework-api}/aot/hint/annotation/RegisterReflection.html[`@RegisterReflection`] is a specialization of `@Reflective` that provides a declarative way to register reflection for arbitrary types.
NOTE: As a specialization of `@Reflective`, this is also detected if you're using `@ReflectiveScan`.
NOTE: As a specialization of `@Reflective`, `@RegisterReflection` is also detected if you are using `@ReflectiveScan`.
In the following example, public constructors and public methods can be invoked via reflection on `AccountService`:
`@RegisterReflection` can be applied to any target type at the class level, but it can also be applied directly to a method to better indicate where the hints are actually required.
`@RegisterReflection` can be used as a meta-annotation to provide more specific needs.
{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is such composed annotation and registers the need for serializing arbitrary types.
`@RegisterReflection` can be used as a meta-annotation to support more specific needs.
{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a composed annotation that is meta-annotated with `@RegisterReflection` and 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.
The following example registers `Order` for serialization.
@@ -660,11 +668,66 @@ This registers hints for constructors, fields, properties, and record components
Hints are also registered for types transitively used on properties and record components.
In other words, if `Order` exposes others types, hints are registered for those as well.
[[aot.hints.convention-based-conversion]]
=== Runtime Hints for Convention-based Conversion
Although the core container provides built-in support for automatic conversion of many
common types (see xref:core/validation/convert.adoc[Spring Type Conversion]), some
conversions are supported via a convention-based algorithm that relies on reflection.
Specifically, if there is no explicit `Converter` registered with the `ConversionService`
for a particular source → target type pair, the internal `ObjectToObjectConverter`
will attempt to use conventions to convert a source object to a target type by delegating
to a method on the source object or to a static factory method or constructor on the
target type. Since this convention-based algorithm can be applied to arbitrary types at
runtime, the core container is not able to infer the runtime hints necessary to support
such reflection.
If you encounter convention-based conversion issues within a native image resulting from
lacking runtime hints, you can register the necessary hints programmatically. For
example, if your application requires a conversion from `java.time.Instant` to
`java.sql.Timestamp` and relies on `ObjectToObjectConverter` to invoke
`java.sql.Timestamp.from(Instant)` using reflection, you could implement a custom
`RuntimeHintsRegitrar` to support this use case within a native image, as demonstrated in
the following example.
[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes"]
----
public class TimestampConversionRuntimeHints implements RuntimeHintsRegistrar {
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
If no `list-class` attribute is supplied, the container chooses a `List` implementation.
[[xsd-schemas-util-map]]
=== Using `<util:map/>`
@@ -444,7 +438,6 @@ following configuration:
If no `'map-class'` attribute is supplied, the container chooses a `Map` implementation.
[[xsd-schemas-util-set]]
=== Using `<util:set/>`
@@ -500,7 +493,6 @@ following configuration:
If no `set-class` attribute is supplied, the container chooses a `Set` implementation.
[[xsd-schemas-aop]]
== The `aop` Schema
@@ -530,7 +522,6 @@ are available to you):
----
[[xsd-schemas-context]]
== The `context` Schema
@@ -555,7 +546,6 @@ available to you:
</beans>
----
[[xsd-schemas-context-pphc]]
=== Using `<property-placeholder/>`
@@ -599,34 +589,25 @@ element for that purpose. Similarly, Spring's
xref:integration/cache/annotations.adoc[caching annotations] need to be explicitly
xref:integration/cache/annotations.adoc#cache-annotation-enable[enabled] as well.
[[xsd-schemas-context-component-scan]]
=== Using `<component-scan/>`
This element is detailed in the section on xref:core/beans/annotation-config.adoc[annotation-based container configuration]
.
This element is detailed in the section on xref:core/beans/annotation-config.adoc[annotation-based container configuration].
[[xsd-schemas-context-ltw]]
=== Using `<load-time-weaver/>`
This element is detailed in the section on xref:core/aop/using-aspectj.adoc#aop-aj-ltw[load-time weaving with AspectJ in the Spring Framework]
.
This element is detailed in the section on xref:core/aop/using-aspectj.adoc#aop-aj-ltw[load-time weaving with AspectJ in the Spring Framework].
[[xsd-schemas-context-sc]]
=== Using `<spring-configured/>`
This element is detailed in the section on xref:core/aop/using-aspectj.adoc#aop-atconfigurable[using AspectJ to dependency inject domain objects with Spring]
.
This element is detailed in the section on xref:core/aop/using-aspectj.adoc#aop-atconfigurable[using AspectJ to dependency inject domain objects with Spring].
[[xsd-schemas-context-mbe]]
=== Using `<mbean-export/>`
This element is detailed in the section on xref:integration/jmx/naming.adoc#jmx-context-mbeanexport[configuring annotation-based MBean export]
.
This element is detailed in the section on xref:integration/jmx/naming.adoc#jmx-context-mbeanexport[configuring annotation-based MBean export].
[[xsd-schemas-beans]]
@@ -666,7 +647,3 @@ as it stands).
In the case of the preceding example, you could assume that there is some logic that consumes
the bean definition and sets up some caching infrastructure that uses the supplied metadata.
demonstrates how to provide a lot of the configuration metadata through source-level
annotations. Even in those examples, however, the "base" bean definitions are explicitly
defined in the XML file, while the annotations drive only the dependency injection.
This section describes an option for implicitly detecting the candidate components by
scanning the classpath. Candidate components are classes that match against a filter
criteria and have a corresponding bean definition registered with the container.
This removes the need to use XML to perform bean registration. Instead, you can use
annotations (for example, `@Component`), AspectJ type expressions, or your own
custom filter criteria to select which classes have bean definitions registered with
the container.
[NOTE]
====
You can define beans using Java rather than using XML files. Take a look at the
`@Configuration`, `@Bean`, `@Import`, and `@DependsOn` annotations for examples of how to
use these features.
`@Configuration`, `@Bean`, `@Import`, and `@DependsOn` annotations for examples
of how to use these features.
====
[[beans-stereotype-annotations]]
== `@Component` and Further Stereotype Annotations
@@ -46,7 +47,6 @@ clearly the better choice. Similarly, as stated earlier, `@Repository` is alread
supported as a marker for automatic exception translation in your persistence layer.
[[beans-meta-annotations]]
== Using Meta-annotations and Composed Annotations
@@ -195,7 +195,6 @@ For further details, see the
wiki page.
[[beans-scanning-autodetection]]
== Automatically Detecting Classes and Registering Bean Definitions
@@ -334,7 +333,6 @@ NOTE: You can disable the registration of `AutowiredAnnotationBeanPostProcessor`
with a value of `false`.
[[beans-scanning-filters]]
== Using Filters to Customize Scanning
@@ -426,7 +424,6 @@ annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Cont
`@RestController`, or `@Configuration`.
[[beans-factorybeans-annotations]]
== Defining Bean Metadata within Components
@@ -663,7 +660,6 @@ analogous to how the container selects between multiple `@Autowired` constructor
====
[[beans-scanning-name-generator]]
== Naming Autodetected Components
@@ -797,7 +793,6 @@ components may be making explicit references to it. On the other hand, the
auto-generated names are adequate whenever the container is responsible for wiring.
[[beans-scanning-scope-resolver]]
== Providing a Scope for Autodetected Components
@@ -837,10 +832,10 @@ definitions, there is no notion of bean definition inheritance, and inheritance
hierarchies at the class level are irrelevant for metadata purposes.
For details on web-specific scopes such as "`request`" or "`session`" in a Spring context,
see xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other[Request, Session, Application, and WebSocket Scopes]. As with the pre-built annotations for those scopes,
you may also compose your own scoping annotations by using Spring's meta-annotation
approach: for example, a custom annotation meta-annotated with `@Scope("prototype")`,
possibly also declaring a custom scoped-proxy mode.
see xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other[Request, Session, Application, and WebSocket Scopes].
As with the pre-built annotations for those scopes, you may also compose your own scoping
annotations by using Spring's meta-annotation approach: for example, a custom annotation
meta-annotated with `@Scope("prototype")`, possibly also declaring a custom scoped-proxy mode.
NOTE: To provide a custom strategy for scope resolution rather than relying on the
annotation-based approach, you can implement the
@@ -882,7 +877,8 @@ Kotlin::
----
When using certain non-singleton scopes, it may be necessary to generate proxies for the
scoped objects. The reasoning is described in xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[Scoped Beans as Dependencies].
scoped objects. The reasoning is described in
xref:core/beans/factory-scopes.adoc#beans-factory-scopes-other-injection[Scoped Beans as Dependencies].
For this purpose, a scoped-proxy attribute is available on the component-scan
element. The three possible values are: `no`, `interfaces`, and `targetClass`. For example,
the following configuration results in standard JDK dynamic proxies:
@@ -920,7 +916,6 @@ Kotlin::
----
[[beans-scanning-qualifiers]]
== Providing Qualifier Metadata with Annotations
@@ -1012,7 +1007,3 @@ NOTE: As with most annotation-based alternatives, keep in mind that the annotati
bound to the class definition itself, while the use of XML allows for multiple beans
of the same type to provide variations in their qualifier metadata, because that
metadata is provided per-instance rather than per-class.
architectures that build upon the well-known Spring programming model.
[[context-functionality-events-annotation]]
=== Annotation-based Event Listeners
@@ -707,7 +704,6 @@ The `handleBlockedListEvent()` method publishes a new `ListUpdateEvent` for ever
`BlockedListEvent` that it handles. If you need to publish several events, you can return
a `Collection` or an array of events instead.
[[context-functionality-events-async]]
=== Asynchronous Listeners
@@ -754,7 +750,6 @@ Be aware of the following limitations when using asynchronous events:
See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]
for more information on Observability concerns.
[[context-functionality-events-order]]
=== Ordering Listeners
@@ -786,7 +781,6 @@ Kotlin::
----
======
[[context-functionality-events-generics]]
=== Generic Events
@@ -880,7 +874,6 @@ for example, for processing all events asynchronously and/or for handling listen
----
[[context-functionality-resources]]
== Convenient Access to Low-level Resources
@@ -913,7 +906,6 @@ with special prefixes to force loading of definitions from the classpath or a UR
regardless of the actual context type.
[[context-functionality-startup]]
== Application Startup Tracking
@@ -990,6 +982,7 @@ or ask for the `ApplicationStartup` type on any injection point.
NOTE: Developers should not use the `"spring.*"` namespace when creating custom startup steps.
This namespace is reserved for internal Spring usage and is subject to change.
[[context-create]]
== Convenient ApplicationContext Instantiation for Web Applications
@@ -1022,7 +1015,6 @@ Examples are `/WEB-INF/{asterisk}Context.xml` (for all files with names that end
(for all such files in any subdirectory of `WEB-INF`).
[[context-deploy-rar]]
== Deploying a Spring `ApplicationContext` as a Jakarta EE RAR File
@@ -1053,7 +1045,8 @@ 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 {spring-framework-api}/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
`META-INF/applicationContext.xml`).
. Drop the resulting RAR file into your
@@ -1066,7 +1059,3 @@ other modules. A RAR-based `ApplicationContext` may also, for example, schedule
or react to new files in the file system (or the like). If it needs to allow synchronous
access from the outside, it could (for example) export RMI endpoints, which may be used
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].
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].
@@ -57,9 +57,9 @@ The following table describes these properties:
In addition to bean definitions that contain information on how to create a specific
bean, the `ApplicationContext` implementations also permit the registration of existing
objects that are created outside the container (by users). This is done by accessing the
ApplicationContext's `BeanFactory` through the `getBeanFactory()` method, which returns
the `DefaultListableBeanFactory` implementation. `DefaultListableBeanFactory` supports
this registration through the `registerSingleton(..)` and `registerBeanDefinition(..)`
ApplicationContext's `BeanFactory` through the `getAutowireCapableBeanFactory()` method,
which returns the `DefaultListableBeanFactory` implementation. `DefaultListableBeanFactory`
supports this registration through the `registerSingleton(..)` and `registerBeanDefinition(..)`
methods. However, typical applications work solely with beans defined through regular
bean definition metadata.
@@ -74,7 +74,6 @@ lead to concurrent access exceptions, inconsistent state in the bean container,
====
[[beans-definition-overriding]]
== Overriding Beans
@@ -104,7 +103,6 @@ explicit support for this as of Spring Framework 6.2. Please refer to
xref:testing/testcontext-framework/bean-overriding.adoc[this section] for more details.
[[beans-beanname]]
== Naming Beans
@@ -147,7 +145,6 @@ case when there is more than one character and both the first and second charact
are upper case, the original casing gets preserved. These are the same rules as
defined by `java.beans.Introspector.decapitalize` (which Spring uses here).
[[beans-beanname-alias]]
=== Aliasing a Bean outside the Bean Definition
@@ -197,7 +194,6 @@ See xref:core/beans/java/bean-annotation.adoc[Using the `@Bean` Annotation] for
****
[[beans-factory-class]]
== Instantiating Beans
@@ -209,7 +205,8 @@ If you use XML-based configuration metadata, you specify the type (or class) of
that is to be instantiated in the `class` attribute of the `<bean/>` element. This
`class` attribute (which, internally, is a `Class` property on a `BeanDefinition`
instance) is usually mandatory. (For exceptions, see
xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[Instantiation by Using an Instance Factory Method] and xref:core/beans/child-bean-definitions.adoc[Bean Definition Inheritance].)
xref:core/beans/definition.adoc#beans-factory-class-instance-factory-method[Instantiation by Using an Instance Factory Method]
and xref:core/beans/child-bean-definitions.adoc[Bean Definition Inheritance].)
You can use the `Class` property in one of two ways:
* Typically, to specify the bean class to be constructed in the case where the container
@@ -233,7 +230,6 @@ a bean definition would be `com.example.SomeThing$OtherThing` or
`com.example.SomeThing.OtherThing`.
****
[[beans-factory-class-ctor]]
=== Instantiation with a Constructor
@@ -268,7 +264,6 @@ NOTE: In the case of constructor arguments, the container can select a correspon
constructor among several overloaded constructors. That said, to avoid ambiguities,
it is recommended to keep your constructor signatures as straightforward as possible.
[[beans-factory-class-static-factory-method]]
=== Instantiation with a Static Factory Method
@@ -346,7 +341,6 @@ overloads of the `mock` method. Choose the most specific variant of `mock` possi
----
====
[[beans-factory-class-instance-factory-method]]
=== Instantiation by Using an Instance Factory Method
@@ -16,8 +16,9 @@ not know the location or class of the dependencies. As a result, your classes be
to test, particularly when the dependencies are on interfaces or abstract base classes,
which allow for stub or mock implementations to be used in unit tests.
DI exists in two major variants: xref:core/beans/dependencies/factory-collaborators.adoc#beans-constructor-injection[Constructor-based dependency injection]
and xref:core/beans/dependencies/factory-collaborators.adoc#beans-setter-injection[Setter-based dependency injection].
The first form is preferable to the second, because using the `idref` tag lets the
container validate at deployment time that the referenced, named bean actually
exists. In the second variation, no validation is performed on the value that is passed
to the `targetName` property of the `client` bean. Typos are only discovered (with most
container validate at deployment time that the referenced, named bean actually exists. In
the second variation, no validation is performed on the value that is passed to the
`targetName` property of the `client` bean. Typos are therefore only discovered (with most
likely fatal results) when the `client` bean is actually instantiated. If the `client`
bean is a xref:core/beans/factory-scopes.adoc[prototype] bean, this typo and the resulting exception
may only be discovered long after the container is deployed.
bean is a xref:core/beans/factory-scopes.adoc[prototype] bean, this typo and the resulting
exception may only be discovered long after the container is deployed.
NOTE: The `local` attribute on the `idref` element is no longer supported in the 4.0 beans
XSD, since it does not provide value over a regular `bean` reference any more. Change
your existing `idref local` references to `idref bean` when upgrading to the 4.0 schema.
A common place (at least in versions earlier than Spring 2.0) where the `<idref/>` element
brings value is in the configuration of xref:core/aop-api/pfb.adoc#aop-pfb-1[AOP interceptors] in a
`ProxyFactoryBean` bean definition. Using `<idref/>` elements when you specify the
NOTE: A common place (at least in versions earlier than Spring 2.0) where the `<idref/>`
element brings value is in the configuration of xref:core/aop-api/pfb.adoc#aop-pfb-1[AOP interceptors]
in a `ProxyFactoryBean` bean definition. Using `<idref/>` elements when you specify the
interceptor names prevents you from misspelling an interceptor ID.
@@ -544,9 +539,10 @@ three approaches at the same time.
[[beans-c-namespace]]
== XML Shortcut with the c-namespace
Similar to the xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[XML Shortcut with the p-namespace], the c-namespace, introduced in Spring
3.1, allows inlined attributes for configuring the constructor arguments rather
then nested `constructor-arg` elements.
Similar to the
xref:core/beans/dependencies/factory-properties-detailed.adoc#beans-p-namespace[XML Shortcut with the p-namespace],
the c-namespace, introduced in Spring 3.1, allows inlined attributes for configuring
the constructor arguments rather then nested `constructor-arg` elements.
The following example uses the `c:` namespace to do the same thing as the from
See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]
javadoc for details on the various constructors.
[[resources-app-ctx-wildcards-in-resource-paths]]
=== Wildcards in Application Context Constructor Resource Paths
@@ -788,7 +752,6 @@ resolved at construction time. It has nothing to do with the `Resource` type its
You cannot use the `classpath*:` prefix to construct an actual `Resource`, as
a resource points to just one resource at a time.
[[resources-app-ctx-ant-patterns-in-paths]]
==== Ant-style Patterns
@@ -832,7 +795,6 @@ walk the contents of the jar and resolve the wildcard. This does work in most en
but fails in others, and we strongly recommend that the wildcard resolution of resources
coming from jars be thoroughly tested in your specific environment before you rely on it.
[[resources-classpath-wildcards]]
==== The `classpath*:` Prefix
@@ -880,7 +842,6 @@ used on the last non-wildcard path segment to get all the matching resources in
class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
strategy described earlier is used for the wildcard subpath.
[[resources-wildcards-in-path-other-stuff]]
==== Other Notes Relating to Wildcards
@@ -934,8 +895,6 @@ location found. Therefore, in such cases you should prefer using `classpath*:` w
same Ant-style pattern, which searches all classpath locations that contain the
`com.mycompany` base package: `classpath*:com/mycompany/**/service-context.xml`.
[[resources-filesystemresource-caveats]]
=== `FileSystemResource` Caveats
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.