15
15
*/
16
16
package org .springframework .http .client .reactive ;
17
17
18
+ import java .util .function .Consumer ;
19
+ import java .util .function .Supplier ;
20
+
18
21
import reactor .netty .http .HttpResources ;
19
22
import reactor .netty .resources .ConnectionProvider ;
20
23
import reactor .netty .resources .LoopResources ;
37
40
*/
38
41
public class ReactorResourceFactory implements InitializingBean , DisposableBean {
39
42
40
- private boolean globalResources = true ;
43
+ private boolean useGlobalResources = true ;
44
+
45
+ @ Nullable
46
+ private Consumer <HttpResources > globalResourcesConsumer ;
47
+
48
+
49
+ private Supplier <ConnectionProvider > connectionProviderSupplier = () -> ConnectionProvider .elastic ("http" );
50
+
51
+ private Supplier <LoopResources > loopResourcesSupplier = () -> LoopResources .create ("reactor-http" );
52
+
41
53
42
54
@ Nullable
43
55
private ConnectionProvider connectionProvider ;
44
56
45
57
@ Nullable
46
58
private LoopResources loopResources ;
47
59
48
- private String threadPrefix = "reactor-http" ;
60
+
61
+ private boolean manageConnectionProvider = false ;
62
+
63
+ private boolean manageLoopResources = false ;
49
64
50
65
51
66
/**
52
- * Whether to expose and manage the global Reactor Netty resources from the
53
- * {@link HttpResources} holder.
54
- * <p>Default is "true" in which case this factory helps to configure and
55
- * shut down the global Reactor Netty resources within the lifecycle of a
56
- * Spring {@code ApplicationContext}.
57
- * <p>If set to "false" then the factory creates and manages its own
58
- * {@link LoopResources} and {@link ConnectionProvider}, independent of the
59
- * global ones in the {@link HttpResources} holder.
60
- * @param globalResources whether to expose and manage the global resources
67
+ * Whether to use global Reactor Netty resources via {@link HttpResources}.
68
+ * <p>Default is "true" in which case this factory initializes and stops the
69
+ * global Reactor Netty resources within Spring's {@code ApplicationContext}
70
+ * lifecycle. If set to "false" the factory manages its resources independent
71
+ * of the global ones.
72
+ * @param useGlobalResources whether to expose and manage the global resources
73
+ * @see #addGlobalResourcesConsumer(Consumer)
61
74
*/
62
- public void setGlobalResources (boolean globalResources ) {
63
- this .globalResources = globalResources ;
75
+ public void setUseGlobalResources (boolean useGlobalResources ) {
76
+ this .useGlobalResources = useGlobalResources ;
64
77
}
65
78
66
79
/**
67
- * Configure the {@link ConnectionProvider} to use.
68
- * <p>By default, initialized with {@link ConnectionProvider#elastic(String)}.
69
- * @param connectionProvider the connection provider to use
80
+ * Add a Consumer for configuring the global Reactor Netty resources on
81
+ * startup. When this option is used, {@link #setUseGlobalResources} is also
82
+ * enabled.
83
+ * @param consumer the consumer to apply
84
+ * @see #setUseGlobalResources(boolean)
70
85
*/
71
- public void setConnectionProvider (@ Nullable ConnectionProvider connectionProvider ) {
72
- this .connectionProvider = connectionProvider ;
86
+ public void addGlobalResourcesConsumer (Consumer <HttpResources > consumer ) {
87
+ this .useGlobalResources = true ;
88
+ this .globalResourcesConsumer = this .globalResourcesConsumer != null ?
89
+ this .globalResourcesConsumer .andThen (consumer ) : consumer ;
73
90
}
74
91
75
92
/**
76
- * Configure the {@link LoopResources} to use.
77
- * <p>By default, initialized with {@link LoopResources#create(String)}.
78
- * @param loopResources the loop resources to use
93
+ * Use this option when you don't want to participate in global resources and
94
+ * you want to customize the creation of the managed {@code ConnectionProvider}.
95
+ * <p>By default, {@code ConnectionProvider.elastic("http")} is used.
96
+ * <p>Note that this option is ignored if {@code userGlobalResources=false} or
97
+ * {@link #setConnectionProvider(ConnectionProvider)} is set.
98
+ * @param supplier the supplier to use
79
99
*/
80
- public void setLoopResources (@ Nullable LoopResources loopResources ) {
81
- this .loopResources = loopResources ;
100
+ public void setConnectionProviderSupplier (@ Nullable Supplier <ConnectionProvider > supplier ) {
101
+ this .connectionProviderSupplier = supplier ;
102
+ }
103
+
104
+ /**
105
+ * Use this option when you don't want to participate in global resources and
106
+ * you want to customize the creation of the managed {@code LoopResources}.
107
+ * <p>By default, {@code LoopResources.create("reactor-http")} is used.
108
+ * <p>Note that this option is ignored if {@code userGlobalResources=false} or
109
+ * {@link #setLoopResources(LoopResources)} is set.
110
+ * @param supplier the supplier to use
111
+ */
112
+ public void setLoopResourcesSupplier (@ Nullable Supplier <LoopResources > supplier ) {
113
+ this .loopResourcesSupplier = supplier ;
114
+ }
115
+
116
+ /**
117
+ * Use this option when you want to provide an externally managed
118
+ * {@link ConnectionProvider} instance.
119
+ * @param connectionProvider the connection provider to use as is
120
+ */
121
+ public void setConnectionProvider (@ Nullable ConnectionProvider connectionProvider ) {
122
+ this .connectionProvider = connectionProvider ;
82
123
}
83
124
84
125
/**
85
- * Configure the thread prefix to initialize {@link LoopResources} with. This
86
- * is used only when a {@link LoopResources} instance isn't
87
- * {@link #setLoopResources(LoopResources) provided}.
88
- * <p>By default set to "reactor-http".
89
- * @param threadPrefix the thread prefix to use
126
+ * Use this option when you want to provide an externally managed
127
+ * {@link LoopResources} instance.
128
+ * @param loopResources the loop resources to use as is
90
129
*/
91
- public void setThreadPrefix (String threadPrefix ) {
92
- Assert .notNull (threadPrefix , "Thread prefix is required" );
93
- this .threadPrefix = threadPrefix ;
130
+ public void setLoopResources (@ Nullable LoopResources loopResources ) {
131
+ this .loopResources = loopResources ;
94
132
}
95
133
96
134
97
135
/**
98
136
* Whether this factory exposes the global
99
137
* {@link reactor.netty.http.HttpResources HttpResources} holder.
100
138
*/
101
- public boolean isGlobalResources () {
102
- return this .globalResources ;
139
+ public boolean isUseGlobalResources () {
140
+ return this .useGlobalResources ;
103
141
}
104
142
105
143
/**
106
144
* Return the configured {@link ConnectionProvider}.
107
145
*/
108
- @ Nullable
109
146
public ConnectionProvider getConnectionProvider () {
147
+ Assert .notNull (this .connectionProvider , "ConnectionProvider not initialized yet via InitializingBean." );
110
148
return this .connectionProvider ;
111
149
}
112
150
113
151
/**
114
152
* Return the configured {@link LoopResources}.
115
153
*/
116
- @ Nullable
117
154
public LoopResources getLoopResources () {
155
+ Assert .notNull (this .loopResources , "LoopResources not initialized yet via InitializingBean." );
118
156
return this .loopResources ;
119
157
}
120
158
121
- /**
122
- * Return the configured prefix for event loop threads.
123
- */
124
- public String getThreadPrefix () {
125
- return this .threadPrefix ;
126
- }
127
-
128
159
129
160
@ Override
130
161
public void afterPropertiesSet () throws Exception {
131
- if (this .loopResources == null ) {
132
- this .loopResources = LoopResources .create (this .threadPrefix );
133
- }
134
- if (this .connectionProvider == null ) {
135
- this .connectionProvider = ConnectionProvider .elastic ("http" );
162
+ if (this .useGlobalResources ) {
163
+ Assert .isTrue (this .loopResources == null && this .connectionProvider == null ,
164
+ "'useGlobalResources' is mutually exclusive with explicitly configured resources." );
165
+ HttpResources httpResources = HttpResources .get ();
166
+ if (this .globalResourcesConsumer != null ) {
167
+ this .globalResourcesConsumer .accept (httpResources );
168
+ }
136
169
}
137
- if (this .globalResources ) {
138
- HttpResources .set (this .loopResources );
139
- HttpResources .set (this .connectionProvider );
170
+ else {
171
+ if (this .loopResources == null ) {
172
+ this .manageLoopResources = true ;
173
+ this .loopResources = this .loopResourcesSupplier .get ();
174
+ }
175
+ if (this .connectionProvider == null ) {
176
+ this .manageConnectionProvider = true ;
177
+ this .connectionProvider = this .connectionProviderSupplier .get ();
178
+ }
140
179
}
141
180
}
142
181
143
182
@ Override
144
183
public void destroy () {
145
- if (this .globalResources ) {
184
+ if (this .useGlobalResources ) {
146
185
HttpResources .disposeLoopsAndConnections ();
147
186
}
148
187
else {
149
188
try {
150
189
ConnectionProvider provider = this .connectionProvider ;
151
- if (provider != null ) {
190
+ if (provider != null && this . manageConnectionProvider ) {
152
191
provider .dispose ();
153
192
}
154
193
}
@@ -158,7 +197,7 @@ public void destroy() {
158
197
159
198
try {
160
199
LoopResources resources = this .loopResources ;
161
- if (resources != null ) {
200
+ if (resources != null && this . manageLoopResources ) {
162
201
resources .dispose ();
163
202
}
164
203
}
0 commit comments