From cad7dd6904b2602d997109bb07a233300c537060 Mon Sep 17 00:00:00 2001
From: Yanming Zhou <zhouyanming@gmail.com>
Date: Mon, 3 Mar 2025 11:19:28 +0800
Subject: [PATCH] Introduce TestSliceTestContextBootstrapper for test slices

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
---
 .../DataCassandraTestContextBootstrapper.java | 14 +----
 .../DataCouchbaseTestContextBootstrapper.java | 14 +----
 ...aElasticsearchTestContextBootstrapper.java | 14 +----
 .../jdbc/DataJdbcTestContextBootstrapper.java | 13 +---
 .../ldap/DataLdapTestContextBootstrapper.java | 13 +---
 .../DataMongoTestContextBootstrapper.java     | 13 +---
 .../DataNeo4jTestContextBootstrapper.java     | 13 +---
 .../DataR2dbcTestContextBootstrapper.java     | 13 +---
 .../DataRedisTestContextBootstrapper.java     | 13 +---
 .../GraphQlTestContextBootstrapper.java       | 11 +---
 .../jdbc/JdbcTestContextBootstrapper.java     | 14 ++---
 .../jooq/JooqTestContextBootstrapper.java     | 13 +---
 .../json/JsonTestContextBootstrapper.java     | 13 +---
 .../jpa/DataJpaTestContextBootstrapper.java   | 11 +---
 .../RestClientTestContextBootstrapper.java    | 14 +----
 .../WebFluxTestContextBootstrapper.java       | 13 +---
 .../WebMvcTestContextBootstrapper.java        | 13 +---
 ...bServiceClientTestContextBootstrapper.java | 14 +----
 ...bServiceServerTestContextBootstrapper.java | 14 +----
 .../TestSliceTestContextBootstrapper.java     | 59 +++++++++++++++++++
 20 files changed, 115 insertions(+), 194 deletions(-)
 create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/TestSliceTestContextBootstrapper.java

diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/cassandra/DataCassandraTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/cassandra/DataCassandraTestContextBootstrapper.java
index 56fb006508b9..d3fc402862f0 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/cassandra/DataCassandraTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/cassandra/DataCassandraTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.cassandra;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -26,13 +25,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataCassandraTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataCassandraTest dataCassandraTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				DataCassandraTest.class);
-		return (dataCassandraTest != null) ? dataCassandraTest.properties() : null;
-	}
+class DataCassandraTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataCassandraTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestContextBootstrapper.java
index e921b751a311..b68f58994175 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.couchbase;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -26,13 +25,6 @@
  *
  * @author Eddú Meléndez
  */
-class DataCouchbaseTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataCouchbaseTest dataCouchbaseTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				DataCouchbaseTest.class);
-		return (dataCouchbaseTest != null) ? dataCouchbaseTest.properties() : null;
-	}
+class DataCouchbaseTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataCouchbaseTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestContextBootstrapper.java
index 4d80cadae3ab..b6fff7d9f488 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.elasticsearch;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -26,13 +25,6 @@
  *
  * @author Eddú Meléndez
  */
-class DataElasticsearchTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataElasticsearchTest dataElasticsearchTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				DataElasticsearchTest.class);
-		return (dataElasticsearchTest != null) ? dataElasticsearchTest.properties() : null;
-	}
+class DataElasticsearchTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataElasticsearchTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestContextBootstrapper.java
index f633edd55f47..16303f8b46b3 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.jdbc;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Andy Wilkinson
  */
-class DataJdbcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataJdbcTest dataJdbcTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataJdbcTest.class);
-		return (dataJdbcTest != null) ? dataJdbcTest.properties() : null;
-	}
+class DataJdbcTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataJdbcTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/ldap/DataLdapTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/ldap/DataLdapTestContextBootstrapper.java
index 8268a2e7b840..b52b10cc56f3 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/ldap/DataLdapTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/ldap/DataLdapTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.ldap;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataLdapTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataLdapTest dataLdapTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataLdapTest.class);
-		return (dataLdapTest != null) ? dataLdapTest.properties() : null;
-	}
+class DataLdapTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataLdapTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/mongo/DataMongoTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/mongo/DataMongoTestContextBootstrapper.java
index 70803b42eb2d..ac2a159a07fc 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/mongo/DataMongoTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/mongo/DataMongoTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.mongo;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataMongoTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataMongoTest dataMongoTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataMongoTest.class);
-		return (dataMongoTest != null) ? dataMongoTest.properties() : null;
-	}
+class DataMongoTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataMongoTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestContextBootstrapper.java
index 5bc499c6c969..5f6d01257dac 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.neo4j;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataNeo4jTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataNeo4jTest dataNeo4jTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataNeo4jTest.class);
-		return (dataNeo4jTest != null) ? dataNeo4jTest.properties() : null;
-	}
+class DataNeo4jTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataNeo4jTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/r2dbc/DataR2dbcTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/r2dbc/DataR2dbcTestContextBootstrapper.java
index 282e27059f8e..e514a7f799b3 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/r2dbc/DataR2dbcTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/r2dbc/DataR2dbcTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.r2dbc;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Mark Paluch
  */
