From 0b5da6b8c817504948d205899adba59edd6c4302 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Tue, 11 Mar 2025 17:44:45 +0100 Subject: [PATCH] refactor: replace direct dependencies with ObjectProvider in MCP transports Replace direct dependencies with ObjectProvider pattern in SSE transport auto-configurations. - Uses ObjectProvider for ObjectMapper and WebClient.Builder dependencies - Removes redundant @ConditionalOnMissingBean methods - Provides fallback instantiation when dependencies are not available Resolves #2440 Signed-off-by: Christian Tzolov --- ...eHttpClientTransportAutoConfiguration.java | 22 +++------- .../SseWebFluxTransportAutoConfiguration.java | 42 ++++--------------- 2 files changed, 15 insertions(+), 49 deletions(-) diff --git a/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseHttpClientTransportAutoConfiguration.java b/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseHttpClientTransportAutoConfiguration.java index 25c7d7e45fe..0fe02a9dc20 100644 --- a/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseHttpClientTransportAutoConfiguration.java +++ b/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseHttpClientTransportAutoConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.ai.autoconfigure.mcp.client.properties.McpClientCommonProperties; import org.springframework.ai.autoconfigure.mcp.client.properties.McpSseClientProperties; import org.springframework.ai.autoconfigure.mcp.client.properties.McpSseClientProperties.SseParameters; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -80,12 +81,15 @@ public class SseHttpClientTransportAutoConfiguration { *
  • ObjectMapper for JSON processing * * @param sseProperties the SSE client properties containing server configurations - * @param objectMapper the ObjectMapper for JSON serialization/deserialization + * @param objectMapperProvider the provider for ObjectMapper or a new instance if not + * available * @return list of named MCP transports */ @Bean public List mcpHttpClientTransports(McpSseClientProperties sseProperties, - ObjectMapper objectMapper) { + ObjectProvider objectMapperProvider) { + + ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new); List sseTransports = new ArrayList<>(); @@ -99,18 +103,4 @@ public List mcpHttpClientTransports(McpSseClientPropert return sseTransports; } - /** - * Creates the default ObjectMapper if none is provided. - * - *

    - * This ObjectMapper is used for JSON serialization and deserialization in the SSE - * transport implementation. - * @return the configured ObjectMapper instance - */ - @Bean - @ConditionalOnMissingBean - public ObjectMapper objectMapper() { - return new ObjectMapper(); - } - } diff --git a/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseWebFluxTransportAutoConfiguration.java b/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseWebFluxTransportAutoConfiguration.java index d92520e5a67..8c6496fc72e 100644 --- a/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseWebFluxTransportAutoConfiguration.java +++ b/auto-configurations/spring-ai-mcp-client/src/main/java/org/springframework/ai/autoconfigure/mcp/client/SseWebFluxTransportAutoConfiguration.java @@ -26,9 +26,9 @@ import org.springframework.ai.autoconfigure.mcp.client.properties.McpClientCommonProperties; import org.springframework.ai.autoconfigure.mcp.client.properties.McpSseClientProperties; import org.springframework.ai.autoconfigure.mcp.client.properties.McpSseClientProperties.SseParameters; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -73,17 +73,21 @@ public class SseWebFluxTransportAutoConfiguration { *

  • Server connection parameters from properties * * @param sseProperties the SSE client properties containing server configurations - * @param webClientBuilderTemplate the template WebClient.Builder to clone for each - * connection - * @param objectMapper the ObjectMapper for JSON serialization/deserialization + * @param webClientBuilderProvider the provider for WebClient.Builder + * @param objectMapperProvider the provider for ObjectMapper or a new instance if not + * available * @return list of named MCP transports */ @Bean public List webFluxClientTransports(McpSseClientProperties sseProperties, - WebClient.Builder webClientBuilderTemplate, ObjectMapper objectMapper) { + ObjectProvider webClientBuilderProvider, + ObjectProvider objectMapperProvider) { List sseTransports = new ArrayList<>(); + var webClientBuilderTemplate = webClientBuilderProvider.getIfAvailable(WebClient::builder); + var objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new); + for (Map.Entry serverParameters : sseProperties.getConnections().entrySet()) { var webClientBuilder = webClientBuilderTemplate.clone().baseUrl(serverParameters.getValue().url()); var transport = new WebFluxSseClientTransport(webClientBuilder, objectMapper); @@ -93,32 +97,4 @@ public List webFluxClientTransports(McpSseClientPropert return sseTransports; } - /** - * Creates the default WebClient.Builder if none is provided. - * - *

    - * This builder serves as a template for creating server-specific WebClient instances - * used in SSE transport implementation. - * @return the configured WebClient.Builder instance - */ - @Bean - @ConditionalOnMissingBean - public WebClient.Builder webClientBuilder() { - return WebClient.builder(); - } - - /** - * Creates the default ObjectMapper if none is provided. - * - *

    - * This ObjectMapper is used for JSON serialization and deserialization in the SSE - * transport implementation. - * @return the configured ObjectMapper instance - */ - @Bean - @ConditionalOnMissingBean - public ObjectMapper objectMapper() { - return new ObjectMapper(); - } - }