Skip to content

Commit 4a0dc8b

Browse files
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
1 parent 321d847 commit 4a0dc8b

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

Diff for: src/main/java/org/springframework/data/keyvalue/aot/KeyValueRuntimeHints.java

+6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
package org.springframework.data.keyvalue.aot;
1717

1818
import java.util.Arrays;
19+
import java.util.List;
1920

21+
import org.springframework.aot.hint.ExecutableMode;
2022
import org.springframework.aot.hint.MemberCategory;
2123
import org.springframework.aot.hint.RuntimeHints;
2224
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -41,5 +43,9 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
4143
TypeReference.of(org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository.class),
4244
TypeReference.of(KeyValuePartTreeQuery.class)),
4345
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
46+
47+
hints.reflection().registerType(org.springframework.util.comparator.NullSafeComparator.class,
48+
builder -> builder.withMethod("compare",
49+
List.of(TypeReference.of(Object.class), TypeReference.of(Object.class)), ExecutableMode.INVOKE));
4450
}
4551
}

Diff for: src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
import org.springframework.expression.spel.standard.SpelExpression;
2121
import org.springframework.expression.spel.standard.SpelExpressionParser;
22+
import org.springframework.expression.spel.support.SimpleEvaluationContext;
2223
import org.springframework.lang.Nullable;
2324
import org.springframework.util.Assert;
25+
import org.springframework.util.comparator.NullSafeComparator;
2426

2527
/**
2628
* {@link Comparator} implementation using {@link SpelExpression}.
@@ -115,9 +117,8 @@ protected SpelExpression getExpression() {
115117
*/
116118
protected String buildExpressionForPath() {
117119

118-
String rawExpression = String.format(
119-
"new org.springframework.util.comparator.NullSafeComparator(new org.springframework.util.comparator.ComparableComparator(), %s).compare(#arg1?.%s,#arg2?.%s)",
120-
Boolean.toString(this.nullsFirst), path.replace(".", "?."), path.replace(".", "?."));
120+
String rawExpression = String.format("#comparator.compare(#arg1?.%s,#arg2?.%s)", path.replace(".", "?."),
121+
path.replace(".", "?."));
121122

122123
return rawExpression;
123124
}
@@ -127,8 +128,12 @@ public int compare(T arg1, T arg2) {
127128

128129
SpelExpression expressionToUse = getExpression();
129130

130-
expressionToUse.getEvaluationContext().setVariable("arg1", arg1);
131-
expressionToUse.getEvaluationContext().setVariable("arg2", arg2);
131+
SimpleEvaluationContext ctx = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
132+
ctx.setVariable("comparator", new NullSafeComparator(Comparator.naturalOrder(), this.nullsFirst));
133+
ctx.setVariable("arg1", arg1);
134+
ctx.setVariable("arg2", arg2);
135+
136+
expressionToUse.setEvaluationContext(ctx);
132137

133138
return expressionToUse.getValue(Integer.class) * (asc ? 1 : -1);
134139
}

0 commit comments

Comments
 (0)