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
- [x] Ensure that property accessors are ordered so that type-matching accessors always have a higher priority than generic/fallback accessors.
- [x] Ensure that property accessors are evaluated in the order in which they were registered.
- [x] Fix the algorithm in
AstUtils.getPropertyAccessorsToTry()
and remove the duplicate algorithm inPropertyOrFieldReference.getPropertyAccessorsToTry()
. - [x] Introduce tests for
AstUtils.getPropertyAccessorsToTry()
in6.1.x
andmain
.
Related Issues
- https://github.com/spring-projects/spring-webflow/issues/1802
Comment From: sbrannen
This issue was fixed in Spring Framework 6.2 M1 in commits 4b0a04857004e3d0e1040a1e70d6ac78af086a6f and d91277095a3eee690f3e6766257cec6e1c2510f8 and tested in Spring Framework 6.1 in commit 9724f9b9c8704ef5e49c183213d28759a7e5a07d and in Spring Framework 6.2 in commit b60cc54b1e6a73708e124033e5485d7364bda368.