-class DataR2dbcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataR2dbcTest dataR2dbcTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataR2dbcTest.class);
-		return (dataR2dbcTest != null) ? dataR2dbcTest.properties() : null;
-	}
+class DataR2dbcTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataR2dbcTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestContextBootstrapper.java
index aaba8abdc4d5..abc891e93755 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.data.redis;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataRedisTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataRedisTest dataRedisTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataRedisTest.class);
-		return (dataRedisTest != null) ? dataRedisTest.properties() : null;
-	}
+class DataRedisTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataRedisTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java
index 8d9b47ef165d..5e2e2b8daa2c 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.graphql;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Brian Clozel
  */
-class GraphQlTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		GraphQlTest graphQlTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, GraphQlTest.class);
-		return (graphQlTest != null) ? graphQlTest.properties() : null;
-	}
+class GraphQlTestContextBootstrapper extends TestSliceTestContextBootstrapper<GraphQlTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestContextBootstrapper.java
index 45211ffde352..477b7a3187a7 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,21 +16,15 @@
 
 package org.springframework.boot.test.autoconfigure.jdbc;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
  * {@link TestContextBootstrapper} for {@link JdbcTest @JdbcTest} support.
  *
  * @author Artsiom Yudovin
+ * @author Yanming Zhou
  */
-class JdbcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		JdbcTest jdbcTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, JdbcTest.class);
-		return (jdbcTest != null) ? jdbcTest.properties() : null;
-	}
+class JdbcTestContextBootstrapper extends TestSliceTestContextBootstrapper<JdbcTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestContextBootstrapper.java
index a99bc1418857..165ec6c75b58 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.jooq;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class JooqTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		JooqTest jooqTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, JooqTest.class);
-		return (jooqTest != null) ? jooqTest.properties() : null;
-	}
+class JooqTestContextBootstrapper extends TestSliceTestContextBootstrapper<JooqTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestContextBootstrapper.java
index 752c887ec9a5..be87468c51e4 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.json;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class JsonTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		JsonTest jsonTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, JsonTest.class);
-		return (jsonTest != null) ? jsonTest.properties() : null;
-	}
+class JsonTestContextBootstrapper extends TestSliceTestContextBootstrapper<JsonTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestContextBootstrapper.java
index 8dd518551b57..d672538d5c08 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestContextBootstrapper.java
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.orm.jpa;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,12 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class DataJpaTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		DataJpaTest dataJpaTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, DataJpaTest.class);
-		return (dataJpaTest != null) ? dataJpaTest.properties() : null;
-	}
+class DataJpaTestContextBootstrapper extends TestSliceTestContextBootstrapper<DataJpaTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestContextBootstrapper.java
index 53de234318d6..a15abc914030 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.web.client;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -25,13 +24,6 @@
  *
  * @author Artsiom Yudovin
  */
-class RestClientTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		RestClientTest restClientTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				RestClientTest.class);
-		return (restClientTest != null) ? restClientTest.properties() : null;
-	}
+class RestClientTestContextBootstrapper extends TestSliceTestContextBootstrapper<RestClientTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java
index 3f813f97b602..8525e5d7fc6e 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,9 +17,8 @@
 package org.springframework.boot.test.autoconfigure.web.reactive;
 
 import org.springframework.boot.test.context.ReactiveWebMergedContextConfiguration;
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.MergedContextConfiguration;
-import org.springframework.test.context.TestContextAnnotationUtils;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -28,17 +27,11 @@
  * @author Stephane Nicoll
  * @author Artsiom Yudovin
  */
-class WebFluxTestContextBootstrapper extends SpringBootTestContextBootstrapper {
+class WebFluxTestContextBootstrapper extends TestSliceTestContextBootstrapper<WebFluxTest> {
 
 	@Override
 	protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
 		return new ReactiveWebMergedContextConfiguration(super.processMergedContextConfiguration(mergedConfig));
 	}
 
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		WebFluxTest webFluxTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, WebFluxTest.class);
-		return (webFluxTest != null) ? webFluxTest.properties() : null;
-	}
-
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java
index 0dcf35d23139..78d4fc27306e 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,9 +16,8 @@
 
 package org.springframework.boot.test.autoconfigure.web.servlet;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.MergedContextConfiguration;
-import org.springframework.test.context.TestContextAnnotationUtils;
 import org.springframework.test.context.TestContextBootstrapper;
 import org.springframework.test.context.web.WebMergedContextConfiguration;
 
