26
26
import java .util .concurrent .ConcurrentMap ;
27
27
import java .util .concurrent .CopyOnWriteArraySet ;
28
28
29
- import org .springframework .expression .AccessException ;
30
29
import org .springframework .expression .EvaluationContext ;
31
30
import org .springframework .expression .Expression ;
32
31
import org .springframework .expression .ExpressionParser ;
33
32
import org .springframework .expression .PropertyAccessor ;
34
33
import org .springframework .expression .TypedValue ;
35
34
import org .springframework .expression .spel .SpelEvaluationException ;
36
35
import org .springframework .expression .spel .standard .SpelExpressionParser ;
37
- import org .springframework .expression .spel .support .StandardEvaluationContext ;
36
+ import org .springframework .expression .spel .support .SimpleEvaluationContext ;
38
37
import org .springframework .messaging .Message ;
39
38
import org .springframework .messaging .MessageHeaders ;
40
39
import org .springframework .messaging .simp .SimpMessageHeaderAccessor ;
@@ -64,6 +63,10 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
64
63
/** Default maximum number of entries for the destination cache: 1024 */
65
64
public static final int DEFAULT_CACHE_LIMIT = 1024 ;
66
65
66
+ /** Static evaluation context to reuse */
67
+ private static EvaluationContext messageEvalContext =
68
+ SimpleEvaluationContext .forPropertyAccessors (new SimpMessageHeaderPropertyAccessor ()).build ();
69
+
67
70
68
71
private PathMatcher pathMatcher = new AntPathMatcher ();
69
72
@@ -191,7 +194,6 @@ private MultiValueMap<String, String> filterSubscriptions(
191
194
if (!this .selectorHeaderInUse ) {
192
195
return allMatches ;
193
196
}
194
- EvaluationContext context = null ;
195
197
MultiValueMap <String , String > result = new LinkedMultiValueMap <String , String >(allMatches .size ());
196
198
for (String sessionId : allMatches .keySet ()) {
197
199
for (String subId : allMatches .get (sessionId )) {
@@ -208,12 +210,8 @@ private MultiValueMap<String, String> filterSubscriptions(
208
210
result .add (sessionId , subId );
209
211
continue ;
210
212
}
211
- if (context == null ) {
212
- context = new StandardEvaluationContext (message );
213
- context .getPropertyAccessors ().add (new SimpMessageHeaderPropertyAccessor ());
214
- }
215
213
try {
216
- if (expression .getValue (context , boolean .class )) {
214
+ if (Boolean . TRUE . equals ( expression .getValue (messageEvalContext , message , Boolean .class ) )) {
217
215
result .add (sessionId , subId );
218
216
}
219
217
}
@@ -525,7 +523,7 @@ private static class SimpMessageHeaderPropertyAccessor implements PropertyAccess
525
523
526
524
@ Override
527
525
public Class <?>[] getSpecificTargetClasses () {
528
- return new Class <?>[] {MessageHeaders .class };
526
+ return new Class <?>[] {Message . class , MessageHeaders .class };
529
527
}
530
528
531
529
@ Override
@@ -534,19 +532,29 @@ public boolean canRead(EvaluationContext context, Object target, String name) {
534
532
}
535
533
536
534
@ 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 ) {
541
536
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 ;
544
539
}
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 ();
549
547
}
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." );
550
558
}
551
559
return new TypedValue (value );
552
560
}
0 commit comments