Skip to content

Commit 0009806

Browse files
committed
Re-use EvaluationContext in DefaultSubscriptionRegistry
Rather than create a new EvaluationContext instance per evaluation, we now create a statically shared instance, without the root object in it, and re-use it for all evalutations.
1 parent 6deee3e commit 0009806

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@
2626
import java.util.concurrent.ConcurrentMap;
2727
import java.util.concurrent.CopyOnWriteArraySet;
2828

29-
import org.springframework.expression.AccessException;
3029
import org.springframework.expression.EvaluationContext;
3130
import org.springframework.expression.Expression;
3231
import org.springframework.expression.ExpressionParser;
3332
import org.springframework.expression.PropertyAccessor;
3433
import org.springframework.expression.TypedValue;
3534
import org.springframework.expression.spel.SpelEvaluationException;
3635
import org.springframework.expression.spel.standard.SpelExpressionParser;
37-
import org.springframework.expression.spel.support.StandardEvaluationContext;
36+
import org.springframework.expression.spel.support.SimpleEvaluationContext;
3837
import org.springframework.messaging.Message;
3938
import org.springframework.messaging.MessageHeaders;
4039
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
@@ -64,6 +63,10 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
6463
/** Default maximum number of entries for the destination cache: 1024 */
6564
public static final int DEFAULT_CACHE_LIMIT = 1024;
6665

66+
/** Static evaluation context to reuse */
67+
private static EvaluationContext messageEvalContext =
68+
SimpleEvaluationContext.forPropertyAccessors(new SimpMessageHeaderPropertyAccessor()).build();
69+
6770

6871
private PathMatcher pathMatcher = new AntPathMatcher();
6972

@@ -191,7 +194,6 @@ private MultiValueMap<String, String> filterSubscriptions(
191194
if (!this.selectorHeaderInUse) {
192195
return allMatches;
193196
}
194-
EvaluationContext context = null;
195197
MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(allMatches.size());
196198
for (String sessionId : allMatches.keySet()) {
197199
for (String subId : allMatches.get(sessionId)) {
@@ -208,12 +210,8 @@ private MultiValueMap<String, String> filterSubscriptions(
208210
result.add(sessionId, subId);
209211
continue;
210212
}
211-
if (context == null) {
212-
context = new StandardEvaluationContext(message);
213-
context.getPropertyAccessors().add(new SimpMessageHeaderPropertyAccessor());
214-
}
215213
try {
216-
if (expression.getValue(context, boolean.class)) {
214+
if (Boolean.TRUE.equals(expression.getValue(messageEvalContext, message, Boolean.class))) {
217215
result.add(sessionId, subId);
218216
}
219217
}
@@ -525,7 +523,7 @@ private static class SimpMessageHeaderPropertyAccessor implements PropertyAccess
525523

526524
@Override
527525
public Class<?>[] getSpecificTargetClasses() {
528-
return new Class<?>[] {MessageHeaders.class};
526+
return new Class<?>[] {Message.class, MessageHeaders.class};
529527
}
530528

531529
@Override
@@ -534,19 +532,29 @@ public boolean canRead(EvaluationContext context, Object target, String name) {
534532
}
535533

536534
@Override
537-
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
538-
MessageHeaders headers = (MessageHeaders) target;
539-
SimpMessageHeaderAccessor accessor =
540-
MessageHeaderAccessor.getAccessor(headers, SimpMessageHeaderAccessor.class);
535+
public TypedValue read(EvaluationContext context, Object target, String name) {
541536
Object value;
542-
if ("destination".equalsIgnoreCase(name)) {
543-
value = accessor.getDestination();
537+
if (target instanceof Message) {
538+
value = name.equals("headers") ? ((Message) target).getHeaders() : null;
544539
}
545-
else {
546-
value = accessor.getFirstNativeHeader(name);
547-
if (value == null) {
548-
value = headers.get(name);
540+
else if (target instanceof MessageHeaders) {
541+
MessageHeaders headers = (MessageHeaders) target;
542+
SimpMessageHeaderAccessor accessor =
543+
MessageHeaderAccessor.getAccessor(headers, SimpMessageHeaderAccessor.class);
544+
Assert.state(accessor != null, "No SimpMessageHeaderAccessor");
545+
if ("destination".equalsIgnoreCase(name)) {
546+
value = accessor.getDestination();
549547
}
548+
else {
549+
value = accessor.getFirstNativeHeader(name);
550+
if (value == null) {
551+
value = headers.get(name);
552+
}
553+
}
554+
}
555+
else {
556+
// Should never happen...
557+
throw new IllegalStateException("Expected Message or MessageHeaders.");
550558
}
551559
return new TypedValue(value);
552560
}

0 commit comments

Comments
 (0)