原文由 Trisha Gee 在当地时间2019年12月16日发布在 INTELLIJ IDEA BLOG
在这一节,我们使用Spring Profiles让应用程序决定使用哪个客户端(使用服务端发送事件的 WebClient,或 RSocket)连接到Kotlin Spring Boot股票价格服务。
现在我们有了一个RSocket客户端,可以让我们连接到我们的RSocket服务器,我们想在我们的JavaFX应用程序中使用它。
创建 RSocketStockClient Bean
我们特意创建两种StockClient
实现,一个通过RSocket连接,然后另一个是用WebClient。我们的ClientConfiguration
仅将其中一个Bean暴露,即WebClientStockClient
,如果我们希望应用程序能够使用RSocket客户端,则也需要添加一个RSocketClient
Bean。
在stock-client模块的
ClientConfiguration
创建一个新的@Bean
方法,命名为rSocketStockClient
,其返回值类型为StockClient
。这个方法体需要返回一个新的
RSocketStockClient
,所以需要一个rSocketRequester
作为构造函数参数。给
rSocketStockClient
方法添加一个RSocketRequester
作为参数。(提示:我们可以让IntelliJ IDEA添加适当的方法参数,如果我们传入一个未知变量
rSocketRequester
到RSocketStockClient
的构造器,在未知变量按下Alt+Enter并选择“Create parameter”)(提示:IntelliJ IDEA Ultimate会警告你说这个参数不能自动注入,因为没有类型匹配的Beans)
创建另一个名为
rSocketRequester
的@Bean
方法,返回RSocketRequester
。给方法声明一个类型为
RSocketRequester.Builder
的参数builder
这应该会被Spring自动注入。使用
builder
的connectTcp
方法,并给它 “localhost” 和端口 7000(这是Spring Boot的RSocket运行地址)。调用block()
方法完成这次连接。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class ClientConfiguration {
// WebClientStockClient bean 方法...
@Bean
public StockClient rSocketStockClient(RSocketRequester rSocketRequester) {
return new RSocketStockClient(rSocketRequester);
}
@Bean
public RSocketRequester rSocketRequester(RSocketRequester.Builder builder) {
return builder.connectTcp("localhost", 7000).block();
}
// WebClient bean 方法...
}
选择使用哪个 Bean
如果我们回到JavaFX的ChartController
(在stock-ui 模块),这个类就是用了StockClient
去连接到价格服务,并在图表上显示价格的。IntelliJ IDEA 旗舰版在这个类显示警告,说这里边有多于一个Bean符合 StockClient 类型,也就是我们的rSocketStockClient
和webClientStockClient
。我们需要配置一种方式,指定我们实际想要使用哪个客户端。一种做法是使用Spring profiles。
- 添加一个
@Profile
注解到webClientStockClient
方法,传入一个值sse
(表示 Server-Sent Events)。 - 给
rSocketStockClient
添加一个@Profile
注解,值为rsocket
1
2
3
4
5
6
7
8
9
10
11
@Bean
@Profile("sse")
public StockClient webClientStockClient(WebClient webClient) {
return new WebClientStockClient(webClient);
}
@Bean
@Profile("rsocket")
public StockClient rSocketStockClient(RSocketRequester rSocketRequester) {
return new RSocketStockClient(rSocketRequester);
}
选择激活的配置
如果我们使用的是IntelliJ IDEA旗舰版,当我们在ChartController
里面,我们可以看到错误已经消失了。但我们还是需要指定想要使用哪个配置(profile)。
- 去到stock-ui模块的application.properties文件
- 设置 spring.profiles.active属性的值为
sse
这应该会给我们同样的Bean和之前同样的功能。
1
2
# web-application and application title properties here...
spring.profiles.active=sse
- 重新运行应用程序,程序应该按预期启动,并像之前那样显示两组价格数据。
- 注意到在运行窗口,JavaFX应用程序已经以sse配置启动。
调试日志
如果我们想更加确认我们所使用的Bean,我们可以回到客户端并添加一些日志功能。
- 在
WebClientStockClient
里面的pricesFor
方法添加一个info等级的日志信息表示当前使用的是 WebClient stock client。
1
2
3
4
public Flux<StockPrice> pricesFor(String symbol) {
log.info("WebClient stock client");
return // 在这里创建Flux
}
- 在
RSocketStockClient
也做类似的操作
1
2
3
4
public Flux<StockPrice> pricesFor(String symbol) {
log.info("RSocket stock client");
return // 在这里创建Flux
}
- 重新运行应用程序,我们应该看到两个日志消息,表示我们当前使用的是WebClient stock client。
通过 RSocket 获取价格
最后让我们使用RSocket去获取股票价格并显示到JavaFX的折线图上吧。
- 回到stock-ui的application.properties文件,并将活动的配置改为
rsocket
。 - 重新运行应用程序,所有东西应该按预期运行。这次我们使用的是rsocket配置,并通过
RSocketStockClient
连接到RSocket价格服务器。
1
2
#这里是 web-application 和 application title 的属性...
spring.profiles.active=rsocket
所以就是这样子。一个完整的带有JavaFX折线图,并订阅到一个Kotlin Spring Boot应用程序的响应式数据流的价格数据的端到端应用程序。而且我们能够配置通过服务端发送事件或新的RSocket协议获取这些股票价格。
全部代码在 GitHub:https://github.com/zwt-io/rsb/