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. 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]] [[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.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.MessagingAdviceBean; import org.springframework.messaging.handler.MessagingAdviceBean;
import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.messaging.rsocket.RSocketStrategies; import org.springframework.messaging.rsocket.RSocketStrategies;
@ -38,6 +39,7 @@ import org.springframework.web.method.ControllerAdviceBean;
* *
* @author Brian Clozel * @author Brian Clozel
* @author Dmitry Sulman * @author Dmitry Sulman
* @author Stephane Nicoll
* @since 4.0.0 * @since 4.0.0
*/ */
@AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class) @AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class)
@ -51,12 +53,39 @@ public final class RSocketMessagingAutoConfiguration {
RSocketMessageHandler messageHandler = new RSocketMessageHandler(); RSocketMessageHandler messageHandler = new RSocketMessageHandler();
messageHandler.setRSocketStrategies(rSocketStrategies); messageHandler.setRSocketStrategies(rSocketStrategies);
customizers.orderedStream().forEach((customizer) -> customizer.customize(messageHandler)); customizers.orderedStream().forEach((customizer) -> customizer.customize(messageHandler));
ControllerAdviceBean.findAnnotatedBeans(context)
.forEach((controllerAdviceBean) -> messageHandler
.registerMessagingAdvice(new ControllerAdviceBeanWrapper(controllerAdviceBean)));
return messageHandler; 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 static final class ControllerAdviceBeanWrapper implements MessagingAdviceBean {
private final ControllerAdviceBean adviceBean; private final ControllerAdviceBean adviceBean;

View File

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