Polish "Register controller advices to RSocket messaging"

See gh-45360
This commit is contained in:
Stéphane Nicoll 2025-10-06 11:24:51 +02:00
parent 94fce6f689
commit 485180df4f
3 changed files with 36 additions and 6 deletions

View File

@ -69,6 +69,8 @@ Spring Boot will auto-configure the Spring Messaging infrastructure for RSocket.
This means that Spring Boot will create a javadoc:org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler[] bean that will handle RSocket requests to your application.
TIP: You can use {url-spring-framework-docs}/web/webmvc/mvc-controller/ann-advice.html[`@ControllerAdvice`] to handle exceptions.
[[messaging.rsocket.requester]]

View File

@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.MessagingAdviceBean;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.messaging.rsocket.RSocketStrategies;
@ -38,6 +39,7 @@ import org.springframework.web.method.ControllerAdviceBean;
*
* @author Brian Clozel
* @author Dmitry Sulman
* @author Stephane Nicoll
* @since 4.0.0
*/
@AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class)
@ -51,12 +53,39 @@ public final class RSocketMessagingAutoConfiguration {
RSocketMessageHandler messageHandler = new RSocketMessageHandler();
messageHandler.setRSocketStrategies(rSocketStrategies);
customizers.orderedStream().forEach((customizer) -> customizer.customize(messageHandler));
ControllerAdviceBean.findAnnotatedBeans(context)
.forEach((controllerAdviceBean) -> messageHandler
.registerMessagingAdvice(new ControllerAdviceBeanWrapper(controllerAdviceBean)));
return messageHandler;
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ControllerAdviceBean.class)
static class MessagingAdviceConfiguration {
@Bean
MessagingAdviceRSocketMessageHandlerCustomizer messagingAdviceRSocketMessageHandlerCustomizer(
ApplicationContext applicationContext) {
return new MessagingAdviceRSocketMessageHandlerCustomizer(applicationContext);
}
}
static final class MessagingAdviceRSocketMessageHandlerCustomizer implements RSocketMessageHandlerCustomizer {
private final ApplicationContext applicationContext;
MessagingAdviceRSocketMessageHandlerCustomizer(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void customize(RSocketMessageHandler messageHandler) {
ControllerAdviceBean.findAnnotatedBeans(this.applicationContext)
.forEach((controllerAdviceBean) -> messageHandler
.registerMessagingAdvice(new ControllerAdviceBeanWrapper(controllerAdviceBean)));
}
}
private static final class ControllerAdviceBeanWrapper implements MessagingAdviceBean {
private final ControllerAdviceBean adviceBean;

View File

@ -89,15 +89,14 @@ class RSocketMessagingAutoConfigurationTests {
void shouldRegisterControllerAdvice() {
this.contextRunner.withBean(TestControllerAdvice.class).withBean(TestController.class).run((context) -> {
RSocketMessageHandler handler = context.getBean(RSocketMessageHandler.class);
TestControllerAdvice controllerAdvice = context.getBean(TestControllerAdvice.class);
MessageHeaderAccessor headers = new MessageHeaderAccessor();
RouteMatcher.Route route = handler.getRouteMatcher().parseRoute("exception");
headers.setHeader(DestinationPatternsMessageCondition.LOOKUP_DESTINATION_HEADER, route);
headers.setHeader(RSocketFrameTypeMessageCondition.FRAME_TYPE_HEADER, FrameType.REQUEST_FNF);
Message<?> message = MessageBuilder.createMessage(Mono.empty(), headers.getMessageHeaders());
StepVerifier.create(handler.handleMessage(message)).expectComplete().verify();
assertThat(controllerAdvice.isExceptionHandled()).isTrue();
assertThat(context.getBean(TestControllerAdvice.class).isExceptionHandled()).isTrue();
});
}