This commit apply several refinements to PropagationContextElement:
- Capture the ThreadLocal when instantiating the
PropagationContextElement in order to support dispatchers switching
threads
- Remove the constructor parameter which is not idiomatic and breaks
the support when switching threads, and use instead the
updateThreadContext(context: CoroutineContext) parameter
- Make the kotlinx-coroutines-reactor dependency optional
- Make the properties private
The Javadoc and tests are also updated to use the
`Dispatchers.IO + PropagationContextElement()` pattern performed
outside of the suspending lambda, which is the typical use case.
Closes gh-35469
Prior to this commit, the Micrometer context-propagation project would
help propagating information from `ThreadLocal`, Reactor `Context` and
other context objects. This is already well supported for Micrometer
Observations.
In the case of Kotlin suspending functions, the processing of tasks
would not necessarily update the `ThreadLocal` when the function is
scheduled on a different thread.
This commit introduces the `PropagationContextElement` operator that
connects the `ThreadLocal`, Reactor `Context` and Coroutine `Context`
for all libraries using the "context-propagation" project.
Applications must manually use this operator in suspending functions
like so:
```
suspend fun suspendingFunction() {
return withContext(PropagationContextElement(currentCoroutineContext())) {
logger.info("Suspending function with traceId")
}
}
```
Closes gh-35185
Prior to this commit, the `JmsTemplate` would use `MessagePostProcessor`
for mutating JMS messages before they are being sent, but only if the
method takes a post processor as an argument.
The main use case so far is to mutate messages after they've been
created by a `MessageConverter` from a payload.
This commit updates the `JmsClient` to use `MessagePostProcessor` more
broadly, for all outgoing messages (converted or not). This brings an
interception-like mechanism for clients to enrich the message before
being sent.
This change also updates the `JmsClient` static factories and
introduces a Builder, allowing for more configuration options: multiple
message converters and message post processors.
Closes gh-35271
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to runDetails
Build and Deploy Snapshot / Verify (push) Blocked by required conditionsDetails
Deploy Docs / Dispatch docs deployment (push) Waiting to runDetails
As of #33894, we introduced a new `HttpMessageConverters` API.
While this achieved our goal of focusing converters classpath detection
in a single place and avoiding waste, a single `HttpMessageConverters`
instance for both client and server added more complexity for developers.
This commit aligns the API here with the WebFlux `CodecsConfigurer` to
opt for a client/server flavor as the first step in the builder.
While this make the sharing of converter instances between server and
client impossible, this allows for a simpler API and separates concerns.
Closes gh-35187
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
This commit updates the whole Spring Framework codebase to use JSpecify
annotations instead of Spring null-safety annotations with JSR 305
semantics.
JSpecify provides signficant enhancements such as properly defined
specifications, a canonical dependency with no split-package issue,
better tooling, better Kotlin integration and the capability to specify
generic type, array and varargs element null-safety. Generic type
null-safety is not defined by this commit yet and will be specified
later.
A key difference is that Spring null-safety annotations, following
JSR 305 semantics, apply to fields, parameters and return values,
while JSpecify annotations apply to type usages. That's why this
commit moves nullability annotations closer to the type for fields
and return values.
See gh-28797
As a preparation to using a Kotlin 2 baseline, this commit stops using
Java code snippets in Kotlin ones in order to avoid redeclaration
errors.
See gh-33629
This commit adapts AOT support in various modules after the RuntimeHints
and related deprecation changes.
`MemberCategory.INTROSPECT_*` hints are now removed and
`MemberCategory.*_FIELDS` are replaced with
`MemberCategory.INVOKE*_FIELDS` when invocation is needed.
Usage of `RuntimeHintsAgent` are also deprecated.
Closes gh-33847
This commit allows `@Reflective` to be used on arbitrary types, not
only Spring beans. This makes the feature much more powerful as
components can be tagged directly.
Scanning happens during AOT processing (typically at build-time) when
`@ReflectiveScan` is used. Types do not need to have a particular
annotation, and types that can't be loaded are ignored.
This commit also exposes the infrastructure that does the scanning so
that custom code can do the scanning in an AOT contribution if they
don't want to rely on the annotation.
Closes gh-33132
This commit restructures the section on MockMvc so that the anchors
are easier to read. The standard integration has moved to a
Hamcrest Integration section at the same level as HtmlUnit Integration,
and a new AssertJ Integration section has been created.
Closes gh-32454
This commit adds support for Kotlin BeanPostProcessor beans which should
be defined in a companion object and annotated with `@JvmStatic`.
Closes gh-32946
Prior to this commit, `@ExceptionHandler` annotated controller methods
could be mapped using the exception type declaration as an annotation
attribute, or as a method parameter.
While such methods support a wide variety of method arguments and return
types, it was not possible to declare the same exception type on
different methods (in the same controller/controller advice).
This commit adds a new `produces` attribute on `@ExceptionHandler`; with
that, applications can vary the HTTP response depending on the exception
type and the requested content-type by the client:
```
@ExceptionHandler(produces = "application/json")
public ResponseEntity<ErrorMessage> handleJson(IllegalArgumentException exc) {
return ResponseEntity.badRequest().body(new ErrorMessage(exc.getMessage(), 42));
}
@ExceptionHandler(produces = "text/html")
public String handle(IllegalArgumentException exc, Model model) {
model.addAttribute("error", new ErrorMessage(exc.getMessage(), 42));
return "errorView";
}
```
This commit implements support in both Spring MVC and Spring WebFlux.
Closes gh-31936