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-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/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")); diff --git a/pom.xml b/pom.xml index a1f0dd40599d..7477681adc04 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 + + + +