Description
Overview
The PropertyAccessor
SPI in the Spring Expression Language (SpEL) defines a getSpecificTargetClasses()
method which allows an accessor to declare what types the accessor supports, or null
if it is a "generic" accessor.
The contract for ordering accessors is only partially mentioned in the Javadoc for PropertyAccessor
; however, it is explained in detail in the Javadoc for org.springframework.expression.spel.ast.AstUtils.getPropertyAccessorsToTry()
:
The resolvers are considered to be in an ordered list, however in the returned list any that are exact matches for the input target type (as opposed to 'general' resolvers that could work for any type) are placed at the start of the list. In addition, there are specific resolvers that exactly name the class in question and resolvers that name a specific class but it is a supertype of the class we have. These are put at the end of the specific resolvers set and will be tried after exactly matching accessors but before generic accessors.
And similar Javadoc exists for the private getPropertyAccessorsToTry()
method in PropertyOrFieldReference
.
However, the implementations of AstUtils.getPropertyAccessorsToTry()
and PropertyOrFieldReference.getPropertyAccessorsToTry()
do not honor that last part of the contract.
On the contrary, a generic accessor (such as ReflectivePropertyAccessor
) is ordered before a custom PropertyAccessor
that claims to support a supertype of the target type, if the generic accessor is registered before the custom accessor.
In other words, a generic accessor can incorrectly take priority over a matching type-specific accessor.
Deliverables
- Ensure that property accessors are ordered so that type-matching accessors always have a higher priority than generic/fallback accessors.
- Ensure that property accessors are evaluated in the order in which they were registered.
- Fix the algorithm in
AstUtils.getPropertyAccessorsToTry()
and remove the duplicate algorithm inPropertyOrFieldReference.getPropertyAccessorsToTry()
. - Introduce tests for
AstUtils.getPropertyAccessorsToTry()
in6.1.x
andmain
.