Usually this request attribute is set for all sub-classes of
AbstractUrlHandlerMapping and therefore whenever
AnnotationMethodHandlerAdapter is used. However, having a
default value to fall back on in AnnotationMethodHandlerAdapter
is still appropriate in general and also considering the Javadoc
of HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING.
Issue: SPR-9629
Backport-Issue: SPR-9633
Before this change the StringHttpMessageConverter used a fixed charset "ISO-8859-1" if the requested content type did not specify one. This change adds a defaultCharset field and a constructor to configure it in StringHttpMessageConverter.
Issue: SPR-9487
Prior to this change, PropertySourcesPropertyResolver (and therefore
all AbstractEnvironment) implementations failed to resolve nested
placeholders as in the following example:
p1=v1
p2=v2
p3=${v1}:{$v2}
Calls to PropertySource#getProperty for keys 'p1' and 'v1' would
successfully return their respective values, but for 'p3' the return
value would be the unresolved placeholders. This behavior is
inconsistent with that of PropertyPlaceholderConfigurer.
PropertySourcesPropertyResolver #getProperty variants now resolve any
nested placeholders recursively, throwing IllegalArgumentException for
any unresolvable placeholders (as is the default behavior for
PropertyPlaceholderConfigurer). See SPR-9569 for an enhancement that
will intoduce an 'ignoreUnresolvablePlaceholders' switch to make this
behavior configurable.
This commit also improves error output in
PropertyPlaceholderHelper#parseStringValue by including the original
string in which an unresolvable placeholder was found.
Issue: SPR-9473, SPR-9569
Prior to this change, by-type lookups using DLBF#getBeanNamesForType
required traversal of all bean definitions within the bean factory
in order to inspect their bean class for assignability to the target
type. These operations are comparatively expensive and when there are a
large number of beans registered within the container coupled with a
large number of by-type lookups at runtime, the performance impact can
be severe. The test introduced here demonstrates such a scenario clearly.
This performance problem is likely to manifest in large Spring-based
applications using non-singleton beans, particularly request-scoped
beans that may be created and wired many thousands of times per second.
This commit introduces a simple ConcurrentHashMap-based caching strategy
for by-type lookups; container-wide assignability checks happen only
once on the first by-type lookup and are afterwards cached by type
with the values in the map being an array of all bean names assignable
to that type. This means that at runtime when creating and autowiring
non-singleton beans, the cost of by-type lookups is reduced to that of
ConcurrentHashMap#get.
Issue: SPR-9448
Backport-Issue: SPR-6870
Backport-Commit: 4c7a1c0a54
ClassPathResource.getDescription() now returns consistent, meaningful
results for all variants of ClassPathResource's constructors.
Issue: SPR-9415
Backport-Issue: SPR-9413
Backport-Commit: b50f6e19a6
Prior to this change, request-scoped components having
@Resource-injected dependencies caused a memory leak in
DefaultListableBeanFactory#dependenciesForBeanMap.
Consider the following example:
@Component
@Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class MyComponent {
@Resource
private HttpServletRequest request;
// ...
}
The bean name for "MyComponent" will end up being
'scopedTarget.myComponent', which will become a key in
the #dependenciesForBeanMap structure.
On the first request, the injected HttpServletRequest bean will be a
proxy and will internally have a bean name of the form
"$Proxy10@1a3a2a52". This name will be added to the Set value associated
with the 'scopedTarget.myComponent' entry in #dependenciesForBeanMap.
On the second request, the process will repeat, but the injected
HttpServletRequest will be a different proxy instance, thus having a
different identity hex string, e.g. "$Proxy10@5eba06ff". This name will
also be added to the Set value associated with the
'scopedTarget.myComponent' entry in #dependenciesForBeanMap, and this
is the source of the leak: a new entry is added to the set on each
request but should be added only once.
This commit fixes the leak by introducing caching to
CommonAnnotationBeanPostProcessor#ResourceElement similar to that already
present in AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement
and #AutowiredMethodElement. Essentially, each ResourceElement instance
now tracks whether it has been created, caches the ultimate value to be
injected and returns it eagerly if necessary. Besides solving the memory
leak, this has the side effect of avoiding unnecessary proxy creation.
This fix also explains clearly why injection into request-scoped
components using @Autowired never suffered this memory leak: because the
correct caching was already in place. Because @Resource is considerably
less-frequently used than @Autowired, and given that this particular
injection arrangement is relatively infrequent, it becomes
understandable how this bug has been present without being reported
since the introduction of @Resource support in Spring 2.5: developers
were unlikely to encounter it in the first place; and if they did, the
leak was minor enough (adding strings to a Set), that it could
potentially go unnoticed indefinitely depending on request volumes and
available memory.
Issue: SPR-9363
Backport-Issue: SPR-9176
Backport-Commit: f779c199ea
Commit 3f387eb9cf refactored and
deprecated TransactionAspectUtils, moving its #qualifiedBeanOfType
and related methods into BeanFactoryUtils. This created a package cycle
between beans.factory and beans.factory.annotation due to use of the
beans.factory.annotation.Qualifier annotation in these methods.
This commit breaks the package cycle by introducing
beans.factory.annotation.BeanFactoryAnnotationUtils and moving these
@Qualifier-related methods to it. It is intentionally similar in name
and style to the familiar BeanFactoryUtils class for purposes of
discoverability.
There are no backward-compatibilty concerns associated with this change
as the cycle was introduced, caught and now fixed before a release.
Issue: SPR-9443
Backport-Issue: SPR-6847
Backport-Commit: a4b00c732b