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.
This commit is contained in:
parent
19293b9847
commit
e0de9126ed
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
import org.springframework.expression.AccessException;
|
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
|
@ -34,7 +33,7 @@ import org.springframework.expression.PropertyAccessor;
|
||||||
import org.springframework.expression.TypedValue;
|
import org.springframework.expression.TypedValue;
|
||||||
import org.springframework.expression.spel.SpelEvaluationException;
|
import org.springframework.expression.spel.SpelEvaluationException;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
import org.springframework.expression.spel.support.SimpleEvaluationContext;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.messaging.Message;
|
import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.MessageHeaders;
|
import org.springframework.messaging.MessageHeaders;
|
||||||
|
@ -65,6 +64,11 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||||
/** Default maximum number of entries for the destination cache: 1024 */
|
/** Default maximum number of entries for the destination cache: 1024 */
|
||||||
public static final int DEFAULT_CACHE_LIMIT = 1024;
|
public static final int DEFAULT_CACHE_LIMIT = 1024;
|
||||||
|
|
||||||
|
/** Static evaluation context to re-use */
|
||||||
|
private static SimpleEvaluationContext evaluationContext = SimpleEvaluationContext.builder()
|
||||||
|
.propertyAccessor(new SimpMessageHeaderPropertyAccessor()).build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
private PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
|
|
||||||
|
@ -192,7 +196,6 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||||
if (!this.selectorHeaderInUse) {
|
if (!this.selectorHeaderInUse) {
|
||||||
return allMatches;
|
return allMatches;
|
||||||
}
|
}
|
||||||
EvaluationContext context = null;
|
|
||||||
MultiValueMap<String, String> result = new LinkedMultiValueMap<>(allMatches.size());
|
MultiValueMap<String, String> result = new LinkedMultiValueMap<>(allMatches.size());
|
||||||
for (String sessionId : allMatches.keySet()) {
|
for (String sessionId : allMatches.keySet()) {
|
||||||
for (String subId : allMatches.get(sessionId)) {
|
for (String subId : allMatches.get(sessionId)) {
|
||||||
|
@ -209,12 +212,8 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||||
result.add(sessionId, subId);
|
result.add(sessionId, subId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (context == null) {
|
|
||||||
context = new StandardEvaluationContext(message);
|
|
||||||
context.getPropertyAccessors().add(new SimpMessageHeaderPropertyAccessor());
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (Boolean.TRUE.equals(expression.getValue(context, Boolean.class))) {
|
if (Boolean.TRUE.equals(expression.getValue(evaluationContext, message, Boolean.class))) {
|
||||||
result.add(sessionId, subId);
|
result.add(sessionId, subId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,7 +532,7 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?>[] getSpecificTargetClasses() {
|
public Class<?>[] getSpecificTargetClasses() {
|
||||||
return new Class<?>[] {MessageHeaders.class};
|
return new Class<?>[] {Message.class, MessageHeaders.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -542,21 +541,29 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
|
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) {
|
||||||
Assert.state(target instanceof MessageHeaders, "No MessageHeaders");
|
|
||||||
MessageHeaders headers = (MessageHeaders) target;
|
|
||||||
SimpMessageHeaderAccessor accessor =
|
|
||||||
MessageHeaderAccessor.getAccessor(headers, SimpMessageHeaderAccessor.class);
|
|
||||||
Assert.state(accessor != null, "No SimpMessageHeaderAccessor");
|
|
||||||
Object value;
|
Object value;
|
||||||
if ("destination".equalsIgnoreCase(name)) {
|
if (target instanceof Message) {
|
||||||
value = accessor.getDestination();
|
value = name.equals("headers") ? ((Message) target).getHeaders() : null;
|
||||||
|
}
|
||||||
|
else if (target instanceof MessageHeaders) {
|
||||||
|
MessageHeaders headers = (MessageHeaders) target;
|
||||||
|
SimpMessageHeaderAccessor accessor =
|
||||||
|
MessageHeaderAccessor.getAccessor(headers, SimpMessageHeaderAccessor.class);
|
||||||
|
Assert.state(accessor != null, "No SimpMessageHeaderAccessor");
|
||||||
|
if ("destination".equalsIgnoreCase(name)) {
|
||||||
|
value = accessor.getDestination();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = accessor.getFirstNativeHeader(name);
|
||||||
|
if (value == null) {
|
||||||
|
value = headers.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
value = accessor.getFirstNativeHeader(name);
|
// Should never happen...
|
||||||
if (value == null) {
|
throw new IllegalStateException("Expected Message or MessageHeaders.");
|
||||||
value = headers.get(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new TypedValue(value);
|
return new TypedValue(value);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue