@@ -12,17 +12,16 @@ This section provides basic information on the Spring Web Reactive support in Sp
12
12
13
13
In plain terms reactive programming is about non-blocking applications that are asynchronous
14
14
and event-driven and require a small number of threads to scale. A key aspect of that
15
- definition is the concept of backpressure which is a mechanism to ensures producers
15
+ definition is the concept of backpressure which is a mechanism to ensure producers
16
16
don't overwhelm consumers. For example in a pipeline of reactive components that extends
17
- from the database to the HTTP server when an HTTP connection slows down the data
18
- repository slows down as well or stops until capacity frees up.
17
+ from the database to the HTTP socket when the HTTP client is slow the data
18
+ repository slows down or stops until capacity frees up.
19
19
20
- Reactive programming involves a shift from imperative to declarative, async composition
21
- of logic. This is comparable to how `CompletableFuture` in Java 8 allows declaring
22
- follow-up actions in lambda expressions to be executed when the future completes .
20
+ From a programming model perspective reactive programming involves a major shift from imperative style logic
21
+ to a declarative composition of async logic. It is comparable to using `CompletableFuture` in Java 8
22
+ and composing follow-up actions via lambda expressions.
23
23
24
- A proper introduction to Reactive programming is beyond scope of this documentation.
25
- For a more extended introduction check the excellent multi-part series
24
+ For a more extended introduction to reactive programming check the excellent multi-part series
26
25
https://spring.io/blog/2016/06/07/notes-on-reactive-programming-part-i-the-reactive-landscape["Notes on Reactive Programming"]
27
26
by Dave Syer.
28
27
@@ -33,83 +32,94 @@ by Dave Syer.
33
32
Spring Framework 5 embraces
34
33
https://github.com/reactive-streams/reactive-streams-jvm#reactive-streams[Reactive Streams]
35
34
as the contract for communicating backpressure across async components and
36
- libraries. Reactive Streams is the result of an industry collaboration and is also
37
- adopted in Java 9 as `java.util.concurrent.Flow`.
35
+ libraries. Reactive Streams is a specification created through industry collaboration that
36
+ has also been adopted in Java 9 as `java.util.concurrent.Flow`.
38
37
39
- For its own reactive support the Spring Framework relies on
40
- https://projectreactor.io/[ Reactor] which implements Reactive Streams and extends
41
- the Reactive Streams `Publisher` contract with the `Flux` and `Mono` composable API
42
- types that provide declarative operations on data sequence of `0..N` and `0..1`.
38
+ The Spring Framework uses https://projectreactor.io/[Reactor] internally for its own
39
+ reactive support. Reactor is a Reactive Streams implementation that further extends the
40
+ basic Reactive Streams `Publisher` contract with the `Flux` and `Mono` composable API
41
+ types to provide declarative operations on data sequences of `0..N` and `0..1`.
43
42
44
- The Spring Framework exposes `Flux` and `Mono` in many of its reactive APIs.
45
- At the application level however as always Spring provides choice and fully supports
46
- the use of RxJava. For more on reactive types check the blog post
43
+ The Spring Framework exposes `Flux` and `Mono` in many of its own reactive APIs.
44
+ At the application level however, as always, Spring provides choice and fully supports
45
+ the use of RxJava. For more on reactive types check the post
47
46
https://spring.io/blog/2016/04/19/understanding-reactive-types["Understanding Reactive Types"]
48
47
by Sebastien Deleuze.
49
48
50
49
51
50
[[web-reactive-feature-overview]]
52
- == Spring Reactive Web Overview
51
+ == Spring Web Reactive Overview
53
52
54
53
55
54
[[web-reactive-module]]
56
55
=== Spring Web Reactive Module
57
56
58
57
59
58
Spring Framework 5 adds a new `spring-web-reactive` module that supports the same
60
- `@Controller` and `@RestController` programming model as Spring MVC but executed
61
- on a reactive and non-blocking foundation . The diagram below shows how Spring MVC
62
- and Spring Web Reactive side by side:
59
+ `@Controller` programming model as Spring MVC but executed on a reactive,
60
+ non-blocking engine . The diagram below shows how Spring MVC and Spring Web
61
+ Reactive compare side by side:
63
62
64
63
image::images/web-reactive-overview.png[width=720]
65
64
66
- Spring Web Reactive makes use of the Servlet 3.1 non-blocking I/O API and runs on
67
- Servlet 3.1 containers and also on other non-blocking runtimes such as Netty and Undertow.
65
+ Spring Web Reactive makes use of Servlet 3.1 non-blocking I/O and runs on
66
+ Servlet 3.1 containers. It also runs on non-Servlet runtimes such as Netty and Undertow.
68
67
Each runtime is adapted to a set of shared, reactive `ServerHttpRequest` and
69
68
`ServerHttpResponse` abstractions that expose the request and response body
70
69
as `Flux<DataBuffer>` with full backpressure support on the read and the
71
70
write side.
72
71
73
72
The `spring-core` module provides reactive `Encoder` and `Decoder` contracts
74
- that enable the serialization of a `Flux` of bytes to and from typed objects
75
- along with some basic implementations.
73
+ that enable the serialization of a `Flux` of bytes to and from typed objects.
74
+ The `spring-web` module adds JSON (Jackson) and XML (JAXB) implementations for use in
75
+ web applications as well as others for SSE streaming and zero-copy file transfer.
76
76
77
- The `spring-web` modules adds JSON and XML implementations for use in reactive
78
- web applications and also provides support for SSE streaming and zero-copy
79
- file transfer.
80
-
81
- The `spring-web-reactive` module defines many of the same contracts as
82
- Spring MVC such as `HandlerMapping` and `HandlerAdapter` among others.
83
- These reactive counterparts have asynchronous and non-blocking semantics and
84
- operate on the reactive HTTP request and response abstractions.
77
+ The `spring-web-reactive` module contains the Spring Web Reactive framework that supports
78
+ the `@Controller` programming model. It re-defines many of the Spring MVC contracts
79
+ such as `HandlerMapping` and `HandlerAdapter` to be asynchronous and
80
+ non-blocking and to operate on the reactive HTTP request and response. For this reason
81
+ Spring MVC and Spring Web Reactive cannot share any code. However they do share
82
+ many of the same algorithms.
85
83
86
84
The end result is a programming model identical to today's Spring MVC but
87
- supporting reactive types and executing on a reactive, non-blocking foundation.
88
- For example a controller method can declare any of the following as a method argument:
89
-
90
- * `@RequestBody Account account` -- the account is deserialized without
91
- blocking before the controller method is invoked.
92
- * `@RequestBody Mono<Account> account` -- the controller can use the `Mono`
93
- type to declare the logic execute when the account is deserialized.
94
- * `@RequestBody Single<Account> account` -- same but with RxJava
95
- * `@RequestBody Flux<Account>` accounts` -- streaming scenario.
96
- * `@RequestBody Observable<Account> accounts` -- streaming with RxJava.
97
-
98
- The same principle also applies on the side of return value handling.
85
+ with support for reactive types and executed in a reactive manner.
86
+ For example a controller method can declare the following as an
87
+ `@RequestBody` method argument:
88
+
89
+ * `Account account` -- the account is deserialized without
90
+ blocking before the controller is invoked.
91
+ * `Mono<Account> account` -- the controller can use the `Mono`
92
+ to declare logic to be executed after the account is deserialized.
93
+ * `Single<Account> account` -- same as with `Mono` but using RxJava
94
+ * `Flux<Account> accounts` -- input streaming scenario.
95
+ * `Observable<Account> accounts` -- input streaming with RxJava.
96
+
97
+ The above also applies to return value handling:
98
+
99
+ * `Mono<Account>` -- serialize without blocking the given Account when the `Mono` completes.
100
+ * `Singe<Account>` -- same but using RxJava.
101
+ * `Flux<Account>` -- streaming scenario, possibly SSE depending on the requested content type.
102
+ * `Flux<SseEvent>` -- SSE streaming.
103
+ * `Observable<SseEvent>` -- same but using RxJava.
104
+ * `Mono<Void>` -- request handling completes when the `Mono` completes.
105
+ * `void` -- request handling completes when the method returns;
106
+ implies a synchronous, non-blocking controller method.
107
+ * `Account` -- serialize without blocking the given Account;
108
+ implies a synchronous, non-blocking controller method.
99
109
100
110
101
111
[[web-reactive-client]]
102
112
=== Reactive Web Client
103
113
104
114
Spring Framework 5 adds a new reactive `WebClient` in addition to the existing `RestTemplate`.
105
115
106
- Much like on the server side each supported HTTP client is adapted to a set of shared,
116
+ Each supported HTTP client (e.g. Reactor Netty) is adapted to a set of shared,
107
117
reactive `ClientHttpRequest` and `ClientHttpResponse` abstractions that expose the request
108
118
and response body as `Flux<DataBuffer>` with full backpressure support on the read and
109
- the write side. The `Encoder` and `Decoder` abstractions from `spring-core` also used on
110
- the client side for serialization of a `Flux` of bytes to and from typed objects.
119
+ the write side. The `Encoder` and `Decoder` abstractions from `spring-core` are also used on
120
+ the client side for the serialization of a `Flux` of bytes to and from typed objects.
111
121
112
- Below is an example :
122
+ An example of using the `WebClient` :
113
123
114
124
[source,java,indent=0]
115
125
[subs="verbatim,quotes"]
@@ -122,10 +132,9 @@ Mono<Account> response = webClient
122
132
.extract(body(Account.class));
123
133
----
124
134
125
- The above example assumes the import of static methods from `ClientWebRequestBuilder`
126
- and `ResponseExtractors`. The enable a fluent syntax similar to that of the MockMvc API
127
- from Spring MVC Test. The same can also be done with RxJava. Simply replace with static
128
- imports from `RxJava1ClientWebRequestBuilder` and `RxJava1ResponseExtractors`:
135
+ The above assumes static method imports from `ClientWebRequestBuilder` and `ResponseExtractors`
136
+ that enable a fluent syntax. The same can also be done with RxJava using static imports from
137
+ `RxJava1ClientWebRequestBuilder` and `RxJava1ResponseExtractors` instead:
129
138
130
139
[source,java,indent=0]
131
140
[subs="verbatim,quotes"]
@@ -143,10 +152,10 @@ Single<Account> response = webClient
143
152
[[web-reactive-getting-started-boot]]
144
153
=== Spring Boot Starter
145
154
146
- The quickest way to get started is through the experimental Spring Boot Web Reactive
147
- starter available on http://start.spring.io. It does all the work so you can simply start
148
- writing `@Controller` classes. By default the starter runs with Tomcat but you can change
149
- the dependencies and use one of the other supported HTTP runtimes .
155
+ The experimental Spring Boot Web Reactive starter available via http://start.spring.io
156
+ is the quickest way to get started. It does all the work so you can start
157
+ writing `@Controller` classes. By default it runs on Tomcat but the dependencies can
158
+ be changed as usual with Spring Boot to switch to a different runtime .
150
159
151
160
152
161
[[web-reactive-getting-started-manual]]
@@ -173,24 +182,22 @@ server.afterPropertiesSet();
173
182
server.start();
174
183
----
175
184
176
- The `WebReactiveConfiguration` at (1) is the Web Reactive Java config from the `spring-web-reactive`
185
+ The `WebReactiveConfiguration` at (1) is the Java config from `spring-web-reactive`
177
186
and is similar in purpose to the MVC Java config from `spring-webmvc`. It provides the
178
- the web framework configuration required to get started leaving you only to
179
- declare your own `@Controller' beans.
187
+ web framework configuration required to get started leaving you only to
188
+ declare your own `@Controller` beans.
180
189
181
190
The `DispatcherHandler` at (2) is the equivalent of the `DispatcherServlet` in Spring MVC.
182
191
183
192
The `HttpServer` at (3) is an abstraction from the
184
193
https://github.com/spring-projects/spring-framework/tree/master/spring-web/src/test/java/org/springframework/http/server/reactive/bootstrap[test sources]
185
- of the `spring-web-reactive` module that's used for the framework 's own integration tests.
186
- It comes with basic implementations of all supported runtimes .
194
+ of `spring-web-reactive` used for Spring Framework 's own integration tests.
195
+ The abstraction comes with basic implementations for each supported runtime .
187
196
188
197
189
198
[[web-reactive-getting-started-M1]]
190
- === Extent of M1 Support
191
-
192
- For M1 the Spring Web Reactive module focuses on support for REST scenarios both
193
- client and server-side. Basic HTML rendering with Freemarker is also supported but
194
- limited to rendering, i.e. there is no support form submissions yet.
199
+ === Extent of Support in 5.0 M1
195
200
196
- On the client side for M1 the Reactor Netty HTTP client is supported.
201
+ For M1 the Spring Web Reactive module focuses on REST scenarios for both
202
+ client and server. Basic HTML rendering with Freemarker is also supported but
203
+ limited to rendering but not form submissions.
0 commit comments