Tutorial: Reactive Spring Boot, Part 10: Spring Profiles to Switch Clients
In this final installment on building a Reactive Spring Boot app, we focus on using Spring profiles to switch clients.
Join the DZone community and get the full member experience.
Join For FreeIn this lesson, we use Spring Profiles to enable an application to determine which of our two clients (server-sent events via WebClient, or RSocket) to use to connect to our Kotlin Spring Boot price service.
This is the final part of our tutorial showing how to build a Reactive application using Spring Boot, Kotlin, Java, and JavaFX. The original inspiration was a 70-minute live demo.
Here is everything you've missed so far:
Tutorial: Reactive Spring Boot, Part 1: Building a Kotlin REST Service
Tutorial: Reactive Spring Boot, Part 2: A REST Client for Reactive Streams
Tutorial: Reactive Spring Boot, Part 3: A JavaFX Spring Boot Application
Tutorial: Reactive Spring Boot, Part 4: A JavaFX Line Chart
Tutorial: Reactive Spring Boot, Part 5: Auto-Configuration for Shared Beans
Tutorial: Reactive Spring Boot, Part 6: Displaying Reactive Data
Tutorial: Reactive Spring Boot, Part 7: Subscribing Multiple Subscribers
Tutorial: Reactive Spring Boot, Part 8: Kotlin RSocket Server
Tutorial: Reactive Spring Boot, Part 9: Java RSocket Client
This blog post contains a video showing the process step-by-step and a textual walk-through (adapted from the transcript of the video) for those who prefer a written format.
This tutorial is a series of steps during which we will build a full Spring Boot application featuring a Kotlin back-end, a Java client, and a JavaFX user interface.
Now we have an RSocket client that lets us connect to our RSocket server, we want to use this from our JavaFX application.
Creating the RSocketStockClient Bean
We intentionally have two implementations of ourStockClient
, one for connecting via RSocket and one via WebClient. Our ClientConfiguration
only exposes one of these, the WebClientStockClient
, as a bean. If we want applications to be able to use the RSocket client, we need to add an RSocket client bean as well.
- Create a new @Bean method on
ClientConfiguration
in the stock-client module, calledrSocketStockClient
, which returns aStockClient
. - The body of this method needs to return a new
RSocketStockClient
, which will need to take anrSocketRequester
as a constructor argument. - Add an RSocketRequester as a method parameter to this
rSocketStockClient
method. - (Tip: We can get IntelliJ IDEA to add the correct method parameter if we pass an unknown variable
rSocketRequester
into theRSocketStockClient
constructor, press Alt+Enter on the unknown variable and select "Create parameter".) - (Tip: IntelliJ IDEA Ultimate will warn you that this parameter can't be autowired because no beans match this type.)
- Create another
@Bean
method calledrSocketRequester
that returns anRSocketRequester
. - Declare an RSocketRequester.Builder parameter
builder
for the method. This should be wired in automatically by Spring. - Use the builder's connectTcp method and give it "localhost" and port 7000 (that's where our Spring Boot RSocket server is running). Call
block()
to complete this connection.
x
public class ClientConfiguration {
// WebClientStockClient bean method...
public StockClient rSocketStockClient(RSocketRequester rSocketRequester) {
return new RSocketStockClient(rSocketRequester);
}
public RSocketRequester rSocketRequester(RSocketRequester.Builder builder) {
return builder.connectTcp("localhost", 7000).block();
}
// WebClient bean method...
}
Choosing Which Bean to Use
If we go to our JavaFX ChartController
(in the stock-ui module), this is the class that uses the StockClient
to connect to the price service and display prices on the chart. IntelliJ IDEA Ultimate shows a warning in this class that there's more than one Bean that matches the StockClient
type, our RSocket stock client and our WebClient
stock client. We need to figure out a way to specify which client we really want to use. One way to do this is with Spring profiles.
- Add a @Profile annotation to the
WebClientStockClient
method, passing in a value ofsse
(Server-Sent Events). - Give the
RSocketStockClient
a @Profile of "rsocket".
x
"sse") (
public StockClient webClientStockClient(WebClient webClient) {
return new WebClientStockClient(webClient);
}
"rsocket") (
public StockClient rSocketStockClient(RSocketRequester rSocketRequester) {
return new RSocketStockClient(rSocketRequester);
}
Selecting the Active Profile
If we're using IntelliJ IDEA Ultimate, when we go to the ChartController
, we can see the error has gone away now. But we still need to say which profile we want to use.
- Go to application.properties in the stock-ui module.
- Set the spring.profiles.active property to
sse
. This should give us the same bean and the same functionality that we had before.
# web-application and application title properties here...
spring.profiles.active=sse
- Re-run the application, the application should start up as expected and the chart should show two sets of prices as before.
- Note in the run window that the JavaFX application has started up with the sse profile.
Logging for Debugging
If we want to be extra sure that we're using the bean we think we're using, we could go back to the clients and add some logging.
-
1. In the
pricesFor
method of
WebClientStockClient
, add an info-level log message to state that this is the
WebClient
stock client.
x
public Flux<StockPrice> pricesFor(String symbol) {
log.info("WebClient stock client");
return // create Flux here...
}
-
2. Do something similar for the
RSocketStockClient
.
x
public Flux<StockPrice> pricesFor(String symbol) {
log.info("RSocket stock client");
return // create Flux here...
}
-
3. Re-run the application, we should see two log messages that we're using the
WebClient
stock client.
Getting Prices Via RSocket
Let's finally use RSocket to get prices to display on our JavaFX line chart.
- Go back to the application.properties file in stock-ui and change the active profile to
rsocket
. - Re-run the application, everything should still works the way we expect. This time we're using the rsocket profile and connecting to the RSocket price server via the
RSocketStockClient
.
xxxxxxxxxx
# web-application and application title properties here...
spring.profiles.active=rsocket
So, there we have it. A full end-to-end application with a JavaFX line chart that subscribes to a reactive stream of prices from a Kotlin Spring Boot application, and can be configured to get those prices either via server-sent events or via the new RSocket protocol.
The full code is available on GitHub:
- Client project (stock-client and stock-ui modules).
- Server project (Kotlin Spring Boot application)
Further Reading
Fully Reactive: Spring, Kotlin, and JavaFX Playing Together [Links]
Published at DZone with permission of Trisha Gee, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments