From 7ff8ba6a43f943aec879470b122667ffc88787a9 Mon Sep 17 00:00:00 2001
From: john <>
Date: Sat, 27 Jun 2026 21:11:33 +0800
Subject: [PATCH 1/2] Support Spring Boot 4 auto configuration
---
.../autoconfigure/SpringBoot3Condition.java | 16 ++-
.../dubbo-spring-boot-4-autoconfigure/pom.xml | 119 ++++++++++++++++++
.../DubboTriple4AutoConfiguration.java | 104 +++++++++++++++
.../autoconfigure/SpringBoot4Condition.java | 46 +++++++
.../main/resources/META-INF/spring.factories | 2 +
...ot.autoconfigure.AutoConfiguration.imports | 1 +
.../DubboTriple4AutoConfigurationTest.java | 91 ++++++++++++++
...Boot4DependencyCheckAutoConfiguration.java | 67 ++++++++++
.../autoconfigure/SpringBoot3Condition.java | 16 ++-
.../SpringBoot4OrLaterCondition.java | 46 +++++++
.../main/resources/META-INF/spring.factories | 3 +-
...ot.autoconfigure.AutoConfiguration.imports | 1 +
.../dubbo-spring-boot-starter4/pom.xml | 51 ++++++++
.../dubbo-spring-boot-starters/pom.xml | 12 ++
pom.xml | 17 +++
15 files changed, 589 insertions(+), 3 deletions(-)
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/pom.xml
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfiguration.java
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4Condition.java
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring.factories
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/test/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfigurationTest.java
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboSpringBoot4DependencyCheckAutoConfiguration.java
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4OrLaterCondition.java
create mode 100644 dubbo-spring-boot-project/dubbo-spring-boot-starters/dubbo-spring-boot-starter4/pom.xml
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java b/dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
index 489446f1d75c..c1c06a629e38 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
@@ -23,10 +23,24 @@
public class SpringBoot3Condition implements Condition {
- public static boolean IS_SPRING_BOOT_3 = SpringBootVersion.getVersion().charAt(0) >= '3';
+ public static boolean IS_SPRING_BOOT_3 = getSpringBootMajorVersion() == 3;
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return IS_SPRING_BOOT_3;
}
+
+ private static int getSpringBootMajorVersion() {
+ String version = SpringBootVersion.getVersion();
+ if (version == null || version.isEmpty()) {
+ return -1;
+ }
+ int separator = version.indexOf('.');
+ String majorVersion = separator < 0 ? version : version.substring(0, separator);
+ try {
+ return Integer.parseInt(majorVersion);
+ } catch (NumberFormatException ignored) {
+ return -1;
+ }
+ }
}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/pom.xml b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/pom.xml
new file mode 100644
index 000000000000..db5952d62b2e
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/pom.xml
@@ -0,0 +1,119 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-parent
+ ${revision}
+ ../../pom.xml
+
+
+ dubbo-spring-boot-4-autoconfigure
+ jar
+ Apache Dubbo Spring Boot 4 Auto-Configure
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot-4.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ true
+
+
+ org.springframework.boot
+ spring-boot-tomcat
+ true
+
+
+
+
+ org.apache.dubbo
+ dubbo
+ ${project.version}
+ true
+
+
+
+ org.apache.dubbo
+ dubbo-triple-servlet
+ ${project.version}
+ true
+
+
+
+ org.apache.dubbo
+ dubbo-triple-websocket
+ ${project.version}
+ true
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ provided
+
+
+
+ jakarta.websocket
+ jakarta.websocket-api
+ provided
+
+
+
+ jakarta.websocket
+ jakarta.websocket-client-api
+ provided
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework
+ spring-web
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ 17
+
+
+
+
+
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfiguration.java b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfiguration.java
new file mode 100644
index 000000000000..54dbe31b3f7d
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfiguration.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.apache.dubbo.spring.boot.autoconfigure;
+
+import org.apache.dubbo.rpc.protocol.tri.ServletExchanger;
+import org.apache.dubbo.rpc.protocol.tri.servlet.jakarta.TripleFilter;
+import org.apache.dubbo.rpc.protocol.tri.websocket.jakarta.TripleWebSocketFilter;
+
+import jakarta.servlet.Filter;
+import org.apache.coyote.ProtocolHandler;
+import org.apache.coyote.UpgradeProtocol;
+import org.apache.coyote.http2.Http2Protocol;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
+import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+@Conditional(SpringBoot4Condition.class)
+public class DubboTriple4AutoConfiguration {
+
+ public static final String SERVLET_PREFIX = "dubbo.protocol.triple.servlet";
+
+ public static final String WEBSOCKET_PREFIX = "dubbo.protocol.triple.websocket";
+
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(Filter.class)
+ @ConditionalOnWebApplication(type = Type.SERVLET)
+ @ConditionalOnProperty(prefix = SERVLET_PREFIX, name = "enabled", havingValue = "true")
+ public static class TripleServletConfiguration {
+
+ @Bean
+ public FilterRegistrationBean tripleProtocolFilter(
+ @Value("${" + SERVLET_PREFIX + ".filter-url-patterns:/*}") String[] urlPatterns,
+ @Value("${" + SERVLET_PREFIX + ".filter-order:-1000000}") int order,
+ @Value("${server.port:8080}") int serverPort) {
+ ServletExchanger.bindServerPort(serverPort);
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new TripleFilter());
+ registrationBean.addUrlPatterns(urlPatterns);
+ registrationBean.setOrder(order);
+ return registrationBean;
+ }
+
+ @Bean
+ @ConditionalOnClass(Http2Protocol.class)
+ @ConditionalOnProperty(prefix = SERVLET_PREFIX, name = "max-concurrent-streams")
+ public WebServerFactoryCustomizer tripleTomcatHttp2Customizer(
+ @Value("${" + SERVLET_PREFIX + ".max-concurrent-streams}") int maxConcurrentStreams) {
+ return factory -> factory.addConnectorCustomizers(connector -> {
+ ProtocolHandler handler = connector.getProtocolHandler();
+ for (UpgradeProtocol upgradeProtocol : handler.findUpgradeProtocols()) {
+ if (upgradeProtocol instanceof Http2Protocol) {
+ Http2Protocol protocol = (Http2Protocol) upgradeProtocol;
+ int value = maxConcurrentStreams <= 0 ? Integer.MAX_VALUE : maxConcurrentStreams;
+ protocol.setMaxConcurrentStreams(value);
+ protocol.setMaxConcurrentStreamExecution(value);
+ }
+ }
+ });
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(Filter.class)
+ @ConditionalOnWebApplication(type = Type.SERVLET)
+ @ConditionalOnProperty(prefix = WEBSOCKET_PREFIX, name = "enabled", havingValue = "true")
+ public static class TripleWebSocketConfiguration {
+
+ @Bean
+ public FilterRegistrationBean tripleWebSocketFilter(
+ @Value("${" + WEBSOCKET_PREFIX + ".filter-url-patterns:/*}") String[] urlPatterns,
+ @Value("${" + WEBSOCKET_PREFIX + ".filter-order:-1000000}") int order,
+ @Value("${server.port:8080}") int serverPort) {
+ ServletExchanger.bindServerPort(serverPort);
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new TripleWebSocketFilter());
+ registrationBean.addUrlPatterns(urlPatterns);
+ registrationBean.setOrder(order);
+ return registrationBean;
+ }
+ }
+}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4Condition.java b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4Condition.java
new file mode 100644
index 000000000000..c7b2822475e4
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4Condition.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.apache.dubbo.spring.boot.autoconfigure;
+
+import org.springframework.boot.SpringBootVersion;
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class SpringBoot4Condition implements Condition {
+
+ public static boolean IS_SPRING_BOOT_4 = getSpringBootMajorVersion() >= 4;
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return IS_SPRING_BOOT_4;
+ }
+
+ private static int getSpringBootMajorVersion() {
+ String version = SpringBootVersion.getVersion();
+ if (version == null || version.isEmpty()) {
+ return -1;
+ }
+ int separator = version.indexOf('.');
+ String majorVersion = separator < 0 ? version : version.substring(0, separator);
+ try {
+ return Integer.parseInt(majorVersion);
+ } catch (NumberFormatException ignored) {
+ return -1;
+ }
+ }
+}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring.factories b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000000..fdeaac16bb62
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.dubbo.spring.boot.autoconfigure.DubboTriple4AutoConfiguration
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000000..0beea7a9d10f
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+org.apache.dubbo.spring.boot.autoconfigure.DubboTriple4AutoConfiguration
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/test/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfigurationTest.java b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/test/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfigurationTest.java
new file mode 100644
index 000000000000..2ec80bf672c8
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure/src/test/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple4AutoConfigurationTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.apache.dubbo.spring.boot.autoconfigure;
+
+import org.apache.dubbo.rpc.protocol.tri.servlet.jakarta.TripleFilter;
+import org.apache.dubbo.rpc.protocol.tri.websocket.jakarta.TripleWebSocketFilter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DubboTriple4AutoConfigurationTest {
+
+ private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(DubboTriple4AutoConfiguration.class));
+
+ @Test
+ void registersTripleServletFilterWhenEnabled() {
+ this.contextRunner
+ .withPropertyValues(
+ "dubbo.protocol.triple.servlet.enabled=true",
+ "dubbo.protocol.triple.servlet.filter-url-patterns=/tri/*",
+ "dubbo.protocol.triple.servlet.filter-order=10",
+ "server.port=9090")
+ .run((context) -> {
+ assertThat(context).hasBean("tripleProtocolFilter");
+ FilterRegistrationBean> registrationBean =
+ context.getBean("tripleProtocolFilter", FilterRegistrationBean.class);
+ assertThat(registrationBean.getFilter()).isInstanceOf(TripleFilter.class);
+ assertThat(registrationBean.getUrlPatterns()).containsExactly("/tri/*");
+ assertThat(registrationBean.getOrder()).isEqualTo(10);
+ });
+ }
+
+ @Test
+ void registersTripleWebSocketFilterWhenEnabled() {
+ this.contextRunner
+ .withPropertyValues(
+ "dubbo.protocol.triple.websocket.enabled=true",
+ "dubbo.protocol.triple.websocket.filter-url-patterns=/tri-ws/*",
+ "dubbo.protocol.triple.websocket.filter-order=20",
+ "server.port=9091")
+ .run((context) -> {
+ assertThat(context).hasBean("tripleWebSocketFilter");
+ FilterRegistrationBean> registrationBean =
+ context.getBean("tripleWebSocketFilter", FilterRegistrationBean.class);
+ assertThat(registrationBean.getFilter()).isInstanceOf(TripleWebSocketFilter.class);
+ assertThat(registrationBean.getUrlPatterns()).containsExactly("/tri-ws/*");
+ assertThat(registrationBean.getOrder()).isEqualTo(20);
+ });
+ }
+
+ @Test
+ void doesNotRegisterTripleFiltersByDefault() {
+ this.contextRunner.run((context) -> {
+ assertThat(context).doesNotHaveBean("tripleProtocolFilter");
+ assertThat(context).doesNotHaveBean("tripleWebSocketFilter");
+ });
+ }
+
+ @Test
+ void registersTomcatHttp2CustomizerWhenMaxConcurrentStreamsIsConfigured() {
+ this.contextRunner
+ .withPropertyValues(
+ "dubbo.protocol.triple.servlet.enabled=true",
+ "dubbo.protocol.triple.servlet.max-concurrent-streams=128")
+ .run((context) -> {
+ assertThat(context).hasBean("tripleTomcatHttp2Customizer");
+ assertThat(context.getBean("tripleTomcatHttp2Customizer"))
+ .isInstanceOf(WebServerFactoryCustomizer.class);
+ });
+ }
+}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboSpringBoot4DependencyCheckAutoConfiguration.java b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboSpringBoot4DependencyCheckAutoConfiguration.java
new file mode 100644
index 000000000000..6e5a7db4ea5e
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboSpringBoot4DependencyCheckAutoConfiguration.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.apache.dubbo.spring.boot.autoconfigure;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+@Conditional(SpringBoot4OrLaterCondition.class)
+public class DubboSpringBoot4DependencyCheckAutoConfiguration {
+
+ public static final String SERVLET_PREFIX = "dubbo.protocol.triple.servlet";
+
+ public static final String WEBSOCKET_PREFIX = "dubbo.protocol.triple.websocket";
+
+ public static final String JAKARTA_SERVLET_FILTER = "jakarta.servlet.Filter";
+
+ public static final String DUBBO_TRIPLE_4_AUTOCONFIGURATION =
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboTriple4AutoConfiguration";
+
+ private static final String SPRING_BOOT_4_DEPENDENCY_CHECK_WARNING =
+ "Couldn't enable servlet support for triple at SpringBoot4+: Missing dubbo-spring-boot-4-autoconfigure";
+
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(name = JAKARTA_SERVLET_FILTER)
+ @ConditionalOnWebApplication(type = Type.SERVLET)
+ @ConditionalOnProperty(prefix = SERVLET_PREFIX, name = "enabled", havingValue = "true")
+ @ConditionalOnMissingClass(DUBBO_TRIPLE_4_AUTOCONFIGURATION)
+ public static class tripleProtocolFilterDependencyCheckConfiguration {
+ @Bean
+ public Object tripleProtocolFilterDependencyCheck() {
+ throw new IllegalStateException(SPRING_BOOT_4_DEPENDENCY_CHECK_WARNING);
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(name = JAKARTA_SERVLET_FILTER)
+ @ConditionalOnWebApplication(type = Type.SERVLET)
+ @ConditionalOnProperty(prefix = WEBSOCKET_PREFIX, name = "enabled", havingValue = "true")
+ @ConditionalOnMissingClass(DUBBO_TRIPLE_4_AUTOCONFIGURATION)
+ public static class tripleWebSocketFilterDependencyCheckConfiguration {
+ @Bean
+ public Object tripleWebSocketFilterDependencyCheck() {
+ throw new IllegalStateException(SPRING_BOOT_4_DEPENDENCY_CHECK_WARNING);
+ }
+ }
+}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
index 489446f1d75c..c1c06a629e38 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot3Condition.java
@@ -23,10 +23,24 @@
public class SpringBoot3Condition implements Condition {
- public static boolean IS_SPRING_BOOT_3 = SpringBootVersion.getVersion().charAt(0) >= '3';
+ public static boolean IS_SPRING_BOOT_3 = getSpringBootMajorVersion() == 3;
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return IS_SPRING_BOOT_3;
}
+
+ private static int getSpringBootMajorVersion() {
+ String version = SpringBootVersion.getVersion();
+ if (version == null || version.isEmpty()) {
+ return -1;
+ }
+ int separator = version.indexOf('.');
+ String majorVersion = separator < 0 ? version : version.substring(0, separator);
+ try {
+ return Integer.parseInt(majorVersion);
+ } catch (NumberFormatException ignored) {
+ return -1;
+ }
+ }
}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4OrLaterCondition.java b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4OrLaterCondition.java
new file mode 100644
index 000000000000..e672b1e991b8
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/SpringBoot4OrLaterCondition.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.apache.dubbo.spring.boot.autoconfigure;
+
+import org.springframework.boot.SpringBootVersion;
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class SpringBoot4OrLaterCondition implements Condition {
+
+ public static boolean IS_SPRING_BOOT_4_OR_LATER = getSpringBootMajorVersion() >= 4;
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return IS_SPRING_BOOT_4_OR_LATER;
+ }
+
+ private static int getSpringBootMajorVersion() {
+ String version = SpringBootVersion.getVersion();
+ if (version == null || version.isEmpty()) {
+ return -1;
+ }
+ int separator = version.indexOf('.');
+ String majorVersion = separator < 0 ? version : version.substring(0, separator);
+ try {
+ return Integer.parseInt(majorVersion);
+ } catch (NumberFormatException ignored) {
+ return -1;
+ }
+ }
+}
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
index 5256a723cd8e..a72642e67b01 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -9,4 +9,5 @@ org.apache.dubbo.spring.boot.autoconfigure.observability.DubboObservationAutoCon
org.apache.dubbo.spring.boot.autoconfigure.observability.brave.BraveAutoConfiguration,\
org.apache.dubbo.spring.boot.autoconfigure.observability.zipkin.ZipkinAutoConfiguration,\
org.apache.dubbo.spring.boot.autoconfigure.observability.otlp.OtlpAutoConfiguration,\
-org.apache.dubbo.spring.boot.autoconfigure.DubboSpringBoot3DependencyCheckAutoConfiguration
+org.apache.dubbo.spring.boot.autoconfigure.DubboSpringBoot3DependencyCheckAutoConfiguration,\
+org.apache.dubbo.spring.boot.autoconfigure.DubboSpringBoot4DependencyCheckAutoConfiguration
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index c92a1ed528c2..cd23d61b1004 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -9,3 +9,4 @@ org.apache.dubbo.spring.boot.autoconfigure.observability.brave.BraveAutoConfigur
org.apache.dubbo.spring.boot.autoconfigure.observability.zipkin.ZipkinAutoConfiguration
org.apache.dubbo.spring.boot.autoconfigure.observability.otlp.OtlpAutoConfiguration
org.apache.dubbo.spring.boot.autoconfigure.DubboSpringBoot3DependencyCheckAutoConfiguration
+org.apache.dubbo.spring.boot.autoconfigure.DubboSpringBoot4DependencyCheckAutoConfiguration
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-starters/dubbo-spring-boot-starter4/pom.xml b/dubbo-spring-boot-project/dubbo-spring-boot-starters/dubbo-spring-boot-starter4/pom.xml
new file mode 100644
index 000000000000..31054d9dd13b
--- /dev/null
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-starters/dubbo-spring-boot-starter4/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-spring-boot-starters
+ ${revision}
+ ../pom.xml
+
+
+ dubbo-spring-boot-starter4
+ jar
+ Apache Dubbo Spring Boot 4 Starter
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ true
+
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-autoconfigure
+ ${project.version}
+
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-4-autoconfigure
+ ${project.version}
+
+
+
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-starters/pom.xml b/dubbo-spring-boot-project/dubbo-spring-boot-starters/pom.xml
index d3bcc63bcb0c..c934c77d1e13 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-starters/pom.xml
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-starters/pom.xml
@@ -41,4 +41,16 @@
dubbo-observability-spring-boot-starter
+
+
+ jdk-version-ge-17
+
+ [17,)
+
+
+ dubbo-spring-boot-starter4
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 56eedbd9b494..27b1ec8cdb88 100644
--- a/pom.xml
+++ b/pom.xml
@@ -167,6 +167,7 @@
6.2.18
6.5.10
3.5.14
+ 4.0.6
4.33.4
@@ -498,6 +499,7 @@
dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure
+ dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure
dubbo-plugin/dubbo-spring6-security
dubbo-plugin/dubbo-mutiny
@@ -649,6 +651,7 @@
release
dubbo-spring-boot-project/dubbo-spring-boot-3-autoconfigure
+ dubbo-spring-boot-project/dubbo-spring-boot-4-autoconfigure
dubbo-plugin/dubbo-spring6-security
dubbo-plugin/dubbo-plugin-loom
dubbo-plugin/dubbo-mutiny
@@ -1211,5 +1214,19 @@
+
+ spring-boot-4
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot-4.version}
+ pom
+ import
+
+
+
+
From 61235c2a1ed01c4bd2689b750ba2d174e16f9a8d Mon Sep 17 00:00:00 2001
From: john <>
Date: Sat, 27 Jun 2026 22:22:57 +0800
Subject: [PATCH 2/2] Add Spring Boot 4 artifacts to dependency metadata
---
.artifacts | 2 ++
dubbo-distribution/dubbo-bom/pom.xml | 10 ++++++++++
dubbo-test/dubbo-dependencies-all/pom.xml | 10 ++++++++++
.../java/org/apache/dubbo/dependency/FileTest.java | 2 ++
4 files changed, 24 insertions(+)
diff --git a/.artifacts b/.artifacts
index 28b0249adb27..3f61d8435cac 100644
--- a/.artifacts
+++ b/.artifacts
@@ -95,6 +95,7 @@ dubbo-spring-boot-actuator-autoconfigure
dubbo-spring-boot-actuator-compatible
dubbo-spring-boot-autoconfigure
dubbo-spring-boot-3-autoconfigure
+dubbo-spring-boot-4-autoconfigure
dubbo-spring-boot-autoconfigure-compatible
dubbo-spring-boot-actuator-autoconfigure-compatible
dubbo-spring-boot-compatible
@@ -103,6 +104,7 @@ dubbo-tracing-otel-zipkin-spring-boot-starter
dubbo-tracing-otel-otlp-spring-boot-starter
dubbo-observability-spring-boot-starter
dubbo-spring-boot-starter
+dubbo-spring-boot-starter4
dubbo-spring-boot-starters
dubbo-spring-boot-interceptor
dubbo-nacos-spring-boot-starter
diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml
index d6994783575e..108df3d7ccf7 100644
--- a/dubbo-distribution/dubbo-bom/pom.xml
+++ b/dubbo-distribution/dubbo-bom/pom.xml
@@ -498,6 +498,11 @@
dubbo-spring-boot-3-autoconfigure
${project.version}
+
+ org.apache.dubbo
+ dubbo-spring-boot-4-autoconfigure
+ ${project.version}
+
org.apache.dubbo
dubbo-spring-boot-compatible
@@ -519,6 +524,11 @@
dubbo-spring-boot-starter
${project.version}
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter4
+ ${project.version}
+
org.apache.dubbo
dubbo-spring-boot
diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml
index 9d5b67d66efb..59351721bd47 100644
--- a/dubbo-test/dubbo-dependencies-all/pom.xml
+++ b/dubbo-test/dubbo-dependencies-all/pom.xml
@@ -499,6 +499,16 @@
dubbo-spring-boot-3-autoconfigure
${project.version}
+
+ org.apache.dubbo
+ dubbo-spring-boot-4-autoconfigure
+ ${project.version}
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter4
+ ${project.version}
+
diff --git a/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java b/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java
index fdc0d7d95944..92f10f521711 100644
--- a/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java
+++ b/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java
@@ -57,6 +57,8 @@ class FileTest {
ignoredModules.add(Pattern.compile("dubbo-config-spring6"));
ignoredModules.add(Pattern.compile("dubbo-spring6-security"));
ignoredModules.add(Pattern.compile("dubbo-spring-boot-3-autoconfigure"));
+ ignoredModules.add(Pattern.compile("dubbo-spring-boot-4-autoconfigure"));
+ ignoredModules.add(Pattern.compile("dubbo-spring-boot-starter4"));
ignoredModules.add(Pattern.compile("dubbo-plugin-loom.*"));
ignoredModules.add(Pattern.compile("dubbo-mutiny.*"));
ignoredModules.add(Pattern.compile("dubbo-mcp"));