Avoid instantiating ComparableComparator via reflection.

We now use a dedicated instance instead of relying upon reflectively created ones, however we still need to register the compare call for reflective access.

Resolves: #564
This commit is contained in:
Christoph Strobl
2024-03-06 14:48:25 +01:00
parent c07ad08ee3
commit 7d7bd29e30
2 changed files with 16 additions and 5 deletions

View File

@@ -16,7 +16,9 @@
package org.springframework.data.keyvalue.aot;
import java.util.Arrays;
import java.util.List;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -41,5 +43,9 @@ class KeyValueRuntimeHints implements RuntimeHintsRegistrar {
TypeReference.of(org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository.class),
TypeReference.of(KeyValuePartTreeQuery.class)),
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
hints.reflection().registerType(org.springframework.util.comparator.NullSafeComparator.class,
builder -> builder.withMethod("compare",
List.of(TypeReference.of(Object.class), TypeReference.of(Object.class)), ExecutableMode.INVOKE));
}
}

View File

@@ -19,8 +19,10 @@ import java.util.Comparator;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.comparator.NullSafeComparator;
/**
* {@link Comparator} implementation using {@link SpelExpression}.
@@ -115,9 +117,8 @@ public class SpelPropertyComparator<T> implements Comparator<T> {
*/
protected String buildExpressionForPath() {
String rawExpression = String.format(
"new org.springframework.util.comparator.NullSafeComparator(new org.springframework.util.comparator.ComparableComparator(), %s).compare(#arg1?.%s,#arg2?.%s)",
Boolean.toString(this.nullsFirst), path.replace(".", "?."), path.replace(".", "?."));
String rawExpression = String.format("#comparator.compare(#arg1?.%s,#arg2?.%s)", path.replace(".", "?."),
path.replace(".", "?."));
return rawExpression;
}
@@ -127,8 +128,12 @@ public class SpelPropertyComparator<T> implements Comparator<T> {
SpelExpression expressionToUse = getExpression();
expressionToUse.getEvaluationContext().setVariable("arg1", arg1);
expressionToUse.getEvaluationContext().setVariable("arg2", arg2);
SimpleEvaluationContext ctx = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
ctx.setVariable("comparator", new NullSafeComparator(Comparator.naturalOrder(), this.nullsFirst));
ctx.setVariable("arg1", arg1);
ctx.setVariable("arg2", arg2);
expressionToUse.setEvaluationContext(ctx);
return expressionToUse.getValue(Integer.class) * (asc ? 1 : -1);
}