Avoid CGLIB proxies on websocket/messaging configurations
This commit updates websocket and messaging configurations in order to not use CGLIB proxies anymore. The goal here is to allow support in native executables and to increase the consistency across the portfolio. Closes gh-26227
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -29,9 +29,10 @@ import org.springframework.util.CollectionUtils;
|
||||
* configure WebSocket request handling.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.0
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class DelegatingWebSocketConfiguration extends WebSocketConfigurationSupport {
|
||||
|
||||
private final List<WebSocketConfigurer> configurers = new ArrayList<>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -37,9 +37,10 @@ import org.springframework.util.CollectionUtils;
|
||||
* <p>This class is typically imported via {@link EnableWebSocketMessageBroker}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.0
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class DelegatingWebSocketMessageBrokerConfiguration extends WebSocketMessageBrokerConfigurationSupport {
|
||||
|
||||
private final List<WebSocketMessageBrokerConfigurer> configurers = new ArrayList<>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.web.servlet.HandlerMapping;
|
||||
* Configuration support for WebSocket request handling.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.0
|
||||
*/
|
||||
public class WebSocketConfigurationSupport {
|
||||
@@ -39,10 +40,10 @@ public class WebSocketConfigurationSupport {
|
||||
|
||||
|
||||
@Bean
|
||||
public HandlerMapping webSocketHandlerMapping() {
|
||||
public HandlerMapping webSocketHandlerMapping(@Nullable TaskScheduler defaultSockJsTaskScheduler) {
|
||||
ServletWebSocketHandlerRegistry registry = initHandlerRegistry();
|
||||
if (registry.requiresTaskScheduler()) {
|
||||
TaskScheduler scheduler = defaultSockJsTaskScheduler();
|
||||
TaskScheduler scheduler = defaultSockJsTaskScheduler;
|
||||
Assert.notNull(scheduler, "Expected default TaskScheduler bean");
|
||||
registry.setTaskScheduler(scheduler);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -19,15 +19,19 @@ package org.springframework.web.socket.config.annotation;
|
||||
import org.springframework.beans.factory.config.CustomScopeConfigurer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.messaging.simp.SimpSessionScope;
|
||||
import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler;
|
||||
import org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler;
|
||||
import org.springframework.messaging.simp.config.AbstractMessageBrokerConfiguration;
|
||||
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
|
||||
import org.springframework.messaging.simp.user.SimpUserRegistry;
|
||||
import org.springframework.messaging.support.AbstractSubscribableChannel;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.config.WebSocketMessageBrokerStats;
|
||||
@@ -46,6 +50,7 @@ import org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessage
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Artem Bilan
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class WebSocketMessageBrokerConfigurationSupport extends AbstractMessageBrokerConfiguration {
|
||||
@@ -55,9 +60,10 @@ public abstract class WebSocketMessageBrokerConfigurationSupport extends Abstrac
|
||||
|
||||
|
||||
@Override
|
||||
protected SimpAnnotationMethodMessageHandler createAnnotationMethodMessageHandler() {
|
||||
return new WebSocketAnnotationMethodMessageHandler(
|
||||
clientInboundChannel(), clientOutboundChannel(), brokerMessagingTemplate());
|
||||
protected SimpAnnotationMethodMessageHandler createAnnotationMethodMessageHandler(
|
||||
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel,
|
||||
SimpMessagingTemplate brokerMessagingTemplate) {
|
||||
return new WebSocketAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerMessagingTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,10 +76,11 @@ public abstract class WebSocketMessageBrokerConfigurationSupport extends Abstrac
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerMapping stompWebSocketHandlerMapping() {
|
||||
WebSocketHandler handler = decorateWebSocketHandler(subProtocolWebSocketHandler());
|
||||
public HandlerMapping stompWebSocketHandlerMapping(WebSocketHandler subProtocolWebSocketHandler,
|
||||
TaskScheduler messageBrokerTaskScheduler) {
|
||||
WebSocketHandler handler = decorateWebSocketHandler(subProtocolWebSocketHandler);
|
||||
WebMvcStompEndpointRegistry registry = new WebMvcStompEndpointRegistry(
|
||||
handler, getTransportRegistration(), messageBrokerTaskScheduler());
|
||||
handler, getTransportRegistration(), messageBrokerTaskScheduler);
|
||||
ApplicationContext applicationContext = getApplicationContext();
|
||||
if (applicationContext != null) {
|
||||
registry.setApplicationContext(applicationContext);
|
||||
@@ -83,8 +90,9 @@ public abstract class WebSocketMessageBrokerConfigurationSupport extends Abstrac
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketHandler subProtocolWebSocketHandler() {
|
||||
return new SubProtocolWebSocketHandler(clientInboundChannel(), clientOutboundChannel());
|
||||
public WebSocketHandler subProtocolWebSocketHandler(AbstractSubscribableChannel clientInboundChannel,
|
||||
AbstractSubscribableChannel clientOutboundChannel) {
|
||||
return new SubProtocolWebSocketHandler(clientInboundChannel, clientOutboundChannel);
|
||||
}
|
||||
|
||||
protected WebSocketHandler decorateWebSocketHandler(WebSocketHandler handler) {
|
||||
@@ -115,20 +123,17 @@ public abstract class WebSocketMessageBrokerConfigurationSupport extends Abstrac
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketMessageBrokerStats webSocketMessageBrokerStats() {
|
||||
AbstractBrokerMessageHandler relayBean = stompBrokerRelayMessageHandler();
|
||||
|
||||
// Ensure STOMP endpoints are registered
|
||||
stompWebSocketHandlerMapping();
|
||||
|
||||
public WebSocketMessageBrokerStats webSocketMessageBrokerStats(@Nullable AbstractBrokerMessageHandler stompBrokerRelayMessageHandler,
|
||||
WebSocketHandler subProtocolWebSocketHandler, TaskExecutor clientInboundChannelExecutor, TaskExecutor clientOutboundChannelExecutor,
|
||||
TaskScheduler messageBrokerTaskScheduler) {
|
||||
WebSocketMessageBrokerStats stats = new WebSocketMessageBrokerStats();
|
||||
stats.setSubProtocolWebSocketHandler((SubProtocolWebSocketHandler) subProtocolWebSocketHandler());
|
||||
if (relayBean instanceof StompBrokerRelayMessageHandler) {
|
||||
stats.setStompBrokerRelay((StompBrokerRelayMessageHandler) relayBean);
|
||||
stats.setSubProtocolWebSocketHandler((SubProtocolWebSocketHandler) subProtocolWebSocketHandler);
|
||||
if (stompBrokerRelayMessageHandler instanceof StompBrokerRelayMessageHandler) {
|
||||
stats.setStompBrokerRelay((StompBrokerRelayMessageHandler) stompBrokerRelayMessageHandler);
|
||||
}
|
||||
stats.setInboundChannelExecutor(clientInboundChannelExecutor());
|
||||
stats.setOutboundChannelExecutor(clientOutboundChannelExecutor());
|
||||
stats.setSockJsTaskScheduler(messageBrokerTaskScheduler());
|
||||
stats.setInboundChannelExecutor(clientInboundChannelExecutor);
|
||||
stats.setOutboundChannelExecutor(clientOutboundChannelExecutor);
|
||||
stats.setSockJsTaskScheduler(messageBrokerTaskScheduler);
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
@@ -67,6 +68,7 @@ import static org.mockito.Mockito.mock;
|
||||
* Test fixture for {@link WebSocketMessageBrokerConfigurationSupport}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class WebSocketMessageBrokerConfigurationSupportTests {
|
||||
|
||||
@@ -251,24 +253,25 @@ public class WebSocketMessageBrokerConfigurationSupportTests {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public AbstractSubscribableChannel clientInboundChannel() {
|
||||
public AbstractSubscribableChannel clientInboundChannel(TaskExecutor clientInboundChannelExecutor) {
|
||||
TestChannel channel = new TestChannel();
|
||||
channel.setInterceptors(super.clientInboundChannel().getInterceptors());
|
||||
channel.setInterceptors(super.clientInboundChannel(clientInboundChannelExecutor).getInterceptors());
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public AbstractSubscribableChannel clientOutboundChannel() {
|
||||
public AbstractSubscribableChannel clientOutboundChannel(TaskExecutor clientOutboundChannelExecutor) {
|
||||
TestChannel channel = new TestChannel();
|
||||
channel.setInterceptors(super.clientOutboundChannel().getInterceptors());
|
||||
channel.setInterceptors(super.clientOutboundChannel(clientOutboundChannelExecutor).getInterceptors());
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSubscribableChannel brokerChannel() {
|
||||
public AbstractSubscribableChannel brokerChannel(AbstractSubscribableChannel clientInboundChannel,
|
||||
AbstractSubscribableChannel clientOutboundChannel, TaskExecutor brokerChannelExecutor) {
|
||||
TestChannel channel = new TestChannel();
|
||||
channel.setInterceptors(super.brokerChannel().getInterceptors());
|
||||
channel.setInterceptors(super.brokerChannel(clientInboundChannel, clientOutboundChannel, brokerChannelExecutor).getInterceptors());
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.simp.annotation.SendToUser;
|
||||
@@ -59,6 +60,7 @@ import static org.springframework.web.socket.messaging.StompTextMessageBuilder.c
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
class StompWebSocketIntegrationTests extends AbstractWebSocketIntegrationTests {
|
||||
|
||||
@@ -331,13 +333,13 @@ class StompWebSocketIntegrationTests extends AbstractWebSocketIntegrationTests {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public AbstractSubscribableChannel clientInboundChannel() {
|
||||
public AbstractSubscribableChannel clientInboundChannel(TaskExecutor clientInboundChannelExecutor) {
|
||||
return new ExecutorSubscribableChannel(); // synchronous
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public AbstractSubscribableChannel clientOutboundChannel() {
|
||||
public AbstractSubscribableChannel clientOutboundChannel(TaskExecutor clientOutboundChannelExecutor) {
|
||||
return new ExecutorSubscribableChannel(); // synchronous
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user