├── .gitignore
├── README.md
├── docker-compose.yaml
├── justfile
├── pom.xml
├── reactive-landscape.png
├── reactive.http
└── src
├── main
├── java
│ └── org
│ │ └── mvnsearch
│ │ ├── reactor
│ │ ├── HttpBinAPI.java
│ │ ├── HttpBinResponse.java
│ │ └── MutableContext.java
│ │ └── spring
│ │ ├── KotlinCoroutineMethod.java
│ │ ├── ReactiveDemoApp.kt
│ │ └── UserService.kt
└── uml
│ └── reactive-classes.puml
└── test
├── java
└── org
│ └── mvnsearch
│ ├── adapter
│ ├── Account.java
│ ├── AccountService.java
│ ├── Cache.java
│ ├── KafkaReactiveApi.java
│ ├── Transaction.java
│ ├── TransactionService.java
│ └── TransactionTest.java
│ ├── akka
│ ├── AkkaStreamTest.java
│ └── HelloActorContext.kt
│ ├── awaitility
│ └── AwaitilityTest.java
│ ├── block
│ ├── ReactiveServiceRpcProxy.java
│ ├── ReactiveServiceRpcProxyInvocationHandler.java
│ └── UserInterface.java
│ ├── cart
│ ├── Account.java
│ ├── AccountReactiveService.java
│ ├── AccountService.java
│ ├── EmailReactiveService.java
│ ├── EmailService.java
│ ├── NotificationManager.java
│ └── impl
│ │ ├── NotificationManagerImpl.java
│ │ ├── NotificationManagerReactiveImpl.java
│ │ └── PortalController.java
│ ├── coroutines
│ ├── CoroutineInvocationHandler.kt
│ ├── CoroutinesFlowTest.kt
│ ├── DelegateTest.kt
│ └── UserServiceKtTest.kt
│ ├── eventloop
│ ├── EventLoopTest.java
│ └── ExecutorServiceTest.java
│ ├── flow
│ └── FlowTest.kt
│ ├── future
│ └── CompletableFutureTest.java
│ ├── kafka_streams
│ └── KafkaStreamsDemo.java
│ ├── mutiny
│ └── SmallRyeMutinyTest.java
│ ├── reactor
│ ├── EncodingException.java
│ ├── EventListener.java
│ ├── ExceptionTest.java
│ ├── MonoCacheTest.java
│ ├── ProcessorTest.kt
│ ├── R2dbcConnection.java
│ ├── ReactorContextTest.java
│ ├── ReactorExceptionTest.java
│ ├── ReactorFluxTest.java
│ ├── ReactorKotlinTest.kt
│ ├── ReactorMonoTest.java
│ ├── ReactorPoolTest.java
│ ├── ReactorProcessorTest.kt
│ ├── ReactorToolsTest.java
│ ├── Resilience4jTest.java
│ ├── RetrofitTest.java
│ ├── RetryTest.java
│ ├── SchedulerTest.java
│ ├── SvelteTest.java
│ ├── TestPublisherTest.java
│ ├── UpstreamEvent.java
│ ├── UserServiceImplTest.java
│ ├── WebClientTest.java
│ ├── blockhound
│ │ └── BlockHoundTest.java
│ ├── filterchain
│ │ ├── FilterChain.java
│ │ ├── FilterChainTest.java
│ │ └── ItemFilter.java
│ ├── kafka
│ │ ├── KafkaReactorReceiverTest.java
│ │ └── KafkaReactorSenderTest.java
│ └── netty
│ │ ├── NettyClientTest.java
│ │ ├── TcpServerApp.java
│ │ └── User.java
│ ├── reaktive
│ └── ReaktiveTest.kt
│ ├── rsocket
│ ├── requester
│ │ ├── RSocketAppRunner1.java
│ │ ├── RSocketLocalTest.java
│ │ └── RSocketRequesterApp.java
│ └── responder
│ │ ├── RSocketResponderHandler.java
│ │ └── RsocketAppServer.java
│ ├── rxjava
│ ├── ObservableTest.java
│ ├── RxJavaTest.java
│ └── RxKotlinTest.kt
│ ├── rxjava2
│ ├── FlowableTest.java
│ └── SingleTest.java
│ ├── rxjava3
│ └── RxJava3Test.java
│ └── streamex
│ └── StreamExTest.java
└── resources
├── application.properties
├── junit-platform.properties
└── logback-test.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### JetBrains template
3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5 |
6 | # User-specific stuff:
7 | .idea/workspace.xml
8 | .idea/tasks.xml
9 | .idea/dictionaries
10 | .idea/vcs.xml
11 | .idea/jsLibraryMappings.xml
12 |
13 | # Sensitive or high-churn files:
14 | .idea/dataSources.ids
15 | .idea/dataSources.xml
16 | .idea/dataSources.local.xml
17 | .idea/sqlDataSources.xml
18 | .idea/dynamic.xml
19 | .idea/uiDesigner.xml
20 |
21 | # Gradle:
22 | .idea/gradle.xml
23 | .idea/libraries
24 |
25 | # Mongo Explorer plugin:
26 | .idea/mongoSettings.xml
27 |
28 | ## File-based project format:
29 | *.iws
30 | *.iml
31 |
32 | ## Plugin-specific files:
33 |
34 | # IntelliJ
35 | /out/
36 |
37 | # mpeltonen/sbt-idea plugin
38 | .idea_modules/
39 |
40 | # JIRA plugin
41 | atlassian-ide-plugin.xml
42 |
43 | # Crashlytics plugin (for Android Studio and IntelliJ)
44 | com_crashlytics_export_strings.xml
45 | crashlytics.properties
46 | crashlytics-build.properties
47 | fabric.properties
48 | ### Java template
49 | *.class
50 |
51 | # Mobile Tools for Java (J2ME)
52 | .mtj.tmp/
53 |
54 | # Package Files #
55 | *.jar
56 | *.war
57 | *.ear
58 |
59 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
60 | hs_err_pid*
61 | ### Maven template
62 | target/
63 | pom.xml.tag
64 | pom.xml.releaseBackup
65 | pom.xml.versionsBackup
66 | pom.xml.next
67 | release.properties
68 | dependency-reduced-pom.xml
69 | buildNumber.properties
70 | .mvn/timing.properties
71 |
72 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Reactive Programming
2 | ====================
3 |
4 | 
5 |
6 | ### Demos
7 | Please use JDK 11 to run all demos.
8 |
9 | * Java 9 Flow
10 | * RxJava 1.x
11 | * RxJava 2.x
12 | * Reactor 3.2.x
13 | * RSocket
14 | * Reactive API for Cache, Messaging
15 | * Reactive with HTTP: webclient & retrofit
16 | * Kotlin
17 | * Webflux
18 | * Kotlin Coroutines & Flow
19 | * Reaktive: Kotlin multi-platform implementation of Reactive Extensions
20 |
21 | ### Glossary
22 |
23 | * reactive: 响应的,响应式的
24 | * streaming: 流式的
25 | * asynchronous: 异步的
26 | * non-blocking: 非阻塞的
27 | * Observable 可观测的
28 | * Single: 单个的
29 | * Flux: 流量
30 | * Mono: 单一的
31 |
32 | ### Reactive Operation
33 |
34 | * Creation
35 | * Combine
36 | * transform(map,flatMap)
37 | * Filter
38 | * Mathematical and Aggregate Operators
39 | * Utility Operators
40 | * Conditional and Boolean Operators
41 | * Error Handling
42 |
43 | ##### reactive stream
44 |
45 | * Publisher: A Publisher is a provider of a potentially unbounded number of sequenced elements, publishing them according to the demand received from its Subscriber(s).
46 | * Subscriber: Receive call to onSubscribe(Subscription) once after passing an instance of Subscriber to Publisher.subscribe(Subscriber).
47 | * Subscription: A Subscription represents a one-to-one lifecycle of a Subscriber subscribing to a Publisher, use subscription.request() method to request items.
48 | * Processor: Processor represents a processing stage—which is both a Subscriber and a Publisher and obeys the contracts of both
49 |
50 | ### ReactiveX
51 |
52 | * Observable
53 | * Operators
54 | * Single
55 | * Subject
56 | * Scheduler
57 |
58 | ### Java 9
59 |
60 | https://www.baeldung.com/java-9-reactive-streams
61 |
62 | * java.util.concurrent.Flow: Interrelated interfaces and static methods for establishing flow-controlled components
63 | * SubmissionPublisher: publisher
64 |
65 | ##### RxJava
66 |
67 | * Observable: This class provides methods for subscribing to the Observable as well as delegate methods to the various Observers.
68 | * Single: Reactive Pattern for a single value response
69 | * Observer: Provides a mechanism for receiving push-based notifications
70 | * Subscriber: Provides a mechanism for receiving push-based notifications from Observables, and permits manual unsubscribing from these Observables.
71 |
72 | #### RxJava 2 & 3
73 |
74 | RxJava 2 features several base classes you can discover operators on:
75 |
76 | * io.reactivex.Flowable: 0..N flows, supporting Reactive-Streams and backpressure
77 | * io.reactivex.Observable: 0..N flows, no backpressure,
78 | * io.reactivex.Single: a flow of exactly 1 item or an error,
79 | * io.reactivex.Completable: a flow without items but only a completion or error signal,
80 | * io.reactivex.Maybe: a flow with no items, exactly one item or an error.
81 | * Notification: Represents the reactive signal types: onNext, onError and onComplete and holds their parameter values (a value, a Throwable, nothing)
82 | * Subject: Represents an Observer and an Observable at the same time, allowing multicasting events from a single source to multiple child Observers
83 |
84 | ##### Reactor
85 |
86 | * Flux: A Reactive Streams {@link Publisher} with rx operators that emits 0 to N elements, and then completes (successfully or with an error).
87 | * Mono: A Reactive Streams {@link Publisher} with basic rx operators that completes successfully by emitting an element, or with an error.
88 | * FluxSink: next/error/complete sink to push data to flux
89 | * FluxProcessor: processor
90 | * Signal: A domain representation of a Reactive Stream signal. There are 4 distinct signals and their possible sequence is defined as such: onError | (onSubscribe onNext* (onError | onComplete)?)
91 |
92 | #### Akka Stream
93 |
94 | Stream process: Source -> Flow -> Sink
95 |
96 | * Source: A processing stage with exactly one output, emitting data elements whenever downstream processing stages are ready to receive them.
97 | * Sink: A processing stage with exactly one input, requesting and accepting data elements possibly slowing down the upstream producer of elements
98 | * Flow: A processing stage which has exactly one input and output, which connects its up- and downstreams by transforming the data elements flowing through it.
99 | * Source.single: Stream a single object
100 |
101 | Operators: https://doc.akka.io/docs/akka/2.5/stream/operators/index.html#source-operators
102 |
103 | ### Kafka Streams
104 |
105 | https://kafka.apache.org/documentation/streams/
106 |
107 | * Topology: A topology is an acyclic graph of sources, processors, and sinks.
108 | * KafkaStreams: A Kafka client that allows for performing continuous computation on input coming from one or more input topics and sends output to zero, one, or more output topics.
109 | * KStream: an abstraction of a record stream of eyValue pairs
110 |
111 | ### Kafka Reactor
112 |
113 | https://projectreactor.io/docs/kafka/release/reference/
114 |
115 | * KafkaSender: publishing messages to Kafka
116 | * KafkaReceiver: consuming messages from Kafka
117 |
118 | ### RxJava VS Reactor
119 |
120 | * RxJava诞生早,使用广泛,尤其在Netflix产品中
121 | * Reactor和Spring整合密切
122 | * 在Java 8支持方面,Reactor基于Java 8,而RxJava是自己的API
123 | * RxJava的模型在其他语言都有实现,如果你用多语言的场景化,RxJava的模型更好一些,如Angular等
124 |
125 | https://www.nurkiewicz.com/2019/02/rxjava-vs-reactor.html
126 |
127 | ### Kotlin Extension
128 |
129 | * https://github.com/ReactiveX/RxKotlin
130 | * https://github.com/reactor/reactor-kotlin-extensions
131 |
132 | ### BlockHound
133 | BlockHound(block代码猎犬)是一个Java agent,主要检测非阻塞线程中的同步调用。 我们常见的同步方法如下:
134 |
135 | * java.lang.Thread: sleep, yield, onSpinWait
136 | * java.lang.Object: wait
137 | * java.io.RandomAccessFile: read0, readBytes, write0, writeBytes
138 | * java.io.FileInputStream: read0, readBytes
139 | * java.io.FileOutputStream: write, writeBytes
140 | * java.net.Socket: connect
141 | * java.net.DatagramSocket: connect
142 | * java.net.PlainDatagramSocketImpl: connect0, peekData, send
143 | * java.net.PlainSocketImpl: socketAccept
144 | * java.net.SocketInputStream: socketRead0
145 | * java.net.SocketOutputStream: socketWrite0
146 | * sun.misc.Unsafe: park
147 | * jdk.internal.misc.Unsafe: park
148 | * java.lang.ProcessImpl: forkAndExec
149 | * java.lang.UNIXProcess: forkAndExec
150 |
151 |
152 | 凡是涉及到以上代码,都是同步调用,需要注意,尤其是使用wait和notifyAll来设计线程协调。
153 |
154 | * java.util.concurrent.CountDownLatch: await
155 |
156 |
157 | ### Exception handling
158 |
159 | Reactor for handling error: doOnError, onErrorMap, onErrorReturn, and onErrorResume
160 |
161 | * doOnError: executed when an error is thrown and hasn't been caught
162 | * onErrorMap: used to map an error into another error. As it's only being mapped, the error is still thrown
163 | * onErrorReturn: set a fallback value that will be returned if error is thrown. The next operator in the chain will get the fallback value instead of error.
164 | * onErrorResume: set a fallback method that will be executed if error is thrown. The next operator in the chain will get the result of the fallback method instead of error.
165 |
166 | ### References
167 |
168 | * http://www.reactive-streams.org: Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure
169 | * http://reactivex.io: An API for asynchronous programming with observable streams
170 | * http://projectreactor.io: Reactor is a second-generation Reactive library for building non-blocking applications on the JVM based on the Reactive Streams Specification
171 | * https://tech.io/playgrounds/929/reactive-programming-with-reactor-3/content/Intro
172 | * http://reactivex.io/documentation/operators.html: reactive operations
173 | * https://dzone.com/articles/functional-amp-reactive-spring-along-with-netflix: Functional and Reactive Spring with Reactor and Netflix OSS
174 | * RxJava2 响应式编程介绍: https://zouzhberk.github.io/rxjava-study/
175 | * Reactive Streams: https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md#specification
176 | * RSocket: http://rsocket.io/
177 | * Reactor Netty: http://projectreactor.io/docs/netty/release/reference/index.html
178 | * Reactor Testing: http://projectreactor.io/docs/core/release/reference/index.html
179 | * RxJava Extensions: https://github.com/akarnokd
180 | * Reaktive — a multiplatform library for reactive Kotlin: https://github.com/badoo/Reaktive https://badootech.badoo.com/reaktive-a-multiplatform-library-for-reactive-kotlin-android-ios-77b6ff25adb1
181 | * Reactive Spring Boot: https://learning.oreilly.com/live-training/courses/reactive-spring-boot/0636920371410/
182 | * Reactive marble diagram generator: https://bitbucket.org/achary/rx-marbles/ https://medium.com/@jshvarts/read-marble-diagrams-like-a-pro-3d72934d3ef5
183 | * Animated playground for Rx Observables: https://rxviz.com/
184 | * SmallRye Mutiny: a reactive programming library https://github.com/smallrye/smallrye-mutiny
185 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | zookeeper:
4 | image: zookeeper:3.4.13
5 | ports:
6 | - "2181:2181"
7 | - "2888:2888"
8 | - "3888:3888"
9 | kafka:
10 | image: wurstmeister/kafka:2.12-2.1.0
11 | ports:
12 | - "9092:9092"
13 | environment:
14 | KAFKA_ADVERTISED_HOST_NAME: 127.0.01
15 | KAFKA_CREATE_TOPICS: "Topic1:1:1:delete,testTopic:1:1:delete"
16 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
17 | kafka-manager:
18 | image: sheepkiller/kafka-manager
19 | ports:
20 | - "9000:9000"
21 | links:
22 | - kafka
23 | - zookeeper
24 | environment:
25 | APPLICATION_SECRET: 123456
26 | ZK_HOSTS: zookeeper:2181
27 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | # rsocket request/response testing
2 | rsocket_request_response:
3 | rsocket-cli --request -i "I am a Client" tcp://localhost:7000
4 |
5 | # send messages to kafka from console input
6 | send_kafka_messages:
7 | docker-compose exec kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic testTopic
8 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.mvnsearch.spring.reactor
7 | reactive-demo
8 | 1.0.0-SNAPSHOT
9 | jar
10 |
11 | Reactive Demo
12 |
13 |
14 | UTF-8
15 | 21
16 | 2023.0.0
17 | 1.3.8
18 | 2.2.21
19 | 3.1.8
20 | 2.0.1
21 | 2.4.0
22 | 1.9.21
23 | 1.8.0-RC
24 | 5.0.0-alpha.11
25 | 2.9.0
26 | 1.1.4
27 | 2.8.1
28 | 3.6.0
29 | 3.2.0
30 | 2.1.0
31 | 0.8.2
32 | 5.10.1
33 |
34 |
35 |
36 |
37 | org.jetbrains
38 | annotations
39 | 24.1.0
40 |
41 |
42 | org.projectlombok
43 | lombok
44 |
45 |
46 | org.reactivestreams
47 | reactive-streams
48 | 1.0.4
49 |
50 |
51 | io.projectreactor
52 | reactor-core
53 |
54 |
55 | io.projectreactor.addons
56 | reactor-extra
57 |
58 |
59 | io.projectreactor.addons
60 | reactor-adapter
61 |
62 |
74 |
75 | io.projectreactor
76 | reactor-tools
77 |
78 |
79 | io.projectreactor.addons
80 | reactor-pool
81 |
82 |
83 | io.projectreactor.kotlin
84 | reactor-kotlin-extensions
85 | 1.2.2
86 |
87 |
88 | io.reactivex
89 | rxjava
90 | ${rxjava.version}
91 |
92 |
93 | io.reactivex.rxjava2
94 | rxjava
95 | ${rxjava2.version}
96 |
97 |
98 | io.reactivex.rxjava3
99 | rxjava
100 | ${rxjava3.version}
101 |
102 |
103 | io.reactivex.rxjava2
104 | rxkotlin
105 | 2.4.0
106 |
107 |
108 | io.reactivex.rxjava3
109 | rxkotlin
110 | 3.0.1
111 |
112 |
113 | com.github.akarnokd
114 | rxjava2-extensions
115 | 0.20.10
116 |
117 |
118 | com.github.akarnokd
119 | rxjava3-extensions
120 | 3.1.1
121 |
122 |
123 |
124 | com.typesafe.akka
125 | akka-stream_2.13
126 |
127 |
128 |
129 | org.apache.kafka
130 | kafka-streams
131 | ${kafka-streams.version}
132 |
133 |
134 | io.projectreactor.kafka
135 | reactor-kafka
136 |
137 |
138 |
139 | com.jakewharton.retrofit
140 | retrofit2-reactor-adapter
141 | 2.1.0
142 |
143 |
144 | com.squareup.retrofit2
145 | retrofit
146 | ${retrofit.version}
147 |
148 |
149 | com.squareup.retrofit2
150 | converter-jackson
151 | ${retrofit.version}
152 |
153 |
154 | com.squareup.okhttp3
155 | okhttp
156 | ${okhttp3.version}
157 |
158 |
159 | io.github.resilience4j
160 | resilience4j-reactor
161 | ${resilience4j.version}
162 |
163 |
164 | io.github.resilience4j
165 | resilience4j-ratelimiter
166 | ${resilience4j.version}
167 |
168 |
169 | one.util
170 | streamex
171 | ${streamex.version}
172 |
173 |
174 |
175 | org.jetbrains.kotlin
176 | kotlin-stdlib
177 |
178 |
179 | org.jetbrains.kotlinx
180 | kotlinx-coroutines-core
181 |
182 |
183 | org.jetbrains.kotlinx
184 | kotlinx-coroutines-reactor
185 |
186 |
187 |
188 | com.fasterxml.jackson.core
189 | jackson-databind
190 |
191 |
192 |
193 | io.rsocket
194 | rsocket-core
195 |
196 |
197 | io.rsocket
198 | rsocket-transport-netty
199 |
200 |
201 | io.rsocket
202 | rsocket-transport-local
203 |
204 |
205 | org.springframework.boot
206 | spring-boot-starter-webflux
207 |
208 |
209 | com.google.guava
210 | guava
211 | 32.1.3-jre
212 |
213 |
214 | io.projectreactor.netty
215 | reactor-netty
216 |
217 |
218 | com.badoo.reaktive
219 | reaktive-jvm
220 | ${reaktive.version}
221 |
222 |
223 | com.badoo.reaktive
224 | rxjava2-interop
225 | ${reaktive.version}
226 |
227 |
228 | com.badoo.reaktive
229 | coroutines-interop-jvm
230 | ${reaktive.version}
231 |
232 |
233 | io.smallrye.reactive
234 | mutiny
235 |
236 |
237 | io.smallrye.reactive
238 | mutiny-reactor
239 |
240 |
241 | io.projectreactor
242 | reactor-test
243 | test
244 |
245 |
246 | org.awaitility
247 | awaitility
248 | 4.2.0
249 | test
250 |
251 |
252 | org.awaitility
253 | awaitility-kotlin
254 | 4.2.0
255 | test
256 |
257 |
258 | org.junit.jupiter
259 | junit-jupiter
260 | test
261 |
262 |
263 | org.assertj
264 | assertj-core
265 | 3.24.2
266 | test
267 |
268 |
269 |
270 |
271 |
272 |
273 | org.junit
274 | junit-bom
275 | ${junit5.version}
276 | import
277 | pom
278 |
279 |
280 | org.jetbrains.kotlin
281 | kotlin-bom
282 | ${kotlin.version}
283 | import
284 | pom
285 |
286 |
287 | org.jetbrains.kotlinx
288 | kotlinx-coroutines-bom
289 | ${kotlinx-coroutines.version}
290 | import
291 | pom
292 |
293 |
294 | io.projectreactor
295 | reactor-bom
296 | ${reactor-bom.version}
297 | pom
298 | import
299 |
300 |
301 | io.smallrye.reactive
302 | mutiny-bom
303 | ${mutiny.version}
304 | pom
305 | import
306 |
307 |
308 | com.typesafe.akka
309 | akka-bom_2.13
310 | ${akka.version}
311 | pom
312 | import
313 |
314 |
315 | io.rsocket
316 | rsocket-bom
317 | ${rsocket.version}
318 | pom
319 | import
320 |
321 |
322 | org.springframework.boot
323 | spring-boot-dependencies
324 | ${spring-boot.version}
325 | import
326 | pom
327 |
328 |
329 |
330 |
331 |
332 |
333 | kotlin-maven-plugin
334 | org.jetbrains.kotlin
335 | ${kotlin.version}
336 |
337 |
338 | kapt
339 |
340 | kapt
341 |
342 |
343 |
344 | ${project.basedir}/src/main/kotlin
345 |
346 |
347 |
348 |
349 | compile
350 | process-sources
351 |
352 | compile
353 |
354 |
355 |
356 | ${project.basedir}/src/main/kotlin
357 | ${project.basedir}/src/main/java
358 |
359 |
360 |
361 |
362 | test-compile
363 |
364 | test-compile
365 |
366 |
367 |
368 | ${project.basedir}/src/test/kotlin
369 | ${project.basedir}/src/test/java
370 |
371 |
372 |
373 |
374 |
375 | ${java.version}
376 | true
377 |
378 | -Xjsr305=strict
379 |
380 |
381 | spring
382 |
383 |
384 |
385 |
386 | org.jetbrains.kotlin
387 | kotlin-maven-allopen
388 | ${kotlin.version}
389 |
390 |
391 |
392 |
393 | org.apache.maven.plugins
394 | maven-compiler-plugin
395 | 3.11.0
396 |
397 | ${java.version}
398 | ${java.version}
399 | true
400 |
401 |
402 |
403 |
404 | default-compile
405 | none
406 |
407 |
408 |
409 | default-testCompile
410 | none
411 |
412 |
413 | java-compile
414 | compile
415 |
416 | compile
417 |
418 |
419 |
420 | java-test-compile
421 | test-compile
422 |
423 | testCompile
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
--------------------------------------------------------------------------------
/reactive-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linux-china/reactive-demo/7fe3a20bfb214f7303df10e88574972f401a68b6/reactive-landscape.png
--------------------------------------------------------------------------------
/reactive.http:
--------------------------------------------------------------------------------
1 | ### http request for mono
2 | GET http://localhost:8080/
3 |
4 | ### http request for single
5 | GET http://localhost:8080/rx
6 |
7 | ###
8 |
9 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/reactor/HttpBinAPI.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.reactor;
2 |
3 | import reactor.core.publisher.Mono;
4 | import retrofit2.http.GET;
5 |
6 | /**
7 | * httpbin api
8 | *
9 | * @author linux_china
10 | */
11 | public interface HttpBinAPI {
12 | @GET("/ip")
13 | Mono ip();
14 |
15 | @GET("/uuid")
16 | Mono uuid();
17 |
18 | @GET("/headers")
19 | Mono headers();
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/reactor/HttpBinResponse.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.reactor;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Data;
5 |
6 | import java.util.Map;
7 |
8 | /**
9 | * httpbin response
10 | *
11 | * @author linux_china
12 | */
13 | @Data
14 | public class HttpBinResponse {
15 | private String uuid;
16 | @JsonProperty(value = "origin")
17 | private String ip;
18 | private Map headers;
19 | }
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/reactor/MutableContext.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.reactor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import reactor.util.context.Context;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.stream.Stream;
9 |
10 | /**
11 | * Mutable Reactor context
12 | *
13 | * @author linux_china
14 | */
15 | public class MutableContext implements Context {
16 | HashMap