Simplify RSocket client responder config
Now that responder RSocketStrategies also exposes responder strategies, AnnotationClientResponderConfigurer is reduced and no longer needs to be public. This commit folds it into RSocketMessageHandler as a nested class and exposes it as a ClientRSocketFactoryConfigurer through a static method that accepts the handlers to use. Effectively a shortcut for creating RSocketMessageHandler, giving it RSocketStrategies, calling afterPropertiesSet, and then the instance createResponder. See gh-23314
This commit is contained in:
@@ -30,7 +30,7 @@ import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.rsocket.annotation.support.AnnotationClientResponderConfigurer;
|
||||
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
@@ -165,14 +165,15 @@ public interface RSocketRequester {
|
||||
|
||||
/**
|
||||
* Callback to configure the {@code ClientRSocketFactory} directly.
|
||||
* <p>See {@link AnnotationClientResponderConfigurer} for configuring a
|
||||
* client side responder.
|
||||
* <p>See static factory method
|
||||
* {@link RSocketMessageHandler#clientResponder(Object...)} for
|
||||
* configuring a client side responder with annotated methods.
|
||||
* <p><strong>Note:</strong> Do not set {@link #dataMimeType(MimeType)}
|
||||
* and {@link #metadataMimeType(MimeType)} directly on the
|
||||
* {@code ClientRSocketFactory}. Use the shortcuts on this builder
|
||||
* instead since the created {@code RSocketRequester} needs to be aware
|
||||
* of those settings.
|
||||
* @see AnnotationClientResponderConfigurer
|
||||
* @see RSocketMessageHandler#clientResponder(Object...)
|
||||
*/
|
||||
RSocketRequester.Builder rsocketFactory(ClientRSocketFactoryConfigurer configurer);
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.messaging.rsocket.annotation.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.rsocket.RSocketFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.rsocket.ClientRSocketFactoryConfigurer;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ClientRSocketFactoryConfigurer} to configure and plug in a responder
|
||||
* that handles requests via annotated handler methods. Effectively a thin layer over
|
||||
* {@link RSocketMessageHandler} that provides a programmatic way to configure
|
||||
* it and obtain a responder via {@link RSocketMessageHandler#clientResponder()
|
||||
* clientResponder()}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.2
|
||||
*/
|
||||
public final class AnnotationClientResponderConfigurer implements ClientRSocketFactoryConfigurer {
|
||||
|
||||
private final List<Object> handlers = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private RSocketStrategies strategies;
|
||||
|
||||
|
||||
private AnnotationClientResponderConfigurer(List<Object> handlers) {
|
||||
for (Object obj : handlers) {
|
||||
this.handlers.add(obj instanceof Class ? BeanUtils.instantiateClass((Class<?>) obj) : obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure handlers to detect {@code @MessasgeMapping} handler methods on.
|
||||
* This is used to set {@link RSocketMessageHandler#setHandlers(List)}.
|
||||
*/
|
||||
public AnnotationClientResponderConfigurer handlers(Object... handlers) {
|
||||
this.handlers.addAll(Arrays.asList(handlers));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of ClientRSocketFactoryConfigurer
|
||||
|
||||
@Override
|
||||
public void configureWithStrategies(RSocketStrategies strategies) {
|
||||
this.strategies = strategies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(RSocketFactory.ClientRSocketFactory factory) {
|
||||
Assert.notEmpty(this.handlers, "No handlers");
|
||||
RSocketMessageHandler messageHandler = new RSocketMessageHandler();
|
||||
messageHandler.setHandlers(this.handlers);
|
||||
messageHandler.setRSocketStrategies(this.strategies);
|
||||
messageHandler.afterPropertiesSet();
|
||||
factory.acceptor(messageHandler.clientResponder());
|
||||
}
|
||||
|
||||
|
||||
// Static factory methods
|
||||
|
||||
/**
|
||||
* Create an {@code AnnotationClientResponderConfigurer} with the given handlers
|
||||
* to check for {@code @MessasgeMapping} handler methods.
|
||||
*/
|
||||
public static AnnotationClientResponderConfigurer withHandlers(Object... handlers) {
|
||||
return new AnnotationClientResponderConfigurer(Arrays.asList(handlers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@code AnnotationClientResponderConfigurer} to set up further.
|
||||
*/
|
||||
public static AnnotationClientResponderConfigurer create() {
|
||||
return new AnnotationClientResponderConfigurer(Collections.emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,10 +24,12 @@ import java.util.function.Function;
|
||||
|
||||
import io.rsocket.ConnectionSetupPayload;
|
||||
import io.rsocket.RSocket;
|
||||
import io.rsocket.RSocketFactory;
|
||||
import io.rsocket.SocketAcceptor;
|
||||
import io.rsocket.frame.FrameType;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
@@ -40,6 +42,7 @@ import org.springframework.messaging.handler.DestinationPatternsMessageCondition
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.handler.annotation.reactive.MessageMappingMessageHandler;
|
||||
import org.springframework.messaging.handler.invocation.reactive.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.messaging.rsocket.ClientRSocketFactoryConfigurer;
|
||||
import org.springframework.messaging.rsocket.DefaultMetadataExtractor;
|
||||
import org.springframework.messaging.rsocket.MetadataExtractor;
|
||||
import org.springframework.messaging.rsocket.RSocketRequester;
|
||||
@@ -324,10 +327,50 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
|
||||
Assert.notNull(strategies, "No RSocketStrategies. Was afterPropertiesSet not called?");
|
||||
RSocketRequester requester = RSocketRequester.wrap(rsocket, dataMimeType, metadataMimeType, strategies);
|
||||
|
||||
Assert.notNull(this.metadataExtractor, () -> "No MetadataExtractor. Was afterPropertiesSet not called?");
|
||||
Assert.state(this.metadataExtractor != null,
|
||||
() -> "No MetadataExtractor. Was afterPropertiesSet not called?");
|
||||
|
||||
Assert.state(getRouteMatcher() != null,
|
||||
() -> "No RouteMatcher. Was afterPropertiesSet not called?");
|
||||
|
||||
return new MessagingRSocket(dataMimeType, metadataMimeType, this.metadataExtractor, requester,
|
||||
this, getRouteMatcher(), strategies);
|
||||
}
|
||||
|
||||
|
||||
public static ClientRSocketFactoryConfigurer clientResponder(Object... handlers) {
|
||||
return new ResponderConfigurer(handlers);
|
||||
}
|
||||
|
||||
|
||||
private static final class ResponderConfigurer implements ClientRSocketFactoryConfigurer {
|
||||
|
||||
private final List<Object> handlers = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private RSocketStrategies strategies;
|
||||
|
||||
|
||||
private ResponderConfigurer(Object... handlers) {
|
||||
Assert.notEmpty(handlers, "No handlers");
|
||||
for (Object obj : handlers) {
|
||||
this.handlers.add(obj instanceof Class ? BeanUtils.instantiateClass((Class<?>) obj) : obj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureWithStrategies(RSocketStrategies strategies) {
|
||||
this.strategies = strategies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(RSocketFactory.ClientRSocketFactory factory) {
|
||||
RSocketMessageHandler handler = new RSocketMessageHandler();
|
||||
handler.setHandlers(this.handlers);
|
||||
handler.setRSocketStrategies(this.strategies);
|
||||
handler.afterPropertiesSet();
|
||||
factory.acceptor(handler.clientResponder());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.rsocket.annotation.ConnectMapping;
|
||||
import org.springframework.messaging.rsocket.annotation.support.AnnotationClientResponderConfigurer;
|
||||
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
@@ -111,7 +110,7 @@ public class RSocketServerToClientIntegrationTests {
|
||||
factory.metadataMimeType("text/plain");
|
||||
factory.setupPayload(ByteBufPayload.create("", connectionRoute));
|
||||
})
|
||||
.rsocketFactory(AnnotationClientResponderConfigurer.withHandlers(new ClientHandler()))
|
||||
.rsocketFactory(RSocketMessageHandler.clientResponder(new ClientHandler()))
|
||||
.rsocketStrategies(context.getBean(RSocketStrategies.class))
|
||||
.connectTcp("localhost", server.address().getPort())
|
||||
.block();
|
||||
|
||||
Reference in New Issue
Block a user