diff --git a/build.gradle.kts b/build.gradle.kts
index d32e72079..b853e867c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -60,7 +60,7 @@ recipeDependencies {
parserClasspath("org.springframework.data:spring-data-jpa:2.3.+")
parserClasspath("org.springframework.data:spring-data-jpa:3.0.+")
parserClasspath("org.springframework.data:spring-data-rest-webmvc:3.1.+")
- parserClasspath("org.springframework.data:spring-data-mongodb:2.2.+")
+ parserClasspath("org.springframework.data:spring-data-mongodb:5.0.6")
parserClasspath("org.mongodb:mongo-java-driver:3.12.+")
parserClasspath("org.springframework.batch:spring-batch-core:4.+")
@@ -170,6 +170,7 @@ recipeDependencies {
testParserClasspath("org.springframework.data:spring-data-jpa:3.4.7")
testParserClasspath("org.springframework.data:spring-data-commons:3.0.+")
testParserClasspath("org.springframework.data:spring-data-mongodb:2.2.+")
+ testParserClasspath("org.springframework.data:spring-data-mongodb:5.0.6")
testParserClasspath("org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE")
diff --git a/src/main/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartup.java b/src/main/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartup.java
new file mode 100644
index 000000000..8bef99054
--- /dev/null
+++ b/src/main/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartup.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * 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.openrewrite.java.spring.data;
+
+import lombok.Getter;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Preconditions;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.java.AnnotationMatcher;
+import org.openrewrite.java.JavaIsoVisitor;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.java.JavaTemplate;
+import org.openrewrite.java.VariableNameUtils;
+import org.openrewrite.java.search.FindMethods;
+import org.openrewrite.java.search.UsesType;
+import org.openrewrite.java.service.AnnotationService;
+import org.openrewrite.java.tree.Expression;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.JavaType;
+import org.openrewrite.java.tree.Statement;
+import org.openrewrite.java.tree.TypeUtils;
+import org.openrewrite.marker.SearchResult;
+
+import java.util.List;
+
+public class PreserveDefaultMessageListenerContainerStartup extends Recipe {
+
+ private static final String LISTENER_CONTAINER =
+ "org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer";
+
+ private static final AnnotationMatcher BEAN_MATCHER =
+ new AnnotationMatcher("@org.springframework.context.annotation.Bean");
+
+ private static final String SET_AUTO_STARTUP_PATTERN =
+ LISTENER_CONTAINER + " setAutoStartup(boolean)";
+
+ private static final String MANUAL_REVIEW_MESSAGE =
+ "Unable to safely preserve DefaultMessageListenerContainer startup behavior. " +
+ "Configure setAutoStartup(false) manually.";
+
+ @Getter
+ final String displayName =
+ "Preserve manual MongoDB listener container startup";
+
+ @Getter
+ final String description =
+ "Preserve the Spring Data MongoDB 4.x startup behavior of Spring-managed " +
+ "`DefaultMessageListenerContainer` beans by explicitly disabling automatic startup.";
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ return Preconditions.check(
+ new UsesType<>(LISTENER_CONTAINER, false),
+ new JavaIsoVisitor() {
+ @Override
+ public J.MethodDeclaration visitMethodDeclaration(
+ J.MethodDeclaration method,
+ ExecutionContext ctx) {
+
+ J.MethodDeclaration m =
+ super.visitMethodDeclaration(method, ctx);
+
+ if (!isListenerContainerBean(m) ||
+ m.getBody() == null ||
+ hasExplicitAutoStartup(m)) {
+ return m;
+ }
+
+ J.VariableDeclarations containerVariable =
+ findContainerVariable(m);
+
+ J.Return returnStatement =
+ findReturnStatement(m);
+
+ if (containerVariable != null &&
+ returnStatement != null &&
+ returnsVariable(
+ returnStatement,
+ containerVariable
+ )) {
+
+ return addAutoStartupFalse(
+ m,
+ returnStatement,
+ ctx
+ );
+ }
+
+ if (returnStatement != null &&
+ isNewListenerContainer(
+ returnStatement.getExpression()
+ )) {
+
+ return replaceDirectReturn(
+ m,
+ returnStatement,
+ ctx
+ );
+ }
+
+ return markForManualReview(m);
+ }
+
+ private boolean isListenerContainerBean(
+ J.MethodDeclaration method) {
+
+ return service(AnnotationService.class)
+ .matches(getCursor(), BEAN_MATCHER) &&
+ method.getReturnTypeExpression() != null &&
+ TypeUtils.isAssignableTo(
+ LISTENER_CONTAINER,
+ method.getReturnTypeExpression()
+ .getType()
+ );
+ }
+
+ private J.MethodDeclaration addAutoStartupFalse(
+ J.MethodDeclaration method,
+ J.Return returnStatement,
+ ExecutionContext ctx) {
+
+ return JavaTemplate.builder(
+ "#{any(" +
+ LISTENER_CONTAINER +
+ ")}.setAutoStartup(false);"
+ )
+ .contextSensitive()
+ .javaParser(javaParser(ctx))
+ .build()
+ .apply(
+ updateCursor(method),
+ returnStatement.getCoordinates()
+ .before(),
+ returnStatement.getExpression()
+ );
+ }
+
+ private J.MethodDeclaration replaceDirectReturn(
+ J.MethodDeclaration method,
+ J.Return returnStatement,
+ ExecutionContext ctx) {
+
+ Expression expression =
+ returnStatement.getExpression();
+
+ String variableName =
+ VariableNameUtils.generateVariableName(
+ "container",
+ getCursor(),
+ VariableNameUtils.GenerationStrategy
+ .INCREMENT_NUMBER
+ );
+
+ return JavaTemplate.builder(
+ "DefaultMessageListenerContainer " +
+ variableName +
+ " = #{any(" +
+ LISTENER_CONTAINER +
+ ")};\n" +
+ variableName +
+ ".setAutoStartup(false);\n" +
+ "return " +
+ variableName +
+ ";"
+ )
+ .contextSensitive()
+ .imports(LISTENER_CONTAINER)
+ .javaParser(javaParser(ctx))
+ .build()
+ .apply(
+ updateCursor(method),
+ returnStatement.getCoordinates()
+ .replace(),
+ expression
+ );
+ }
+
+ private JavaParser.Builder, ?> javaParser(
+ ExecutionContext ctx) {
+
+ return JavaParser.fromJavaVersion()
+ .classpathFromResources(
+ ctx,
+ "spring-data-mongodb-5.0",
+ "spring-context-6"
+ );
+ }
+ }
+ );
+ }
+
+ private static boolean hasExplicitAutoStartup(
+ J.MethodDeclaration method) {
+
+ return !FindMethods.find(
+ method,
+ SET_AUTO_STARTUP_PATTERN
+ ).isEmpty();
+ }
+
+ private static J.VariableDeclarations findContainerVariable(
+ J.MethodDeclaration method) {
+
+ if (method.getBody() == null) {
+ return null;
+ }
+
+ for (Statement statement :
+ method.getBody().getStatements()) {
+
+ if (!(statement instanceof J.VariableDeclarations)) {
+ continue;
+ }
+
+ J.VariableDeclarations declarations =
+ (J.VariableDeclarations) statement;
+
+ if (TypeUtils.isAssignableTo(
+ LISTENER_CONTAINER,
+ declarations.getType()) &&
+ declarations.getVariables().size() == 1 &&
+ isNewListenerContainer(
+ declarations.getVariables()
+ .get(0)
+ .getInitializer()
+ )) {
+
+ return declarations;
+ }
+ }
+
+ return null;
+ }
+
+ private static J.Return findReturnStatement(
+ J.MethodDeclaration method) {
+
+ if (method.getBody() == null) {
+ return null;
+ }
+
+ List statements =
+ method.getBody().getStatements();
+
+ for (int i = statements.size() - 1; i >= 0; i--) {
+ Statement statement = statements.get(i);
+
+ if (statement instanceof J.Return) {
+ return (J.Return) statement;
+ }
+ }
+
+ return null;
+ }
+
+ private static boolean returnsVariable(
+ J.Return returnStatement,
+ J.VariableDeclarations declarations) {
+
+ if (!(returnStatement.getExpression()
+ instanceof J.Identifier)) {
+ return false;
+ }
+
+ J.Identifier returnedIdentifier =
+ (J.Identifier) returnStatement.getExpression();
+
+ return declarations.getVariables().stream()
+ .map(variable ->
+ variable.getName().getSimpleName())
+ .anyMatch(
+ returnedIdentifier
+ .getSimpleName()::equals
+ );
+ }
+
+ private static boolean isNewListenerContainer(
+ Expression expression) {
+
+ if (!(expression instanceof J.NewClass)) {
+ return false;
+ }
+
+ JavaType type =
+ ((J.NewClass) expression).getType();
+
+ return TypeUtils.isAssignableTo(
+ LISTENER_CONTAINER,
+ type
+ );
+ }
+
+ private static J.MethodDeclaration markForManualReview(
+ J.MethodDeclaration method) {
+
+ List annotations =
+ method.getLeadingAnnotations();
+
+ return method.withLeadingAnnotations(
+ org.openrewrite.internal.ListUtils.map(
+ annotations,
+ annotation ->
+ TypeUtils.isOfClassType(
+ annotation.getType(),
+ "org.springframework.context.annotation.Bean"
+ ) ?
+ SearchResult.found(
+ annotation,
+ MANUAL_REVIEW_MESSAGE
+ ) :
+ annotation
+ )
+ );
+ }
+}
diff --git a/src/main/resources/META-INF/rewrite/classpath.tsv.gz b/src/main/resources/META-INF/rewrite/classpath.tsv.gz
index 4bee30898..f78b5c077 100644
Binary files a/src/main/resources/META-INF/rewrite/classpath.tsv.gz and b/src/main/resources/META-INF/rewrite/classpath.tsv.gz differ
diff --git a/src/main/resources/META-INF/rewrite/recipes.csv b/src/main/resources/META-INF/rewrite/recipes.csv
index fe67042e8..56889dffe 100644
--- a/src/main/resources/META-INF/rewrite/recipes.csv
+++ b/src/main/resources/META-INF/rewrite/recipes.csv
@@ -191,7 +191,7 @@ maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.Re
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.SpringBootProperties_4_0,Migrate Spring Boot properties to 4.0,Migrate properties found in `application.properties` and `application.yml`.,155,,,,Boot4,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.SpringBootProperties_4_1,Migrate Spring Boot properties to 4.1,Migrate properties found in `application.properties` and `application.yml`.,6,,,,Boot4,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.UnwrapMockAndSpyBeanContainers,Unwrap `@MockBeans` and `@SpyBeans` container annotations,Replaces class-level `@MockBeans` and `@SpyBeans` container annotations with a single class-level `@MockBean` or `@SpyBean` annotation with a merged `types` attribute for compatibility with `@MockitoBean`.,1,,,,Boot4,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0,Migrate to Spring Boot 4.0,"Migrate applications to the latest Spring Boot 4.0 release. This recipe will modify an application's build files, make changes to deprecated/preferred APIs.",4386,,,,Boot4,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0,Migrate to Spring Boot 4.0,"Migrate applications to the latest Spring Boot 4.0 release. This recipe will modify an application's build files, make changes to deprecated/preferred APIs.",4385,,,,Boot4,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.cloud2022.AddLoggingPatternLevelForSleuth,Add logging.pattern.level for traceId and spanId,"Add `logging.pattern.level` for traceId and spanId which was previously set by default, if not already set.",1,,,,Spring Cloud 2022,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.cloud2022.DependencyUpgrades,Upgrade dependencies to Spring Cloud 2022,Upgrade dependencies to Spring Cloud 2022 from prior 2021.x version.,11,,,,Spring Cloud 2022,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.cloud2022.MigrateCloudSleuthToMicrometerTracing,Migrate Spring Cloud Sleuth 3.1 to Micrometer Tracing 1.0,Spring Cloud Sleuth has been discontinued and only compatible with Spring Boot 2.x.,29,,,,Spring Cloud 2022,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
@@ -218,14 +218,15 @@ maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.Mig
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.MigrateQueryToNativeQuery,Replace `@Query` annotation by `@NativeQuery` when possible,Replace `@Query` annotation by `@NativeQuery` when `nativeQuery = true`. `@NativeQuery` was introduced in Spring Data JPA 3.4.,1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.MigrateQuerydslJpaRepository,Use `QuerydslPredicateExecutor`,"`QuerydslJpaRepository` was deprecated in Spring Data 2.1.",1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.MigrateRepositoryRestConfigurerAdapter,Replace `RepositoryRestConfigurerAdapter` with `RepositoryRestConfigurer`,"Since 3.1, implement RepositoryRestConfigurer directly.",1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.PreserveDefaultMessageListenerContainerStartup,Preserve manual MongoDB listener container startup,Preserve the Spring Data MongoDB 4.x startup behavior of Spring-managed `DefaultMessageListenerContainer` beans by explicitly disabling automatic startup.,1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.RefactorSimpleMongoDbFactory,Use `new SimpleMongoClientDbFactory(String)`,Replace usage of deprecated `new SimpleMongoDbFactory(new MongoClientURI(String))` with `new SimpleMongoClientDbFactory(String)`.,1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringDataMongoDb_5_0,Migrate to Spring Data MongoDB 5.0,"Align explicitly versioned Spring Data MongoDB and supported MongoDB JVM driver dependencies with Spring Data MongoDB 5.0. Managed, versionless dependencies remain managed.",10,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringDataMongoDb_5_0,Migrate to Spring Data MongoDB 5.0,"Align explicitly versioned Spring Data MongoDB and supported MongoDB JVM driver dependencies with Spring Data MongoDB 5.0. Managed, versionless dependencies remain managed.",11,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_2_3,Migrate to Spring Data 2.3,Migrate applications to the latest Spring Data 2.3 release.,9,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_2_5,Migrate to Spring Data JPA 2.5,Migrate applications to the latest Spring Data 2.5 release.,12,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_2_7,Migrate to Spring Data JPA 2.7,Migrate applications to the latest Spring Data JPA 2.7 release.,15,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_3_0,Migrate to Spring Data 3.0,"Migrate applications to Spring Data 3.0. Handles the PagingAndSortingRepository hierarchy change where it no longer extends CrudRepository, and chains prior deprecation fixes from Spring Data 2.7.",18,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_3_4,Migrate to Spring Data JPA 3.4,Migrate applications to the latest Spring Data JPA 3.4 release.,20,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_4_0,Migrate to Spring Data 4.0,Migrate applications to the Spring Data 2025.1 release train. Datastore-specific migration support is added incrementally.,31,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UpgradeSpringData_4_0,Migrate to Spring Data 4.0,Migrate applications to the Spring Data 2025.1 release train. Datastore-specific migration support is added incrementally.,32,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.data.UseTlsJdbcConnectionString,Use TLS for JDBC connection strings,"Increasingly, for compliance reasons (e.g. [NACHA](https://www.nacha.org/sites/default/files/2022-06/End_User_Briefing_Supplementing_Data_Security_UPDATED_FINAL.pdf)), JDBC connection strings should be TLS-enabled. This recipe will update the port and optionally add a connection attribute to indicate that the connection is TLS-enabled.",1,,,,Spring Data,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,"[{""name"":""propertyKey"",""type"":""String"",""displayName"":""Property key"",""description"":""The Spring property key to perform updates against. If this value is specified, the specified property will be used for searching, otherwise a default of `spring.datasource.url` will be used instead."",""example"":""spring.datasource.url"",""required"":true},{""name"":""oldPort"",""type"":""Integer"",""displayName"":""Old port"",""description"":""The non-TLS enabled port number to replace with the TLS-enabled port. If this value is specified, no changes will be made to jdbc connection strings which do not contain this port number. "",""example"":""1234"",""required"":true},{""name"":""port"",""type"":""Integer"",""displayName"":""TLS port"",""description"":""The TLS-enabled port to use."",""example"":""1234"",""required"":true},{""name"":""attribute"",""type"":""String"",""displayName"":""Connection attribute"",""description"":""A connection attribute, if any, indicating to the JDBC provider that this is a TLS connection."",""example"":""sslConnection=true"",""required"":true}]",
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.doc.ApiInfoBuilderToInfo,Migrate `ApiInfoBuilder` to `Info`,Migrate SpringFox's `ApiInfoBuilder` to Swagger's `Info`.,4,,,,Doc,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.doc.MigrateDocketBeanToGroupedOpenApiBean,Migrate `Docket` to `GroupedOpenAPI`,"Migrate a `Docket` bean to a `GroupedOpenAPI` bean preserving group name, packages and paths. When possible the recipe will prefer property based configuration.",1,,,,Doc,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
@@ -262,7 +263,7 @@ maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framewor
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UpgradeSpringFramework_6_0,Migrate to Spring Framework 6.0,Migrate applications to the latest Spring Framework 6.0 release.,948,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UpgradeSpringFramework_6_1,Migrate to Spring Framework 6.1,Migrate applications to the latest Spring Framework 6.1 release.,953,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UpgradeSpringFramework_6_2,Migrate to Spring Framework 6.2,Migrate applications to the latest Spring Framework 6.2 release.,970,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
-maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0,Migrate to Spring Framework 7.0,Migrate applications to the latest Spring Framework 7.0 release.,1325,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0,Migrate to Spring Framework 7.0,Migrate applications to the latest Spring Framework 7.0 release.,1324,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.framework.UseObjectUtilsIsEmpty,Use `ObjectUtils#isEmpty(Object)`,`StringUtils#isEmpty(Object)` was deprecated in 5.3.,1,,,,Spring Framework,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.http.ReplaceStringLiteralsWithHttpHeadersConstants,Replace String literals with `HttpHeaders` constants,Replace String literals with `org.springframework.http.HttpHeaders` constants.,62,,,,Http,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.http.ReplaceStringLiteralsWithMediaTypeConstants,Replace String literals with `MediaType` constants,Replace String literals with `org.springframework.http.MediaType` constants.,32,,,,Http,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
diff --git a/src/main/resources/META-INF/rewrite/spring-data-4.yml b/src/main/resources/META-INF/rewrite/spring-data-4.yml
index 21dcb39f5..d04163012 100644
--- a/src/main/resources/META-INF/rewrite/spring-data-4.yml
+++ b/src/main/resources/META-INF/rewrite/spring-data-4.yml
@@ -40,6 +40,7 @@ preconditions:
artifactIdPattern: spring-data-mongodb
- org.openrewrite.Singleton
recipeList:
+ - org.openrewrite.java.spring.data.PreserveDefaultMessageListenerContainerStartup
- org.openrewrite.java.dependencies.UpgradeDependencyVersion:
groupId: org.springframework.data
artifactId: spring-data-mongodb
diff --git a/src/test/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartupTest.java b/src/test/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartupTest.java
new file mode 100644
index 000000000..0340c8d49
--- /dev/null
+++ b/src/test/java/org/openrewrite/java/spring/data/PreserveDefaultMessageListenerContainerStartupTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * 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.openrewrite.java.spring.data;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.DocumentExample;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+
+import static org.openrewrite.java.Assertions.java;
+
+class PreserveDefaultMessageListenerContainerStartupTest implements RewriteTest {
+
+ @Override
+ public void defaults(RecipeSpec spec) {
+ spec.recipe(new PreserveDefaultMessageListenerContainerStartup())
+ .parser(JavaParser.fromJavaVersion().classpathFromResources(
+ new InMemoryExecutionContext(),
+ "spring-data-mongodb-5.0",
+ "spring-context-6"
+ ));
+ }
+
+ @DocumentExample
+ @Test
+ void addsExplicitAutoStartupFalseToBean() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ return container;
+ }
+ }
+ """,
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ container.setAutoStartup(false);
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesExplicitAutoStartupTrueUnchanged() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ container.setAutoStartup(true);
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesExplicitAutoStartupFalseUnchanged() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ container.setAutoStartup(false);
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void leavesNonSpringManagedContainerUnchanged() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerFactory {
+
+ DefaultMessageListenerContainer create(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void updatesDirectBeanReturn() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ return new DefaultMessageListenerContainer(template);
+ }
+ }
+ """,
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(template);
+ container.setAutoStartup(false);
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+ @Test
+ void marksIndirectBeanReturnForManualReview() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ private DefaultMessageListenerContainer createContainer(MongoTemplate template) {
+ return new DefaultMessageListenerContainer(template);
+ }
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ return createContainer(template);
+ }
+ }
+ """,
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ private DefaultMessageListenerContainer createContainer(MongoTemplate template) {
+ return new DefaultMessageListenerContainer(template);
+ }
+
+ /*~~(Unable to safely preserve DefaultMessageListenerContainer startup behavior. Configure setAutoStartup(false) manually.)~~>*/@Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ return createContainer(template);
+ }
+ }
+ """
+ )
+ );
+ }
+ @Test
+ void leavesConditionalAutoStartupConfigurationUnchanged() {
+ rewriteRun(
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ boolean shouldStartAutomatically() {
+ return true;
+ }
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+
+ if (shouldStartAutomatically()) {
+ container.setAutoStartup(true);
+ }
+
+ return container;
+ }
+ }
+ """
+ )
+ );
+ }
+}
diff --git a/src/test/java/org/openrewrite/java/spring/data/UpgradeSpringDataMongoDb_5_0Test.java b/src/test/java/org/openrewrite/java/spring/data/UpgradeSpringDataMongoDb_5_0Test.java
index fe1b4b4ce..e9a908e84 100644
--- a/src/test/java/org/openrewrite/java/spring/data/UpgradeSpringDataMongoDb_5_0Test.java
+++ b/src/test/java/org/openrewrite/java/spring/data/UpgradeSpringDataMongoDb_5_0Test.java
@@ -22,6 +22,8 @@
import org.openrewrite.DocumentExample;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.java.JavaParser;
import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.gradle.Assertions.buildGradle;
@@ -435,7 +437,76 @@ void doesNotUpgradeMongoDriverOutsideSpringDataMongoDbModules() {
)
);
}
+ @Test
+ void preservesManualListenerContainerStartupWhenUpgrading() {
+ rewriteRun(
+ spec -> spec.parser(
+ JavaParser.fromJavaVersion().classpathFromResources(
+ new InMemoryExecutionContext(),
+ "spring-data-mongodb-5.0",
+ "spring-context-6"
+ )
+ ),
+ mavenProject("listener-container-startup",
+ pomXml(
+ """
+
+ 4.0.0
+ com.example
+ listener-container-startup
+ 1.0.0
+
+
+ org.springframework.data
+ spring-data-mongodb
+ 4.5.13
+
+
+
+ """,
+ spec -> spec.after(actual ->
+ assertDependencyVersion(
+ actual,
+ "spring-data-mongodb",
+ "5\\.0\\.\\d+"
+ ).actual())
+ ),
+ java(
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ return container;
+ }
+ }
+ """,
+ """
+ import org.springframework.context.annotation.Bean;
+ import org.springframework.data.mongodb.core.MongoTemplate;
+ import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
+
+ class ListenerConfiguration {
+
+ @Bean
+ DefaultMessageListenerContainer listenerContainer(MongoTemplate template) {
+ DefaultMessageListenerContainer container =
+ new DefaultMessageListenerContainer(template);
+ container.setAutoStartup(false);
+ return container;
+ }
+ }
+ """
+ )
+ )
+ );
+ }
private static AbstractStringAssert> assertDependencyVersion(String pom, String artifactId, String versionPattern) {
return assertThat(pom).containsPattern(
"" + artifactId + "\\s*" + versionPattern + "");
diff --git a/src/test/resources/META-INF/rewrite/classpath.tsv.gz b/src/test/resources/META-INF/rewrite/classpath.tsv.gz
index 6bd5772d3..4e5fe6cf1 100644
Binary files a/src/test/resources/META-INF/rewrite/classpath.tsv.gz and b/src/test/resources/META-INF/rewrite/classpath.tsv.gz differ