Prior to this commit, `MediaType.parseMediaType` would already rely on
the internal LRU cache in `MimeTypeUtils` for better performance. With
that optimization, the parsing of raw media types is skipped for cached
elements.
But still, `MediaType.parseMediaType` would first get a cached
`MimeType` instance from that cache and then instantiate a
`new MediaType(type, subtype, parameters)`. This constructor not only
replays the `MimeType` checks on type/subtyme tokens and parameters, but
it also performs `MediaType`-specific checks on parameters.
Such checks are not required, as we're using an existing `MimeType`
instance in the first place.
This commit adds a new protected copy constructor (skipping checks) in
`MimeType` and uses it in `MediaType.parseMediaType` as a result.
This yields interesting performance improvements, with +400% throughput
and -40% allocation/call in benchmarks. This commit also introduces a
new JMH benchmark for future optimization work.
Closes gh-24769
Prior to this commit, the Spring Framework test suite would rely only on
"Performance" tests associated with a specific CI build. As outlined in
gh-24830, the way they're built and executed is not working well
anymore.
This commit introduces a new JMH benchmark infrastructure in the build.
The goal here is not to run those benchmarks as part of a CI build, but
rather provide a proper infrastructure for writing and locally running
micro-benchmarks when working on specific optimizations.
This commit adds and configures a Gradle JMH plugin to allow for JMH
benchmark classes in Spring Framework modules (in `src/jmh/java` of each
`spring-*` module). It's also relaxing the checkstyle rules for JMH
classes, especially around Javadoc rules: this code is not meant to
have Javadocs.
Finally, this commit links to a new Wiki page on the project GitHub
repository documenting the infrastructure and helping contributors to
run and design benchmarks.
See gh-24830
This commit avoids invoking StringBuilder.append(Object) in favor
of explicit method calls to append(String) and append(char) in
ContentDisposition.escapeQuotationsInFilename(String).
Closes gh-25056
This commit optimizes code in ResourceBundleMessageSource
by using computeIfAbsent instead of putIfAbsent.
In addition, the content of some Javadoc has been adjusted.
Closes gh-25054
Prior to this commit, if a BeanNameAutoProxyCreator was configured with
a custom TargetSourceCreator, the TargetSourceCreator was applied to
all beans in the ApplicationContext. Thus, the list of supported
beanNames was effectively ignored when applying any
TargetSourceCreator. Consequently, if a TargetSourceCreator returned a
non-null TargetSource for a given bean, the BeanNameAutoProxyCreator
proxied the bean even if the bean name had not been configured in the
beanNames list.
This commit addresses this issue by ensuring that a custom
TargetSourceCreator is only applied to beans whose names match the
configured beanNames list in a BeanNameAutoProxyCreator.
Closes gh-24915
Prior to this commit, the `VersionResourceResolver` implementations
would write a strong ETag HTTP response header with the resolved version
of the resource (the actual value depending on the chosen strategy).
This approach doesn't work well when combined with HTTP compression.
Web servers disable HTTP response copression in the presence of strong
ETags since mutating the response body would break the contract.
This commit changes this semantic and ensures that weak ETags are used
instead.
Closes gh-24898
Prior to this commit, patterns like `"/path/**/other"` would be treated
as `"/path/*/other"` (single wildcard, i.e. matching zero to many chars
within a path segment). This will not match multiple segments, as
expected by `AntPathMatcher` users or by `PathPatternParser` users when
in patterns like `"/resource/**"`.
This commit now rejects patterns like `"/path/**/other"` as invalid.
This behavior was previously warned against since gh-24958.
Closes gh-24952
This commit picks up where 613bd3be1d
left off by ensuring that a transaction manager configured via the
TransactionManagementConfigurer API takes precedence over any
transaction manager configured as a bean in the ApplicationContext
unless @Transactional is configured with a qualifier for the explicit
transaction manager to use in tests.
Closes gh-24869
When mutating a ServerHttpRequest or ClientResponse, the respective
builders no longer access cookies automatically which causes them to
be parsed and does so only if necessary. Likewise re-applying the
read-only HttpHeaders wrapper is avoided.
See gh-24680
Given that the body is a Flux<DataBuffer> there probably could be a
Flux<DataBuffer> body();
At least bodyToFlux(DataBuffer.class) which is used when mutating and
is a common case should not incur overhead.
See gh-24680
from() has the flaw of ignoring the body and it can't be fixed because
applications are guaranteed to be setting it already and if set twice
the builder drains the first body.
mutate() is a better fit in any case for what needs to be done in a
filter chain. It can be done more efficiently and is consistent with
similar options on the server side.
See gh-24680
Native server request headers have been wrapped rather than copied
since 5.1. This commit applies the same change to the client side
where, to make matters worse, headers were copied repeatedly on every
access, see also previous commit ca897b95.
For Netty and Jetty the wrappers are the same as on the server side
but duplicated in order to remain package private.
See gh-24680