@@ -29,7 +28,7 @@
  * @author Artsiom Yudovin
  * @author Lorenzo Dee
  */
-class WebMvcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
+class WebMvcTestContextBootstrapper extends TestSliceTestContextBootstrapper<WebMvcTest> {
 
 	@Override
 	protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
@@ -37,10 +36,4 @@ protected MergedContextConfiguration processMergedContextConfiguration(MergedCon
 		return new WebMergedContextConfiguration(processedMergedConfiguration, determineResourceBasePath(mergedConfig));
 	}
 
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		WebMvcTest webMvcTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, WebMvcTest.class);
-		return (webMvcTest != null) ? webMvcTest.properties() : null;
-	}
-
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTestContextBootstrapper.java
index 24bf8b795054..8335dc5ea976 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
 
 package org.springframework.boot.test.autoconfigure.webservices.client;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
-import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.TestContextBootstrapper;
 
 /**
@@ -26,13 +25,6 @@
  *
  * @author Dmytro Nosan
  */
-class WebServiceClientTestContextBootstrapper extends SpringBootTestContextBootstrapper {
-
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		WebServiceClientTest webServiceClientTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				WebServiceClientTest.class);
-		return (webServiceClientTest != null) ? webServiceClientTest.properties() : null;
-	}
+class WebServiceClientTestContextBootstrapper extends TestSliceTestContextBootstrapper<WebServiceClientTest> {
 
 }
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/server/WebServiceServerTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/server/WebServiceServerTestContextBootstrapper.java
index 8d2e8047b7b8..794272e40d36 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/server/WebServiceServerTestContextBootstrapper.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/server/WebServiceServerTestContextBootstrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,9 +16,8 @@
 
 package org.springframework.boot.test.autoconfigure.webservices.server;
 
-import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
+import org.springframework.boot.test.context.TestSliceTestContextBootstrapper;
 import org.springframework.test.context.MergedContextConfiguration;
-import org.springframework.test.context.TestContextAnnotationUtils;
 import org.springframework.test.context.TestContextBootstrapper;
 import org.springframework.test.context.web.WebMergedContextConfiguration;
 
@@ -28,7 +27,7 @@
  *
  * @author Daniil Razorenov
  */
-class WebServiceServerTestContextBootstrapper extends SpringBootTestContextBootstrapper {
+class WebServiceServerTestContextBootstrapper extends TestSliceTestContextBootstrapper<WebServiceServerTest> {
 
 	@Override
 	protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
@@ -36,11 +35,4 @@ protected MergedContextConfiguration processMergedContextConfiguration(MergedCon
 		return new WebMergedContextConfiguration(processedMergedConfiguration, determineResourceBasePath(mergedConfig));
 	}
 
-	@Override
-	protected String[] getProperties(Class<?> testClass) {
-		WebServiceServerTest webServiceServerTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
-				WebServiceServerTest.class);
-		return (webServiceServerTest != null) ? webServiceServerTest.properties() : null;
-	}
-
 }
diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/TestSliceTestContextBootstrapper.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/TestSliceTestContextBootstrapper.java
new file mode 100644
index 000000000000..9a677e71fb8f
--- /dev/null
+++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/TestSliceTestContextBootstrapper.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://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.springframework.boot.test.context;
+
+import java.lang.annotation.Annotation;
+
+import org.springframework.core.ResolvableType;
+import org.springframework.core.annotation.MergedAnnotation;
+import org.springframework.core.annotation.MergedAnnotations;
+import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
+import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.test.context.TestContextBootstrapper;
+import org.springframework.util.Assert;
+
+/**
+ * {@link TestContextBootstrapper} for test slices support.
+ *
+ * @param <T> the test slice annotation
+ * @author Yanming Zhou
+ * @since 3.5.0
+ */
+public class TestSliceTestContextBootstrapper<T extends Annotation> extends SpringBootTestContextBootstrapper {
+
+	private final Class<T> annotationType;
+
+	@SuppressWarnings("unchecked")
+	public TestSliceTestContextBootstrapper() {
+		this.annotationType = (Class<T>) ResolvableType.forClass(getClass())
+			.as(TestSliceTestContextBootstrapper.class)
+			.getGeneric(0)
+			.resolve();
+		Assert.notNull(this.annotationType, "'%s' doesn't contain type parameter of '%s'"
+			.formatted(getClass().getName(), TestSliceTestContextBootstrapper.class.getName()));
+	}
+
+	@Override
+	protected String[] getProperties(Class<?> testClass) {
+		MergedAnnotation<T> annotation = MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
+			.withEnclosingClasses(TestContextAnnotationUtils::searchEnclosingClass)
+			.from(testClass)
+			.get(this.annotationType);
+		return annotation.isPresent() ? annotation.getStringArray("properties") : null;
+	}
+
+}