1
1
/*
2
- * Copyright 2002-2017 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
19
19
import java .util .Arrays ;
20
20
import java .util .Collections ;
21
21
import java .util .List ;
22
+ import java .util .ListIterator ;
22
23
23
24
import reactor .core .publisher .Mono ;
24
25
26
+ import org .springframework .lang .Nullable ;
25
27
import org .springframework .util .Assert ;
26
- import org .springframework .util .ObjectUtils ;
27
28
import org .springframework .web .server .ServerWebExchange ;
28
29
import org .springframework .web .server .WebFilter ;
29
30
import org .springframework .web .server .WebFilterChain ;
32
33
/**
33
34
* Default implementation of {@link WebFilterChain}.
34
35
*
36
+ * <p>Each instance of this class represents one link in the chain. The public
37
+ * constructor {@link #DefaultWebFilterChain(WebHandler, List)}
38
+ * initializes the full chain and represents its first link.
39
+ *
40
+ * <p>This class is immutable and thread-safe. It can be created once and
41
+ * re-used to handle request concurrently.
42
+ *
35
43
* @author Rossen Stoyanchev
36
44
* @since 5.0
37
45
*/
38
46
public class DefaultWebFilterChain implements WebFilterChain {
39
47
40
- private final List <WebFilter > filters ;
48
+ private final List <WebFilter > allFilters ;
41
49
42
50
private final WebHandler handler ;
43
51
44
- private final int index ;
52
+ @ Nullable
53
+ private final WebFilter currentFilter ;
45
54
55
+ @ Nullable
56
+ private final DefaultWebFilterChain next ;
46
57
47
- public DefaultWebFilterChain (WebHandler handler , WebFilter ... filters ) {
58
+
59
+ /**
60
+ * Public constructor with the list of filters and the target handler to use.
61
+ * @param handler the target handler
62
+ * @param filters the filters ahead of the handler
63
+ * @since 5.1
64
+ */
65
+ public DefaultWebFilterChain (WebHandler handler , List <WebFilter > filters ) {
48
66
Assert .notNull (handler , "WebHandler is required" );
49
- this .filters = ObjectUtils . isEmpty ( filters ) ? Collections .emptyList () : Arrays . asList (filters );
67
+ this .allFilters = Collections .unmodifiableList (filters );
50
68
this .handler = handler ;
51
- this .index = 0 ;
69
+ DefaultWebFilterChain chain = initChain (filters , handler );
70
+ this .currentFilter = chain .currentFilter ;
71
+ this .next = chain .next ;
72
+ }
73
+
74
+ private static DefaultWebFilterChain initChain (List <WebFilter > filters , WebHandler handler ) {
75
+ DefaultWebFilterChain chain = new DefaultWebFilterChain (filters , handler , null , null );
76
+ ListIterator <? extends WebFilter > iterator = filters .listIterator (filters .size ());
77
+ while (iterator .hasPrevious ()) {
78
+ chain = new DefaultWebFilterChain (filters , handler , iterator .previous (), chain );
79
+ }
80
+ return chain ;
52
81
}
53
82
54
- private DefaultWebFilterChain (DefaultWebFilterChain parent , int index ) {
55
- this .filters = parent .getFilters ();
56
- this .handler = parent .getHandler ();
57
- this .index = index ;
83
+ /**
84
+ * Private constructor to represent one link in the chain.
85
+ */
86
+ private DefaultWebFilterChain (List <WebFilter > allFilters , WebHandler handler ,
87
+ @ Nullable WebFilter currentFilter , @ Nullable DefaultWebFilterChain next ) {
88
+
89
+ this .allFilters = allFilters ;
90
+ this .currentFilter = currentFilter ;
91
+ this .handler = handler ;
92
+ this .next = next ;
93
+ }
94
+
95
+ /**
96
+ * Public constructor with the list of filters and the target handler to use.
97
+ * @param handler the target handler
98
+ * @param filters the filters ahead of the handler
99
+ * @deprecated as of 5.1 this constructor is deprecated in favor of
100
+ * {@link #DefaultWebFilterChain(WebHandler, List)}.
101
+ */
102
+ @ Deprecated
103
+ public DefaultWebFilterChain (WebHandler handler , WebFilter ... filters ) {
104
+ this (handler , Arrays .asList (filters ));
58
105
}
59
106
60
107
61
108
public List <WebFilter > getFilters () {
62
- return this .filters ;
109
+ return this .allFilters ;
63
110
}
64
111
65
112
public WebHandler getHandler () {
@@ -69,16 +116,10 @@ public WebHandler getHandler() {
69
116
70
117
@ Override
71
118
public Mono <Void > filter (ServerWebExchange exchange ) {
72
- return Mono .defer (() -> {
73
- if (this .index < this .filters .size ()) {
74
- WebFilter filter = this .filters .get (this .index );
75
- WebFilterChain chain = new DefaultWebFilterChain (this , this .index + 1 );
76
- return filter .filter (exchange , chain );
77
- }
78
- else {
79
- return this .handler .handle (exchange );
80
- }
81
- });
119
+ return Mono .defer (() ->
120
+ this .currentFilter != null && this .next != null ?
121
+ this .currentFilter .filter (exchange , this .next ) :
122
+ this .handler .handle (exchange ));
82
123
}
83
124
84
125
}
0 commit comments