From 98bb889b06c3de26253f743dbb58153f27cb75c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E8=BE=B9?= Date: Wed, 12 Nov 2025 14:20:48 +0800 Subject: [PATCH 1/3] add convert.py to process local dataset --- scripts/convert.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 scripts/convert.py diff --git a/scripts/convert.py b/scripts/convert.py new file mode 100644 index 0000000..5a9140e --- /dev/null +++ b/scripts/convert.py @@ -0,0 +1,13 @@ +import pandas as pd + +# 手动下载数据集放到 scripts/data,处理成jsonl文件 +# https://huggingface.co/datasets/inclusionAI/SWE-CARE/blob/main/data/dev-00000-of-00001.parquet +# https://huggingface.co/datasets/inclusionAI/SWE-CARE/blob/main/data/test-00000-of-00001.parquet + +# 转换test数据集 +test_df = pd.read_parquet('data/test-00000-of-00001.parquet') +test_df.to_json('swe_care_test.jsonl', orient='records', lines=True) + +# 转换dev数据集 +dev_df = pd.read_parquet('data/dev-00000-of-00001.parquet') +dev_df.to_json('swe_care_dev.jsonl', orient='records', lines=True) From ba270d83d68f7823227a9ef968128bf764101e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E8=BE=B9?= Date: Wed, 12 Nov 2025 22:46:58 +0800 Subject: [PATCH 2/3] add min__oracle__deepseek-reasoner.jsonl --- .../deepseek-reasoner/min__oracle__deepseek-reasoner.jsonl | 1 + 1 file changed, 1 insertion(+) create mode 100644 scripts/results/pipeline_output/predictions/deepseek-reasoner/min__oracle__deepseek-reasoner.jsonl diff --git a/scripts/results/pipeline_output/predictions/deepseek-reasoner/min__oracle__deepseek-reasoner.jsonl b/scripts/results/pipeline_output/predictions/deepseek-reasoner/min__oracle__deepseek-reasoner.jsonl new file mode 100644 index 0000000..e7da763 --- /dev/null +++ b/scripts/results/pipeline_output/predictions/deepseek-reasoner/min__oracle__deepseek-reasoner.jsonl @@ -0,0 +1 @@ +{"instance_id": "tobymao__sqlglot-5284@3f57fcd", "review_text": "\n## Function\nThe patch aims to address the issue of GROUP_CONCAT being incorrectly used in Databricks by implementing proper support for string aggregation functions. It adds transformations to convert GROUP_CONCAT expressions to LISTAGG (the equivalent Databricks function) during SQL generation. The patch also adds corresponding test cases to validate this behavior. This directly addresses the issue by ensuring valid SQL generation for Databricks when handling string aggregation.\n\n## Complexity\nThe patch is appropriately minimal and focused. It adds only necessary changes:\n- One import statement\n- One transformation mapping\n- Several test case updates\nThe complexity is well-contained and doesn't introduce unnecessary abstractions or code.\n\n## Style\nThe patch follows the existing codebase conventions perfectly:\n- Imports are added in alphabetical order with other dialect imports\n- Transformation uses the existing lambda pattern\n- Test cases follow the existing validation patterns\n- Names are consistent with existing code (groupconcat_sql, LISTAGG)\n\n## Documentation\nThe patch doesn't add explicit code comments, but the changes are self-explanatory given the context. The test cases serve as effective documentation by demonstrating the expected behavior. No additional documentation updates are needed since this doesn't change user-facing interfaces.\n\n## Defects\n\nfile_path: tests/dialects/test_databricks.py\nline: 174\nsuggestion: The test case uses LISTAGG but the issue mentions STRING_AGG. While both are valid in Databricks, for consistency with the issue statement, consider using STRING_AGG in the test to match user expectations.\n\n\nfile_path: sqlglot/dialects/databricks.py\nline: 91\nsuggestion: The transformation uses groupconcat_sql which generates LISTAGG. If STRING_AGG is preferred in Databricks, consider modifying groupconcat_sql to generate STRING_AGG instead when dialect is databricks.\n\n", "review_trajectory": null} From 931bad0da9160db1ee3694264115d2c38e8d9f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E8=BE=B9?= Date: Wed, 12 Nov 2025 22:53:36 +0800 Subject: [PATCH 3/3] add spring-projects/spring-framework results --- ...__spring-framework_pr_classification.jsonl | 20 +++++++++++++++++++ .../dataset/code_review_task_instances.jsonl | 3 +++ ...s__spring-framework_graphql_prs_data.jsonl | 20 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 results/classify_prs_data/spring-projects__spring-framework_pr_classification.jsonl create mode 100644 results/dataset/code_review_task_instances.jsonl create mode 100644 results/graphql_prs_data/spring-projects__spring-framework_graphql_prs_data.jsonl diff --git a/results/classify_prs_data/spring-projects__spring-framework_pr_classification.jsonl b/results/classify_prs_data/spring-projects__spring-framework_pr_classification.jsonl new file mode 100644 index 0000000..ea41566 --- /dev/null +++ b/results/classify_prs_data/spring-projects__spring-framework_pr_classification.jsonl @@ -0,0 +1,20 @@ +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 35732, "url": "https://github.com/spring-projects/spring-framework/pull/35732", "commits": [{"commit_sha": "089c627c5b0610a0325fe93b4d6535d45429b516", "labeled_review_comments": [], "total_score": 0.4170212765957447, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.30000000000000004, "conventional_commit": true, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": true, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java\nindex 0b45256ea3f3..a2085d1ad64a 100644\n--- a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java\n+++ b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java\n@@ -630,8 +630,15 @@ private Set getClassPathManifestEntriesFromJar(File jar)\n \t\t\t\t\t\t// See jdk.internal.loader.URLClassPath.JarLoader.tryResolveFile(URL, String)\n \t\t\t\t\t\tcontinue;\n \t\t\t\t\t}\n-\t\t\t\t\tFile candidate = new File(parent, path);\n-\t\t\t\t\tif (candidate.isFile() && candidate.getCanonicalPath().contains(parent.getCanonicalPath())) {\n+\n+\t\t\t\t\t// Handle absolute paths correctly - don't use parent for absolute paths\n+\t\t\t\t\tFile pathFile = new File(path);\n+\t\t\t\t\tFile candidate = pathFile.isAbsolute() ? pathFile : new File(parent, path);\n+\n+\t\t\t\t\t// For relative paths, enforce security check (must be under parent)\n+\t\t\t\t\t// For absolute paths, just verify file exists (matching JVM behavior)\n+\t\t\t\t\tif (candidate.isFile() &&\n+\t\t\t\t\t\t\t(pathFile.isAbsolute() || candidate.getCanonicalPath().contains(parent.getCanonicalPath()))) {\n \t\t\t\t\t\tmanifestEntries.add(ClassPathManifestEntry.of(candidate, this.useCaches));\n \t\t\t\t\t}\n \t\t\t\t}\ndiff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java\nindex a5943124de45..e0390b6c7b03 100644\n--- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java\n+++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java\n@@ -337,6 +337,21 @@ void javaDashJarFindsClassPathManifestEntries() throws Exception {\n \t\t\tassertThat(result.replace(\"\\\\\", \"/\")).contains(\"!!!!\").contains(\"/lib/asset.jar!/assets/file.txt\");\n \t\t}\n \n+\t\t@Test\n+\t\tvoid javaDashJarFindsAbsoluteClassPathManifestEntries() throws Exception {\n+\t\t\tPath assetJar = this.temp.resolve(\"dependency\").resolve(\"asset.jar\");\n+\t\t\tFiles.createDirectories(assetJar.getParent());\n+\t\t\twriteAssetJar(assetJar);\n+\t\t\twriteApplicationJarWithAbsolutePath(this.temp.resolve(\"app.jar\"), assetJar);\n+\t\t\tString java = ProcessHandle.current().info().command().get();\n+\t\t\tProcess process = new ProcessBuilder(java, \"-jar\", \"app.jar\")\n+\t\t\t\t\t.directory(this.temp.toFile())\n+\t\t\t\t\t.start();\n+\t\t\tassertThat(process.waitFor()).isZero();\n+\t\t\tString result = StreamUtils.copyToString(process.getInputStream(), StandardCharsets.UTF_8);\n+\t\t\tassertThat(result.replace(\"\\\\\", \"/\")).contains(\"!!!!\").contains(\"asset.jar!/assets/file.txt\");\n+\t\t}\n+\n \t\tprivate void writeAssetJar(Path path) throws Exception {\n \t\t\ttry (JarOutputStream jar = new JarOutputStream(new FileOutputStream(path.toFile()))) {\n \t\t\t\tjar.putNextEntry(new ZipEntry(\"assets/\"));\n@@ -392,6 +407,35 @@ private void writeApplicationJar(Path path) throws Exception {\n \t\t\tassertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue();\n \t\t}\n \n+\t\tprivate void writeApplicationJarWithAbsolutePath(Path path, Path assetJar) throws Exception {\n+\t\t\tManifest manifest = new Manifest();\n+\t\t\tAttributes mainAttributes = manifest.getMainAttributes();\n+\t\t\tmainAttributes.put(Name.CLASS_PATH, buildSpringClassPath() + assetJar.toAbsolutePath());\n+\t\t\tmainAttributes.put(Name.MAIN_CLASS, ClassPathManifestEntriesTestApplication.class.getName());\n+\t\t\tmainAttributes.put(Name.MANIFEST_VERSION, \"1.0\");\n+\t\t\ttry (JarOutputStream jar = new JarOutputStream(new FileOutputStream(path.toFile()), manifest)) {\n+\t\t\t\tString appClassResource = ClassUtils.convertClassNameToResourcePath(\n+\t\t\t\t\t\tClassPathManifestEntriesTestApplication.class.getName()) + ClassUtils.CLASS_FILE_SUFFIX;\n+\t\t\t\tString folder = \"\";\n+\t\t\t\tfor (String name : appClassResource.split(\"/\")) {\n+\t\t\t\t\tif (!name.endsWith(ClassUtils.CLASS_FILE_SUFFIX)) {\n+\t\t\t\t\t\tfolder += name + \"/\";\n+\t\t\t\t\t\tjar.putNextEntry(new ZipEntry(folder));\n+\t\t\t\t\t\tjar.closeEntry();\n+\t\t\t\t\t}\n+\t\t\t\t\telse {\n+\t\t\t\t\t\tjar.putNextEntry(new ZipEntry(folder + name));\n+\t\t\t\t\t\ttry (InputStream in = getClass().getResourceAsStream(name)) {\n+\t\t\t\t\t\t\tin.transferTo(jar);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\tjar.closeEntry();\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tassertThat(new FileSystemResource(path).exists()).isTrue();\n+\t\t\tassertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue();\n+\t\t}\n+\n \t\tprivate String buildSpringClassPath() throws Exception {\n \t\t\treturn copyClasses(PathMatchingResourcePatternResolver.class, \"spring-core\") +\n \t\t\t\t\tcopyClasses(LogFactory.class, \"commons-logging\");\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 35543, "url": "https://github.com/spring-projects/spring-framework/pull/35543", "commits": [{"commit_sha": "96d8109b780a97a3c8780003d25b5a8a1f9ce90f", "labeled_review_comments": [], "total_score": 0.32340425531914896, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-core/src/main/java/org/springframework/cglib/core/CodeEmitter.java b/spring-core/src/main/java/org/springframework/cglib/core/CodeEmitter.java\nindex 35181c5d8940..6fa920a0d032 100644\n--- a/spring-core/src/main/java/org/springframework/cglib/core/CodeEmitter.java\n+++ b/spring-core/src/main/java/org/springframework/cglib/core/CodeEmitter.java\n@@ -29,6 +29,22 @@\n public class CodeEmitter extends LocalVariablesSorter {\n private static final Signature BOOLEAN_VALUE =\n TypeUtils.parseSignature(\"boolean booleanValue()\");\n+ private static final Signature BOOLEAN_VALUE_OF =\n+ TypeUtils.parseSignature(\"Boolean valueOf(boolean)\");\n+ private static final Signature INTEGER_VALUE_OF =\n+ TypeUtils.parseSignature(\"Integer valueOf(int)\");\n+ private static final Signature BYTE_VALUE_OF =\n+ TypeUtils.parseSignature(\"Byte valueOf(byte)\");\n+ private static final Signature SHORT_VALUE_OF =\n+ TypeUtils.parseSignature(\"Short valueOf(short)\");\n+ private static final Signature LONG_VALUE_OF =\n+ TypeUtils.parseSignature(\"Long valueOf(long)\");\n+ private static final Signature FLOAT_VALUE_OF =\n+ TypeUtils.parseSignature(\"Float valueOf(float)\");\n+ private static final Signature DOUBLE_VALUE_OF =\n+ TypeUtils.parseSignature(\"Double valueOf(double)\");\n+ private static final Signature CHARACTER_VALUE_OF =\n+ TypeUtils.parseSignature(\"Character valueOf(char)\");\n private static final Signature CHAR_VALUE =\n TypeUtils.parseSignature(\"char charValue()\");\n private static final Signature LONG_VALUE =\n@@ -705,29 +721,56 @@ public void throw_exception(Type type, String msg) {\n \n /**\n * If the argument is a primitive class, replaces the primitive value\n- * on the top of the stack with the wrapped (Object) equivalent. For\n- * example, char -> Character.\n+ * on the top of the stack with the wrapped (Object) equivalent using valueOf() methods.\n+\t * For example, char -> Character.\n * If the class is Void, a null is pushed onto the stack instead.\n * @param type the class indicating the current type of the top stack value\n */\n public void box(Type type) {\n if (TypeUtils.isPrimitive(type)) {\n- if (type == Type.VOID_TYPE) {\n- aconst_null();\n- } else {\n- Type boxed = TypeUtils.getBoxedType(type);\n- new_instance(boxed);\n- if (type.getSize() == 2) {\n- // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o\n- dup_x2();\n- dup_x2();\n- pop();\n- } else {\n- // p -> po -> opo -> oop -> o\n- dup_x1();\n- swap();\n- }\n- invoke_constructor(boxed, new Signature(Constants.CONSTRUCTOR_NAME, Type.VOID_TYPE, new Type[]{ type }));\n+\t\t\tswitch (type.getSort()) {\n+\t\t\t\tcase Type.VOID:\n+\t\t\t\t\taconst_null();\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.BOOLEAN:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_BOOLEAN, BOOLEAN_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.INT:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_INTEGER, INTEGER_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.BYTE:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_BYTE, BYTE_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.SHORT:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_SHORT, SHORT_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.LONG:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_LONG, LONG_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.FLOAT:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_FLOAT, FLOAT_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.DOUBLE:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_DOUBLE, DOUBLE_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase Type.CHAR:\n+\t\t\t\t\tinvoke_static(Constants.TYPE_CHARACTER, CHARACTER_VALUE_OF);\n+\t\t\t\t\tbreak;\n+\n+\t\t\t\tdefault:\n+\t\t\t\t\tType boxed = TypeUtils.getBoxedType(type);\n+\t\t\t\t\tnew_instance(boxed);\n+\t\t\t\t\tif (type.getSize() == 2) {\n+\t\t\t\t\t\t// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o\n+\t\t\t\t\t\tdup_x2();\n+\t\t\t\t\t\tdup_x2();\n+\t\t\t\t\t\tpop();\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t// p -> po -> opo -> oop -> o\n+\t\t\t\t\t\tdup_x1();\n+\t\t\t\t\t\tswap();\n+\t\t\t\t\t}\n+\t\t\t\t\tinvoke_constructor(boxed, new Signature(Constants.CONSTRUCTOR_NAME, Type.VOID_TYPE, new Type[]{ type }));\n }\n }\n }\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 34623, "url": "https://github.com/spring-projects/spring-framework/pull/34623", "commits": [{"commit_sha": "2745eab27a78e9262a7363bb8912aebc4d43ca27", "labeled_review_comments": [], "total_score": 0.30638297872340425, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java\nindex 5eb6fc79b227..dccf0cb6cd40 100644\n--- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java\n+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java\n@@ -18,6 +18,8 @@\n \n import java.util.List;\n import java.util.Map;\n+import java.util.function.BiFunction;\n+import java.util.stream.Stream;\n \n import javax.sql.DataSource;\n \n@@ -25,6 +27,7 @@\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.support.DataAccessUtils;\n+import org.springframework.jdbc.core.PreparedStatementCreator;\n import org.springframework.jdbc.core.RowMapper;\n import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;\n import org.springframework.jdbc.core.namedparam.NamedParameterUtils;\n@@ -52,6 +55,7 @@\n * @author Rod Johnson\n * @author Juergen Hoeller\n * @author Thomas Risberg\n+ * @author Yanming Zhou\n * @param the result type\n * @see SqlUpdate\n */\n@@ -94,6 +98,23 @@ public List execute(Object @Nullable [] params, @Nullable Map context)\n \t\treturn getJdbcTemplate().query(newPreparedStatementCreator(params), rowMapper);\n \t}\n \n+\t/**\n+\t * Central stream method. All un-named parameter execution goes through this method.\n+\t * @param params parameters, similar to JDO query parameters.\n+\t * Primitive parameters must be represented by their Object wrapper type.\n+\t * The ordering of parameters is significant.\n+\t * @param context the contextual information passed to the {@code mapRow}\n+\t * callback method. The JDBC operation itself doesn't rely on this parameter,\n+\t * but it can be useful for creating the objects of the result list.\n+\t * @return a result Stream of objects, one per row of the ResultSet. Normally all these\n+\t * will be of the same class, although it is possible to use different types.\n+\t */\n+\tpublic Stream stream(Object @Nullable [] params, @Nullable Map context) throws DataAccessException {\n+\t\tvalidateParameters(params);\n+\t\tRowMapper rowMapper = newRowMapper(params, context);\n+\t\treturn getJdbcTemplate().queryForStream(newPreparedStatementCreator(params), rowMapper);\n+\t}\n+\n \t/**\n \t * Convenient method to execute without context.\n \t * @param params parameters for the query. Primitive parameters must\n@@ -104,6 +125,16 @@ public List execute(Object... params) throws DataAccessException {\n \t\treturn execute(params, null);\n \t}\n \n+\t/**\n+\t * Convenient method to stream without context.\n+\t * @param params parameters for the query. Primitive parameters must\n+\t * be represented by their Object wrapper type. The ordering of parameters is\n+\t * significant.\n+\t */\n+\tpublic Stream stream(Object... params) throws DataAccessException {\n+\t\treturn stream(params, null);\n+\t}\n+\n \t/**\n \t * Convenient method to execute without parameters.\n \t * @param context the contextual information for object creation\n@@ -112,6 +143,14 @@ public List execute(Map context) throws DataAccessException {\n \t\treturn execute((Object[]) null, context);\n \t}\n \n+\t/**\n+\t * Convenient method to stream without parameters.\n+\t * @param context the contextual information for object creation\n+\t */\n+\tpublic Stream stream(Map context) throws DataAccessException {\n+\t\treturn stream(null, context);\n+\t}\n+\n \t/**\n \t * Convenient method to execute without parameters nor context.\n \t */\n@@ -119,6 +158,13 @@ public List execute() throws DataAccessException {\n \t\treturn execute((Object[]) null, null);\n \t}\n \n+\t/**\n+\t * Convenient method to stream without parameters nor context.\n+\t */\n+\tpublic Stream stream() throws DataAccessException {\n+\t\treturn stream(null, null);\n+\t}\n+\n \t/**\n \t * Convenient method to execute with a single int parameter and context.\n \t * @param p1 single int parameter\n@@ -202,13 +248,23 @@ public List execute(String p1) throws DataAccessException {\n \t * will be of the same class, although it is possible to use different types.\n \t */\n \tpublic List executeByNamedParam(Map paramMap, @Nullable Map context) throws DataAccessException {\n-\t\tvalidateNamedParameters(paramMap);\n-\t\tParsedSql parsedSql = getParsedSql();\n-\t\tMapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap);\n-\t\tString sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);\n-\t\t@Nullable Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters());\n-\t\tRowMapper rowMapper = newRowMapper(params, context);\n-\t\treturn getJdbcTemplate().query(newPreparedStatementCreator(sqlToUse, params), rowMapper);\n+\t\treturn queryByNamedParam(paramMap, context, getJdbcTemplate()::query);\n+\t}\n+\n+\t/**\n+\t * Central stream method. All named parameter execution goes through this method.\n+\t * @param paramMap parameters associated with the name specified while declaring\n+\t * the SqlParameters. Primitive parameters must be represented by their Object wrapper\n+\t * type. The ordering of parameters is not significant since they are supplied in a\n+\t * SqlParameterMap which is an implementation of the Map interface.\n+\t * @param context the contextual information passed to the {@code mapRow}\n+\t * callback method. The JDBC operation itself doesn't rely on this parameter,\n+\t * but it can be useful for creating the objects of the result list.\n+\t * @return a Stream of objects, one per row of the ResultSet. Normally all these\n+\t * will be of the same class, although it is possible to use different types.\n+\t */\n+\tpublic Stream streamByNamedParam(Map paramMap, @Nullable Map context) throws DataAccessException {\n+\t\treturn queryByNamedParam(paramMap, context, getJdbcTemplate()::queryForStream);\n \t}\n \n \t/**\n@@ -221,6 +277,15 @@ public List executeByNamedParam(Map param\n \t\treturn executeByNamedParam(paramMap, null);\n \t}\n \n+\t/**\n+\t * Convenient method to stream without context.\n+\t * @param paramMap parameters associated with the name specified while declaring\n+\t * the SqlParameters. Primitive parameters must be represented by their Object wrapper\n+\t * type. The ordering of parameters is not significant.\n+\t */\n+\tpublic Stream streamByNamedParam(Map paramMap) throws DataAccessException {\n+\t\treturn streamByNamedParam(paramMap, null);\n+\t}\n \n \t/**\n \t * Generic object finder method, used by all other {@code findObject} methods.\n@@ -342,4 +407,14 @@ public List executeByNamedParam(Map param\n \t */\n \tprotected abstract RowMapper newRowMapper(@Nullable Object @Nullable [] parameters, @Nullable Map context);\n \n+\tprivate R queryByNamedParam(Map paramMap, @Nullable Map context, BiFunction, R> queryFunction) {\n+\t\tvalidateNamedParameters(paramMap);\n+\t\tParsedSql parsedSql = getParsedSql();\n+\t\tMapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap);\n+\t\tString sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);\n+\t\t@Nullable Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters());\n+\t\tRowMapper rowMapper = newRowMapper(params, context);\n+\t\treturn queryFunction.apply(newPreparedStatementCreator(sqlToUse, params), rowMapper);\n+\t}\n+\n }\ndiff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java\nindex ce1e0fcc51bf..19257b222803 100644\n--- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java\n+++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java\n@@ -26,6 +26,7 @@\n import java.util.HashMap;\n import java.util.List;\n import java.util.Map;\n+import java.util.stream.Stream;\n \n import javax.sql.DataSource;\n \n@@ -52,6 +53,7 @@\n * @author Trevor Cook\n * @author Thomas Risberg\n * @author Juergen Hoeller\n+ * @author Yanming Zhou\n */\n class SqlQueryTests {\n \n@@ -125,6 +127,72 @@ protected Integer mapRow(ResultSet rs, int rownum, Object @Nullable [] params, @\n \t\tverify(preparedStatement).close();\n \t}\n \n+\t@Test\n+\tvoid testStreamWithoutParams() throws SQLException {\n+\t\tgiven(resultSet.next()).willReturn(true, false);\n+\t\tgiven(resultSet.getInt(1)).willReturn(1);\n+\n+\t\tSqlQuery query = new MappingSqlQueryWithParameters<>() {\n+\t\t\t@Override\n+\t\t\tprotected Integer mapRow(ResultSet rs, int rownum, Object @Nullable [] params, @Nullable Map context)\n+\t\t\t\t\tthrows SQLException {\n+\t\t\t\tassertThat(params).as(\"params were null\").isNull();\n+\t\t\t\tassertThat(context).as(\"context was null\").isNull();\n+\t\t\t\treturn rs.getInt(1);\n+\t\t\t}\n+\t\t};\n+\t\tquery.setDataSource(dataSource);\n+\t\tquery.setSql(SELECT_ID);\n+\t\tquery.compile();\n+\t\ttry (Stream stream = query.stream()) {\n+\t\t\tList list = stream.toList();\n+\t\t\tassertThat(list).containsExactly(1);\n+\t\t}\n+\t\tverify(connection).prepareStatement(SELECT_ID);\n+\t\tverify(resultSet).close();\n+\t\tverify(preparedStatement).close();\n+\t}\n+\n+\t@Test\n+\tvoid testStreamByNamedParam() throws SQLException {\n+\t\tgiven(resultSet.next()).willReturn(true, false);\n+\t\tgiven(resultSet.getInt(\"id\")).willReturn(1);\n+\t\tgiven(resultSet.getString(\"forename\")).willReturn(\"rod\");\n+\t\tgiven(connection.prepareStatement(SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED,\n+\t\t\t\tResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)\n+\t\t).willReturn(preparedStatement);\n+\n+\t\tSqlQuery query = new MappingSqlQueryWithParameters<>() {\n+\t\t\t@Override\n+\t\t\tprotected Customer mapRow(ResultSet rs, int rownum, Object @Nullable [] params, @Nullable Map context)\n+\t\t\t\t\tthrows SQLException {\n+\t\t\t\tassertThat(params).as(\"params were not null\").isNotNull();\n+\t\t\t\tassertThat(context).as(\"context was null\").isNull();\n+\t\t\t\tCustomer cust = new Customer();\n+\t\t\t\tcust.setId(rs.getInt(COLUMN_NAMES[0]));\n+\t\t\t\tcust.setForename(rs.getString(COLUMN_NAMES[1]));\n+\t\t\t\treturn cust;\n+\t\t\t}\n+\t\t};\n+\t\tquery.declareParameter(new SqlParameter(\"id\", Types.NUMERIC));\n+\t\tquery.declareParameter(new SqlParameter(\"country\", Types.VARCHAR));\n+\t\tquery.setDataSource(dataSource);\n+\t\tquery.setSql(SELECT_ID_FORENAME_NAMED_PARAMETERS);\n+\t\tquery.compile();\n+\t\ttry (Stream stream = query.streamByNamedParam(Map.of(\"id\", 1, \"country\", \"UK\"))) {\n+\t\t\tList list = stream.toList();\n+\t\t\tassertThat(list).hasSize(1);\n+\t\t\tCustomer customer = list.get(0);\n+\t\t\tassertThat(customer.getId()).isEqualTo(1);\n+\t\t\tassertThat(customer.getForename()).isEqualTo(\"rod\");\n+\t\t}\n+\t\tverify(connection).prepareStatement(SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED);\n+\t\tverify(preparedStatement).setObject(1, 1, Types.NUMERIC);\n+\t\tverify(preparedStatement).setString(2, \"UK\");\n+\t\tverify(resultSet).close();\n+\t\tverify(preparedStatement).close();\n+\t}\n+\n \t@Test\n \tvoid testQueryWithoutEnoughParams() {\n \t\tMappingSqlQuery query = new MappingSqlQuery<>() {\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 31784, "url": "https://github.com/spring-projects/spring-framework/pull/31784", "commits": [{"commit_sha": "dfadac8207bb53e9d44c9efb4ac44a1ae74279d7", "labeled_review_comments": [], "total_score": 0.3361702127659575, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.7}, "patch": "diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLIdentityColumnMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLIdentityColumnMaxValueIncrementer.java\nnew file mode 100644\nindex 000000000000..02d52d732f34\n--- /dev/null\n+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLIdentityColumnMaxValueIncrementer.java\n@@ -0,0 +1,73 @@\n+/*\n+ * Copyright 2002-2023 the original author or authors.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * https://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.springframework.jdbc.support.incrementer;\n+\n+import javax.sql.DataSource;\n+\n+/**\n+ * {@link DataFieldMaxValueIncrementer} that increments the maximum counter value of an\n+ * auto-increment column of a given MySQL table.\n+ *\n+ *

The sequence is kept in a table. The storage engine used by the sequence table must be\n+ * InnoDB in MySQL 8.0 or later since the current maximum auto-increment counter is required to be\n+ * persisted across restarts of the database server.\n+ *\n+ *

Example:\n+ *\n+ *

\n+ * create table tab_sequence (`id` bigint unsigned primary key auto_increment);
\n+ *\n+ *

If {@code cacheSize} is set, the intermediate values are served without querying the\n+ * database. If the server or your application is stopped or crashes or a transaction\n+ * is rolled back, the unused values will never be served. The maximum hole size in\n+ * numbering is consequently the value of {@code cacheSize}.\n+ *\n+ * @author Henning P\u00f6ttker\n+ * @since 6.1.2\n+ */\n+public class MySQLIdentityColumnMaxValueIncrementer extends AbstractIdentityColumnMaxValueIncrementer {\n+\n+\t/**\n+\t * Default constructor for bean property style usage.\n+\t * @see #setDataSource\n+\t * @see #setIncrementerName\n+\t * @see #setColumnName\n+\t */\n+\tpublic MySQLIdentityColumnMaxValueIncrementer() {\n+\t}\n+\n+\t/**\n+\t * Convenience constructor.\n+\t * @param dataSource the DataSource to use\n+\t * @param incrementerName the name of the sequence table to use\n+\t * @param columnName the name of the column in the sequence table to use\n+\t */\n+\tpublic MySQLIdentityColumnMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) {\n+\t\tsuper(dataSource, incrementerName, columnName);\n+\t}\n+\n+\t@Override\n+\tprotected String getIncrementStatement() {\n+\t\treturn \"insert into \" + getIncrementerName() + \" () values ()\";\n+\t}\n+\n+\t@Override\n+\tprotected String getIdentityStatement() {\n+\t\treturn \"select last_insert_id()\";\n+\t}\n+\n+}\ndiff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/DataFieldMaxValueIncrementerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/DataFieldMaxValueIncrementerTests.java\nindex 0fb7a6cbfbed..95610de294c7 100644\n--- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/DataFieldMaxValueIncrementerTests.java\n+++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/incrementer/DataFieldMaxValueIncrementerTests.java\n@@ -133,6 +133,33 @@ void hsqlMaxValueIncrementerWithDeleteSpecificValues() throws SQLException {\n \t\tverify(connection, times(2)).close();\n \t}\n \n+\t@Test\n+\tvoid mySQLIdentityColumnMaxValueIncrementer() throws SQLException {\n+\t\tgiven(dataSource.getConnection()).willReturn(connection);\n+\t\tgiven(connection.createStatement()).willReturn(statement);\n+\t\tgiven(statement.executeQuery(\"select last_insert_id()\")).willReturn(resultSet);\n+\t\tgiven(resultSet.next()).willReturn(true);\n+\t\tgiven(resultSet.getLong(1)).willReturn(1L, 2L, 3L, 4L);\n+\n+\t\tMySQLIdentityColumnMaxValueIncrementer incrementer = new MySQLIdentityColumnMaxValueIncrementer();\n+\t\tincrementer.setDataSource(dataSource);\n+\t\tincrementer.setIncrementerName(\"myseq\");\n+\t\tincrementer.setColumnName(\"seq\");\n+\t\tincrementer.setCacheSize(2);\n+\t\tincrementer.setPaddingLength(1);\n+\t\tincrementer.afterPropertiesSet();\n+\n+\t\tassertThat(incrementer.nextIntValue()).isEqualTo(1);\n+\t\tassertThat(incrementer.nextLongValue()).isEqualTo(2);\n+\t\tassertThat(incrementer.nextStringValue()).isEqualTo(\"3\");\n+\t\tassertThat(incrementer.nextLongValue()).isEqualTo(4);\n+\n+\t\tverify(statement, times(4)).executeUpdate(\"insert into myseq () values ()\");\n+\t\tverify(resultSet, times(4)).close();\n+\t\tverify(statement, times(2)).close();\n+\t\tverify(connection, times(2)).close();\n+\t}\n+\n \t@Test\n \tvoid mySQLMaxValueIncrementer() throws SQLException {\n \t\tgiven(dataSource.getConnection()).willReturn(connection);\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 31699, "url": "https://github.com/spring-projects/spring-framework/pull/31699", "commits": [{"commit_sha": "acecf3753ff9f0b8856c56b4605ddc4d1a975177", "labeled_review_comments": [], "total_score": 0.31063829787234043, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.7}, "patch": "diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java\nindex a3bfd17bc169..2fc9486c50f6 100644\n--- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java\n+++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java\n@@ -49,6 +49,7 @@\n * @author Juergen Hoeller\n * @author Rob Harrop\n * @author Dave Syer\n+ * @author Yanming Zhou\n * @since 2.0\n * @see BeanWrapperImpl\n * @see SimpleTypeConverter\n@@ -178,15 +179,15 @@ else if (requiredType.isArray()) {\n \t\t\t\t\treturn (T) convertToTypedArray(convertedValue, propertyName, requiredType.componentType());\n \t\t\t\t}\n \t\t\t\telse if (convertedValue.getClass().isArray()) {\n-\t\t\t\t\tif (Array.getLength(convertedValue) == 1) {\n-\t\t\t\t\t\tconvertedValue = Array.get(convertedValue, 0);\n-\t\t\t\t\t\tstandardConversion = true;\n-\t\t\t\t\t}\n-\t\t\t\t\telse if (Collection.class.isAssignableFrom(requiredType)) {\n+\t\t\t\t\tif (Collection.class.isAssignableFrom(requiredType)) {\n \t\t\t\t\t\tconvertedValue = convertToTypedCollection(CollectionUtils.arrayToList(convertedValue),\n \t\t\t\t\t\t\t\tpropertyName, requiredType, typeDescriptor);\n \t\t\t\t\t\tstandardConversion = true;\n \t\t\t\t\t}\n+\t\t\t\t\telse if (Array.getLength(convertedValue) == 1) {\n+\t\t\t\t\t\tconvertedValue = Array.get(convertedValue, 0);\n+\t\t\t\t\t\tstandardConversion = true;\n+\t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\telse if (convertedValue instanceof Collection coll) {\n \t\t\t\t\t// Convert elements to target type, if determined.\ndiff --git a/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java b/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java\nindex 170b1b656134..449518aeab33 100644\n--- a/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java\n+++ b/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java\n@@ -48,6 +48,7 @@\n * @author Juergen Hoeller\n * @author Chris Beams\n * @author Sam Brannen\n+ * @author Yanming Zhou\n */\n public class ClassPathXmlApplicationContextTests {\n \n@@ -223,6 +224,10 @@ void resourceArrayPropertyEditor() throws IOException {\n \t\tService service = ctx.getBean(\"service\", Service.class);\n \t\tassertThat(service.getResources()).containsExactlyInAnyOrder(contextA, contextB, contextC);\n \t\tassertThat(service.getResourceSet()).containsExactlyInAnyOrder(contextA, contextB, contextC);\n+\n+\t\tService service3 = ctx.getBean(\"service3\", Service.class);\n+\t\tassertThat(service3.getResources()).containsOnly(new ClassPathResource(FQ_CONTEXT_A));\n+\t\tassertThat(service3.getResourceSet()).containsOnly(new ClassPathResource(FQ_CONTEXT_A));\n \t\tctx.close();\n \t}\n \ndiff --git a/spring-context/src/test/resources/org/springframework/context/support/test/contextA.xml b/spring-context/src/test/resources/org/springframework/context/support/test/contextA.xml\nindex d58a2e82587a..7a140cfdaad3 100644\n--- a/spring-context/src/test/resources/org/springframework/context/support/test/contextA.xml\n+++ b/spring-context/src/test/resources/org/springframework/context/support/test/contextA.xml\n@@ -24,6 +24,11 @@\n \t\t\n \t\n \n+\t\n+\t\t\n+\t\t\n+\t\n+\n \t\n \n \t\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 31619, "url": "https://github.com/spring-projects/spring-framework/pull/31619", "commits": [{"commit_sha": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794", "labeled_review_comments": [{"text": "@user1:\nSince this is specific to Framework (as opposed to the Spring portfolio in general) and is only used once, I suggest we remove it and inline it in `spring-framework-github`.", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"", "line": null, "start_line": null, "original_line": 28, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nA quick search reveals that we're only using that base URL for a single `SPR-` issue.\r\n\r\nSince all `SPR-` issues have been migrated to GitHub, I suggest we remove the `issues-old` attribute.\r\n\r\nIn fact, I'll replace that JIRA link with a GitHub link on `main`.\n\n@author:\n@user1 let's perhaps do the replace in this PR? (this would avoid a merge conflict)\n\n@user1:\nIt turns out the sections related to that SPR issue were obsolete, so I removed them in 617ba845771f8cf6d8f7e30ba8ff66214e97bc54.\r\n\r\nApologies if that causes troubling merge conflicts.", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'", "line": null, "start_line": null, "original_line": 33, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nThis appears to be overridden in `attributes.adoc`.\r\n\r\nDo we need both?\n\n@author:\nI don't think so, not even sure `attributes.adoc` is used anymore in the antora toolchain \ud83e\udd14\r\nactually, let me double check that the whole `src/docs/asciidoc` folder is even relevant at all now...", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'", "line": 19, "start_line": null, "original_line": 19, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": false, "is_resolved": true, "is_outdated": false, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nDo we still need this file?\r\n\r\nIn other words, can we move `chomp` and `fold` to `antora.yml` and remove this one?", "path": "framework-docs/modules/ROOT/pages/attributes.adoc", "diff_hunk": "@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io", "line": null, "start_line": null, "original_line": 2, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}], "total_score": 0.6723404255319149, "rule_results": {"has_resolved_review_comments": true, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..121996a15ef5 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..9e64fc1447ff 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {issues-old}/SPR-10237[SPR-10237]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\n"}, {"commit_sha": "366681fc95787637ac509e23e40b4070e4b7767c", "labeled_review_comments": [{"text": "@user1:\nThis remaining link somehow didn't show up in my local searches.\r\n\r\nIt can be replaced with the [GitHub issue](https://github.com/spring-projects/spring-framework/issues/14870).\r\n\r\n```asciidoc\r\n{spring-framework-issues}/14870[gh-14870]\r\n```\n\n@author:\nthat's my bad, I somehow reintroduced the wrong link / missed the fact that there were 2 jira links in the doc \ud83d\ude2e\u200d\ud83d\udca8 will fix right away", "path": "framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc", "diff_hunk": "@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see {issues-old}/SPR-10237[SPR-10237]\n+unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]", "line": null, "start_line": null, "original_line": 70, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}], "total_score": 0.6723404255319149, "rule_results": {"has_resolved_review_comments": true, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..121996a15ef5 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..c699123e6bc6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\n"}, {"commit_sha": "21c016fe3ecbd8c07903d74397f3d4432148157e", "labeled_review_comments": [], "total_score": 0.4340425531914893, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..c699123e6bc6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\ndiff --git a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties b/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\ndeleted file mode 100644\nindex e1e20afb8446..000000000000\n--- a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-aot=core.aot\n-aot-basics=core.aot.basics\n-aot-refresh=core.aot.refresh\n-aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions\n-aot-bean-registration-contributions=core.aot.bean-registration-contributions\n-aot-hints=core.aot.hints\n-aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints\n-aot-hints-reflective=core.aot.hints.reflective\n-aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/DataAccessException.png b/framework-docs/src/docs/asciidoc/images/DataAccessException.png\ndeleted file mode 100644\nindex 746f17399b99..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/DataAccessException.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png\ndeleted file mode 100644\nindex de6be86ed543..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png\ndeleted file mode 100644\nindex 8ece077d3445..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/container-magic.png b/framework-docs/src/docs/asciidoc/images/container-magic.png\ndeleted file mode 100644\nindex 2628e59b00e8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/container-magic.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png b/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png\ndeleted file mode 100644\nindex 3cf93fa1439c..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png b/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png\ndeleted file mode 100644\nindex 9afd54f57c23..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png\ndeleted file mode 100644\nindex 9c4a950caadb..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\ndeleted file mode 100644\nindex 07148744b549..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\n+++ /dev/null\n@@ -1,612 +0,0 @@\n-\n-\n-\n-image/svg+xmlPage-1DispatcherServlet\n-Servlet WebApplicationContext\n-(containing controllers, view resolvers,and other web-related beans)\n-Controllers\n-ViewResolver\n-HandlerMapping\n-Root WebApplicationContext\n-(containing middle-tier services, datasources, etc.)\n-Services\n-Repositories\n-Delegates if no bean found\n-\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\ndeleted file mode 100644\nindex 4b72bf45285b..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\n+++ /dev/null\n@@ -1,1619 +0,0 @@\n-\n-\n-\n-\n-\tActiveLayerIndex\n-\t0\n-\tApplicationVersion\n-\t\n-\t\tcom.omnigroup.OmniGraffle\n-\t\t137.11.0.108132\n-\t\n-\tAutoAdjust\n-\t\n-\tBackgroundGraphic\n-\t\n-\t\tBounds\n-\t\t{{0, 0}, {756, 553}}\n-\t\tClass\n-\t\tSolidGraphic\n-\t\tID\n-\t\t2\n-\t\tStyle\n-\t\t\n-\t\t\tshadow\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\tstroke\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\n-\t\n-\tCanvasOrigin\n-\t{0, 0}\n-\tColumnAlign\n-\t1\n-\tColumnSpacing\n-\t36\n-\tCreationDate\n-\t2009-09-11 10:15:26 -0400\n-\tCreator\n-\tThomas Risberg\n-\tDisplayScale\n-\t1 0/72 in = 1 0/72 in\n-\tGraphDocumentVersion\n-\t6\n-\tGraphicsList\n-\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t42\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{334.726, 144}\n-\t\t\t\t{394.042, 102.288}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t41\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{489.5, 143.713}\n-\t\t\t\t{430.452, 102.287}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t40\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{230, 217}\n-\t\t\t\t{275.683, 175.337}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t39\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{430.381, 216.81}\n-\t\t\t\t{329.369, 175.19}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\tTail\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t5\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{56, 217}, {249, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t6\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{325.5, 217}, {283.5, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t5\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 UnmarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{184, 145}, {217, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t4\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{430, 145}, {239, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t3\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 ValidationFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{294, 72}, {244, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t1\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tStyle\n-\t\t\t\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\i\\fs36 \\cf0 XmlMappingException}\n-\t\t\t\n-\t\t\tWrap\n-\t\t\tNO\n-\t\t\n-\t\n-\tGridInfo\n-\t\n-\tGuidesLocked\n-\tNO\n-\tGuidesVisible\n-\tYES\n-\tHPages\n-\t1\n-\tImageCounter\n-\t1\n-\tKeepToScale\n-\t\n-\tLayers\n-\t\n-\t\t\n-\t\t\tLock\n-\t\t\tNO\n-\t\t\tName\n-\t\t\tLayer 1\n-\t\t\tPrint\n-\t\t\tYES\n-\t\t\tView\n-\t\t\tYES\n-\t\t\n-\t\n-\tLayoutInfo\n-\t\n-\t\tAnimate\n-\t\tNO\n-\t\tcircoMinDist\n-\t\t18\n-\t\tcircoSeparation\n-\t\t0.0\n-\t\tlayoutEngine\n-\t\tdot\n-\t\tneatoSeparation\n-\t\t0.0\n-\t\ttwopiSeparation\n-\t\t0.0\n-\t\n-\tLinksVisible\n-\tNO\n-\tMagnetsVisible\n-\tNO\n-\tMasterSheets\n-\t\n-\tModificationDate\n-\t2009-09-11 10:38:54 -0400\n-\tModifier\n-\tThomas Risberg\n-\tNotesVisible\n-\tNO\n-\tOrientation\n-\t2\n-\tOriginVisible\n-\tNO\n-\tPageBreaks\n-\tYES\n-\tPrintInfo\n-\t\n-\t\tNSBottomMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t41\n-\t\t\n-\t\tNSLeftMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSOrientation\n-\t\t\n-\t\t\tint\n-\t\t\t1\n-\t\t\n-\t\tNSPaperSize\n-\t\t\n-\t\t\tsize\n-\t\t\t{792, 612}\n-\t\t\n-\t\tNSRightMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSTopMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\n-\tPrintOnePage\n-\t\n-\tQuickLookPreview\n-\t\n-\tJVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls\n-\tdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA\n-\tDRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p\n-\tT84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf\n-\thIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk\n-\tc56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9\n-\tBPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt\n-\toO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj\n-\tAHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY\n-\tv19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT\n-\tz2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm\n-\ts9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O\n-\t5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W\n-\tcvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI\n-\tx6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW\n-\t6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN\n-\t5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp\n-\thZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf\n-\twCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N\n-\tYfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i\n-\tago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50\n-\tIDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb\n-\tMCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv\n-\tVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg\n-\tMTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw\n-\tIDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0\n-\tIDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8\n-\tPCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp\n-\tZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg\n-\tUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh\n-\tbQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz\n-\tNAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg\n-\tL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK\n-\tMjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G\n-\tbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox\n-\tMyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl\n-\tIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D\n-\tb2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg\n-\tL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK\n-\tZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T\n-\tdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw\n-\tIDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh\n-\tdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i\n-\tago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg\n-\tL0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T\n-\tTWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k\n-\tZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0\n-\tcmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg\n-\tMjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I\n-\tZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50\n-\tIDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2\n-\t9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG\n-\tzfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA\n-\tHfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9\n-\tCPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp\n-\t4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW\n-\tFxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg\n-\tNBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW\n-\tpBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I\n-\thGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD\n-\trJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih\n-\tbEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1\n-\tSi4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2\n-\tC5sV5JJUSYElAe4GJYBgttEer782FGlobmvv6OzqjqGId6C7q7Ojva25IRKq9Xs9tI29\n-\tIJQySAqHrge4HPLyJfICjd5spSt8NcFoU+vZc7Efe3r7LsXjl1FEOxCPX+rr7fkxdu5s\n-\ta1M0WOOroK1mvaaATQqHrofsE/AECSlBZ6Lsbm9NqL7lTNf5nr741f6fB4euDaOIduDa\n-\t0ODP/VfjfT3nu8601IdqvG47ZdJBUoAnyYOFAns5QJWg0VtKXYw/WN/aEbtw8Ur/4PCN\n-\tm4lbIyjCHbiVuHljeLD/ysULsY7W+qCfcZVa9Bq2UoDr4cuPGZMkKAq1JspR4auNAgi9\n-\t8f6h64mR0Tt3x+6hCHdg7O6d0ZHE9aH+eC+gEK31VTgok7ZQkZKEPJFUqS4221xMVajp\n-\tTKz38sBwYuTO2Pj9iYeTKMIdeDhxf3zszkhieOByb+xMU6iKcdnMxWqlVJR3KCcI8kQy\n-\t9nIoc/sCkbauC/GBXxKjY79PTD5+Mv0URbgD008eT078Pjaa+GUgfqGrLRLwucvY60Em\n-\tgpLxwO0gEIrlBVoj5fD4v2s4e/7iT8OJ0XsPJqdmZucWFhZRRDuwsDA3OzM1+eDeaGL4\n-\tp4vnzzZ85/c4KKO2QC4WpiBBIocywepkqsPN53quDAIIE4+mZ+eXni2/WEER7cCL5WdL\n-\t87PTjyYAhcErPeeaw9WM0wqFglySggR4dFAXf1Na7oXLIdbXf33ktwePZuYWn6+svlx7\n-\thSLagbWXqyvPF+dmHj34beR6f18Mrgdveek3xWp4eDiUE+AhUqFmy4TKuvr2H+KDidvj\n-\tk9NzS8t/rr1e33iDItqBjfXXa38uL81NT47fTgzGf2ivr6tkCwU1+/BwsE4AEpRAgt3j\n-\tDzZ29FwdHhmbmJpdXF59tfFmc2sbRbQDW5tvNl6tLi/OTk2MjQxf7eloDPo9diBBmZIE\n-\tqbJIXwIFY6ips7f/xq/jkzPzzwGEze23OyjCHXi7vQkoPJ+fmRz/9UZ/b2dTCErGEn2R\n-\tUpoqJ0hVRQaK/rY63NLVN3Dz9v3HfyytrK1vbu+8e7+LItqB9+92tjfX11aW/nh8//bN\n-\tgb6ulnD1tzRlKFIdQYLGSNFMTaS1+9Jg4u7E1Nyz1dd/be282/2AItyB3Xc7W3+9Xn02\n-\tNzVxNzF4qbs1UsPQlFFzNAnwEAkkfB8fujX28Mn88sv1zbcAwsdPKKId+Phh993bzfWX\n-\ty/NPHo7dGop/z5LgtB5LQlssfm3k3uTMwou1ja2d9wDCZxTRDnz6+OH9ztbG2ouFmcl7\n-\tI9fi8Bh5FAnwpXS+VKUxJnNCChL+RhHswGduEr74+7XsnFz42gE+YnSdDERPxy4PQ054\n-\turjy6s32zu6HT58JdgG3Dg58/vRhd2f7zauVxaeQE4Yvx05HAydd8CEjfPGQm4Mk8AcS\n-\tJIE/seY+KZLA7Q9/VpEE/sSa+6RIArc//FlFEvgTa+6TIgnc/vBnFUngT6y5T4okcPvD\n-\tn1UkgT+x5j4pksDtD39WkQT+xJr7pEgCtz/8WUUS+BNr7pMiCdz+8GcVSeBPrLlPiiRw\n-\t+8OfVSSBP7HmPimSwO0Pf1aRBP7EmvukSAK3P/xZRRL4E2vukyIJ3P7wZxVJ4E+suU+K\n-\tJHD7w59VJIE/seY+KZLA7Q9/VtMhAd+QzWAu0nlDNusYEoh+Zxw3z/2u9IHOnP/11jx2\n-\t0iC6bUaKzf8PnTSwuw7hbXSO2H663XWw4xbRfbWO3ny6HbewCx/hvfaO3n56XfiwMyfR\n-\t3Te5Np9mZ07s1kt0R16uzafVrVeAHbyJbtLNufm0OngLhNjVn+jO/VybT6+rP076IHqY\n-\tB+fm05v0gdN/CJ/ww7X9dKb/5OBEMMKnfnFtP52JYOy8SJwSSPgwwCO3n9aUQJwcSvh0\n-\tUK7tpzE5FKcJEz0u+JjNpzNNGCeMEz1C/JjNpzdhHAoFMYwY1xrMNtrj9deGIg3Nbe0d\n-\tnV3dMRTxDnR3dXa0tzU3REK1fq+HtpkNWhgwLmbHSn/RwDsrKxsGS+exM8YBBYuNdjO+\n-\tqkAwHK1vbGppbTuNItyBttaWpsb6aDgYqPIxbtpmARDY+eJ5h0kAFASQFKSAgs5gttpd\n-\tFYzPXx2oC4bCkUgkiiLaAQhhOBSsC1T7fUyFy241G3QAghRSguBgSvh3UhDLFGxWMFOl\n-\tDpfbw3grT/mra0ABFMEOsBGs9p+q9DIet8tRSrFXg0oBd0OqlAA5AZKCMF+SREFvslC2\n-\tMtpZ7vZ4GIY5iSLcAQiix+Mud9JlNspi0idBkOQLISUczglspQAoiCQyuapQo9ObzBbK\n-\tWlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN\n-\tVm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa\n-\tUMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS\n-\tKZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a\n-\tBLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF\n-\tvAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD\n-\te9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK\n-\tZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv\n-\tTGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo\n-\tIDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv\n-\tbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH\n-\tBQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF\n-\txohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk\n-\tgASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw\n-\tXgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt\n-\t1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os\n-\tWsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj\n-\t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\n-\tWX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B\n-\tgwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl\n-\tbmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw\n-\tIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo\n-\tdCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv\n-\tRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu\n-\tueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521\n-\tCzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB\n-\tdJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5\n-\tkBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR\n-\tCf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo\n-\tIh2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q\n-\tU0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke\n-\t6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH\n-\tlA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C\n-\tpQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo\n-\tHRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF\n-\t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\n-\tYQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA\n-\tJNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji\n-\tHHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK\n-\tUAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo\n-\t5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K\n-\tO/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I\n-\tpDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als\n-\tJB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv\n-\t8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu\n-\tZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg\n-\tUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0\n-\tIDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G\n-\taWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z\n-\tUui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+\n-\tZ4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K\n-\tIQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo\n-\tIh34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ\n-\t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\n-\tKjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz\n-\tiHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW\n-\tIsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY\n-\tEqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy\n-\tcsFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p\n-\tcvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX\n-\tmVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O\n-\tFJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb\n-\tuFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV\n-\t7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL\n-\tVPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL\n-\tv8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k\n-\tb2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS\n-\tIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg\n-\tMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7\n-\tpXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn\n-\t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\n-\tkC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C\n-\tL4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz\n-\tNyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k\n-\tb2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2\n-\taWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ\n-\t953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99\n-\t+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC\n-\tBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA\n-\tCDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ\n-\tABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh\n-\tBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT\n-\tgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB\n-\toGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp\n-\tfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS\n-\tVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f\n-\t/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4\n-\tv3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc\n-\tJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8\n-\tLKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc\n-\tph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ\n-\tUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu\n-\tH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+\n-\tOL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC\n-\tr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E\n-\tQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz\n-\tQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC\n-\tqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+\n-\tqr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y\n-\t5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr\n-\t+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy\n-\tejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV\n-\tLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9\n-\tTsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag\n-\t7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/\n-\tF3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9\n-\tt3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO\n-\tLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA\n-\tlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp\n-\tO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz\n-\tbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x\n-\tnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI\n-\t8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI\n-\taDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl\n-\tS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs\n-\tUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne\n-\tpb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik\n-\tc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi\n-\ttL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+\n-\tUIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs\n-\t5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+\n-\t7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k\n-\tnpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp\n-\tJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm\n-\tfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB\n-\t2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb\n-\tfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y\n-\t2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0\n-\tCmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv\n-\tYmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ\n-\tQ0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97\n-\tzue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw\n-\tyU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx\n-\tQcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1\n-\tCtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5\n-\tE4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk\n-\tBB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/\n-\t7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG\n-\twA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7\n-\tqbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D\n-\t+4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy\n-\tTPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx\n-\tRHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB\n-\tT01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64\n-\tcrm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn\n-\tE7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f\n-\te6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM\n-\t6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///\n-\tXfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj\n-\tdvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz\n-\tNMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE\n-\tKsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU\n-\trkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t\n-\tGe2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG\n-\tE5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd\n-\tKa2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV\n-\t/JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL\n-\tV6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H\n-\tg0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx\n-\t2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+\n-\tWLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3\n-\thi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN\n-\t1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ\n-\tfH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t\n-\taq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj\n-\t3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB\n-\t6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR\n-\trZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8\n-\t+KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3\n-\tJaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q\n-\tQMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf\n-\teJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF\n-\t9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa\n-\ttEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h\n-\tnaa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+\n-\tIwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN\n-\thsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI\n-\tq2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz\n-\tZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe\n-\tM3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri\n-\tJ7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn\n-\tN0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0\n-\tIDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu\n-\tZ3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2\n-\t2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf\n-\t5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i\n-\tTeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH\n-\ttSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU\n-\tM0gAsI8D6+uJA4BVA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAF\n-\tYcAbRAEbYAusARIYgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE\n-\t8tCzHwiFpyCBGSACLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR\n-\t+QEwoPx2PD90zr0AZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6x\n-\tFXCF908AuaAG9IHn4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mE\n-\taJxo8mmmaflpXWmv0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0ya\n-\tTNXMPMxnmbdZiCxvWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35\n-\tlwRSBNGCk0JxwijhaZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+\n-\t8noKwgrfFV8p3T1YjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3Sjk\n-\tyBnjYpM203GzdQtWS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlg\n-\ts3GvfdTx2b7v/Y0Dqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy\n-\t0kTTm8+ZZi5mn7rAn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+\n-\tJb7NtkPmFuia7e7sLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mX\n-\tZJa1V+xXCWtpH69vDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvk\n-\tfuhANCSOOCi+P+Euf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7L\n-\tnPqQnwOhlcKqex7IuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxf\n-\tGHFM4yzarLXsPBxJnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVK\n-\te8tYopRlBeWo5N6jx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQj\n-\toEuj+0FvTf83g/eGK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxO\n-\tuDkGOSU4n3cpP9ns2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PG\n-\tScvk72Ec4TIROpF2UX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKq\n-\tzpVnlmSdzvY5b35BMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpby\n-\ttavDFdWVZ6qw1/SrRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JH\n-\tX2fprbgu19ta3YLdX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yj\n-\tb8baHqU8NnpC9eTO+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iph\n-\tHjP/dqFg0WLxr9eNb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8C\n-\tlQt1Gk0H7RIdB70eA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtw\n-\tQ2hEuEokQVRQtB15DLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B2\n-\t8gj5egUXRQbFdiXcQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntI\n-\tJ1v3uJ6g3qJ+tUGgIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWy\n-\tXbcbsq88nukQccLD0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1\n-\te+d/JyA/MIhgTBQhbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC\n-\t4+0SVBN5E7+efpnUm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5v\n-\tzujFjFzzPPq8wUtn840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrd\n-\tqu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24\n-\tfagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1\n-\tYfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6\n-\tCekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P\n-\tgV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV\n-\t6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc\n-\tjvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q\n-\tteDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0\n-\tVDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS\n-\t9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH\n-\tT2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP\n-\txPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb\n-\tvo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ\n-\tCmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv\n-\tSUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS\n-\tIC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+\n-\tPgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj\n-\tszPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE\n-\tbZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2\n-\tPbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R\n-\tU+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j\n-\tnEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9\n-\tAHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e\n-\tLQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3\n-\t0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB\n-\tVnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE\n-\tj9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9\n-\tg0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx\n-\tW6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08\n-\tCT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK\n-\tZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD\n-\tQ0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv\n-\tTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz\n-\tdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC\n-\tkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN\n-\tAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN\n-\tkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC\n-\t72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV\n-\tA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY\n-\tgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC\n-\tLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A\n-\tZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn\n-\t4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv\n-\t0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv\n-\tWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh\n-\taZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y\n-\tjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW\n-\tS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D\n-\tqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA\n-\tn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s\n-\tLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v\n-\tDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu\n-\tf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I\n-\tuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ\n-\tnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j\n-\tx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG\n-\tK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns\n-\t2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2\n-\tUX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B\n-\tMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr\n-\tRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd\n-\tX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO\n-\t+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN\n-\tb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e\n-\tA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15\n-\tDLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc\n-\tQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg\n-\tIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD\n-\t0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh\n-\tbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU\n-\tm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn\n-\t840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek\n-\t1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z\n-\trsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp\n-\tfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj\n-\tD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6\n-\tRhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k\n-\tyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf\n-\tura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw\n-\t6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ\n-\tmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV\n-\tyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9\n-\tL3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0\n-\tmboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm\n-\tlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl\n-\tbmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg\n-\tMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy\n-\tbmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X\n-\tiTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR\n-\tvT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd\n-\tnZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT\n-\tTf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5\n-\tUnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI\n-\tbXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ\n-\twVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI\n-\teNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D\n-\toOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD\n-\tZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO\n-\tgC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd\n-\t2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD\n-\tbmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz\n-\tVdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT\n-\ttjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk\n-\t6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h\n-\tXREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5\n-\tiBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/\n-\tt8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU\n-\tzsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw\n-\tx8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB\n-\t/CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH\n-\tj2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt\n-\tumi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb\n-\tS4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2\n-\txT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15\n-\tlZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y\n-\tI67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf\n-\tdehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD\n-\tp+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ\n-\tl9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE\n-\tqy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc\n-\tUfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn\n-\tKhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz\n-\tE1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6\n-\tyRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ\n-\tn8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq\n-\tbOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r\n-\twozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub\n-\tvHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy\n-\terV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ\n-\tc1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+\n-\tUiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF\n-\tdVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2\n-\tYT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck\n-\teDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa\n-\tGBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv\n-\tMl78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o\n-\tWaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698\n-\tz2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p\n-\tzDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS\n-\tgMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw\n-\tIG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv\n-\tYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g\n-\tL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw\n-\tZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg\n-\tMCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF\n-\tTFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5\n-\tdWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta\n-\tmg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN\n-\tFHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv\n-\tkX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg\n-\tNa1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS\n-\tqo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr\n-\t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\n-\tMlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+\n-\tW73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1\n-\t8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT\n-\ti91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph\n-\tWq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d\n-\tCAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx\n-\thdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp\n-\toU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u\n-\tuo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr\n-\tAa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8\n-\trYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK\n-\tPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3\n-\tIC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg\n-\tMTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu\n-\tZ2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG\n-\taWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg\n-\tODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1\n-\tMDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg\n-\tMjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi\n-\tdHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg\n-\tL0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5\n-\tIC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i\n-\tago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg\n-\tL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD\n-\tSMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW\n-\tj2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n\n-\t4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u\n-\t7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM\n-\tF69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl\n-\tAN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq\n-\t6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn\n-\taby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO\n-\ttsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81\n-\t8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8\n-\t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\n-\tVrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a\n-\tiVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2\n-\tIDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv\n-\tciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz\n-\tMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT\n-\tK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg\n-\tL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK\n-\tNTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy\n-\tMiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1\n-\tNTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg\n-\tMCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry\n-\tdWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK\n-\tNTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv\n-\tRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp\n-\tdGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP\n-\tbW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv\n-\tbnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k\n-\tRGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK\n-\tMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg\n-\tMDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw\n-\tMDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw\n-\tMDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw\n-\tMDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw\n-\tMCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw\n-\tNDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg\n-\tbiAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw\n-\tNzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g\n-\tCjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0\n-\tIDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow\n-\tMDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw\n-\tMDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw\n-\tMDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw\n-\tMDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw\n-\tMjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw\n-\tIG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw\n-\tMTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu\n-\tIAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3\n-\tNyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK\n-\tMDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg\n-\tMDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw\n-\tMDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw\n-\tMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS\n-\tIC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk\n-\tYTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP\n-\tRgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo\n-\tRDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE\n-\tYXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR\n-\tdWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg\n-\tMQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3\n-\tZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm\n-\tMDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5\n-\tPj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==\n-\t\n-\tQuickLookThumbnail\n-\t\n-\t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\n-\tAdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH\n-\tvggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe\n-\tEuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki\n-\t1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy\n-\tOSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU\n-\taFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF\n-\tdvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e\n-\tYaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB\n-\tzfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j\n-\tdXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY\n-\tAPIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F\n-\togXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l\n-\tD14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd\n-\t1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn\n-\tMpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M\n-\tMk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul\n-\tbQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS\n-\tuZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y\n-\twHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry\n-\t7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO\n-\tAF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD\n-\t4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ\n-\tDDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ\n-\tQxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO\n-\tLGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E\n-\tcUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+\n-\tY49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H\n-\tjokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu\n-\ts3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk\n-\tKOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog\n-\tAAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA\n-\teQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw\n-\tADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2\n-\tY2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh\n-\tF2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v\n-\thzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk\n-\tR+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh\n-\t+WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr\n-\tfcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV\n-\tpJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+\n-\trF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC\n-\tNcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq\n-\t1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o\n-\tBOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt\n-\tEogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l\n-\tKSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy\n-\tNqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ\n-\tikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V\n-\tYH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1\n-\tVHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK\n-\tiwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud\n-\tOp34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N\n-\tr3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA\n-\tUsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI\n-\tEoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm\n-\tkydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc\n-\tON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N\n-\tc05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj\n-\tZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+\n-\tcX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6\n-\tlp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut\n-\trq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7\n-\tyNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo\n-\t4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA\n-\t9SH////2AAABX////RUAARx2\n-\t\n-\tReadOnly\n-\tNO\n-\tRowAlign\n-\t1\n-\tRowSpacing\n-\t36\n-\tSheetTitle\n-\tCanvas 1\n-\tSmartAlignmentGuidesActive\n-\tYES\n-\tSmartDistanceGuidesActive\n-\tYES\n-\tUniqueID\n-\t1\n-\tUseEntirePage\n-\t\n-\tVPages\n-\t1\n-\tWindowInfo\n-\t\n-\t\tCurrentSheet\n-\t\t0\n-\t\tExpandedCanvases\n-\t\t\n-\t\t\t\n-\t\t\t\tname\n-\t\t\t\tCanvas 1\n-\t\t\t\n-\t\t\n-\t\tFrame\n-\t\t{{218, 52}, {999, 826}}\n-\t\tListView\n-\t\t\n-\t\tOutlineWidth\n-\t\t142\n-\t\tRightSidebar\n-\t\t\n-\t\tShowRuler\n-\t\t\n-\t\tSidebar\n-\t\t\n-\t\tSidebarWidth\n-\t\t120\n-\t\tVisibleRegion\n-\t\t{{-54, -59}, {864, 672}}\n-\t\tZoom\n-\t\t1\n-\t\tZoomValues\n-\t\t\n-\t\t\t\n-\t\t\t\tCanvas 1\n-\t\t\t\t1\n-\t\t\t\t1\n-\t\t\t\n-\t\t\n-\t\n-\tsaveQuickLookFiles\n-\tYES\n-\n-\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png\ndeleted file mode 100644\nindex 8515e7c4887a..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/prototype.png b/framework-docs/src/docs/asciidoc/images/prototype.png\ndeleted file mode 100644\nindex 26fa2c1cf2d9..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/prototype.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/singleton.png b/framework-docs/src/docs/asciidoc/images/singleton.png\ndeleted file mode 100644\nindex 591520ec1dcc..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/singleton.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png\ndeleted file mode 100644\nindex 6e0eeab744d4..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx.png b/framework-docs/src/docs/asciidoc/images/tx.png\ndeleted file mode 100644\nindex 06f2e77c76f8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png b/framework-docs/src/docs/asciidoc/images/tx_prop_required.png\ndeleted file mode 100644\nindex 218790aca635..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png b/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png\ndeleted file mode 100644\nindex a8ece48193f3..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/index-docinfo-header.html b/framework-docs/src/docs/asciidoc/index-docinfo-header.html\ndeleted file mode 100644\nindex 485f2e4e9803..000000000000\n--- a/framework-docs/src/docs/asciidoc/index-docinfo-header.html\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-

\n-

Spring Framework Documentation

\n-\n-{revnumber}\n-
\ndiff --git a/framework-docs/src/docs/asciidoc/spring-framework.adocbook b/framework-docs/src/docs/asciidoc/spring-framework.adocbook\ndeleted file mode 100644\nindex e020f7337c2d..000000000000\n--- a/framework-docs/src/docs/asciidoc/spring-framework.adocbook\n+++ /dev/null\n@@ -1,26 +0,0 @@\n-:noheader:\n-:toc:\n-:toclevels: 4\n-:tabsize: 4\n-include::attributes.adoc[]\n-= Spring Framework Documentation\n-Rod Johnson; Juergen Hoeller; Keith Donald; Colin Sampaleanu; Rob Harrop; Thomas Risberg; Alef Arendsen; Darren Davison; Dmitriy Kopylenko; Mark Pollack; Thierry Templier; Erwin Vervaet; Portia Tung; Ben Hale; Adrian Colyer; John Lewis; Costin Leau; Mark Fisher; Sam Brannen; Ramnivas Laddad; Arjen Poutsma; Chris Beams; Tareq Abedrabbo; Andy Clement; Dave Syer; Oliver Gierke; Rossen Stoyanchev; Phillip Webb; Rob Winch; Brian Clozel; Stephane Nicoll; Sebastien Deleuze; Jay Bryant; Mark Paluch\n-\n-NOTE: This documentation is also available in {docs-spring-framework}/reference/html/index.html[HTML] format.\n-\n-[[legal]]\n-== Legal\n-\n-Copyright \u00a9 2002 - 2023 VMware, Inc. All Rights Reserved.\n-\n-Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.\n-\n-include::overview.adoc[leveloffset=+1]\n-include::core.adoc[leveloffset=+1]\n-include::testing.adoc[leveloffset=+1]\n-include::data-access.adoc[leveloffset=+1]\n-include::web.adoc[leveloffset=+1]\n-include::web-reactive.adoc[leveloffset=+1]\n-include::integration.adoc[leveloffset=+1]\n-include::languages.adoc[leveloffset=+1]\n-include::appendix.adoc[leveloffset=+1]\n"}, {"commit_sha": "e481fb2149ffdc1b472cd56fae9cd383e4baf459", "labeled_review_comments": [], "total_score": 0.42978723404255326, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.3}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..a7fd63f2d8a9 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,74 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..c699123e6bc6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\n"}, {"commit_sha": "c771d63a24dd7d420c208af409545b7ec2398bc9", "labeled_review_comments": [], "total_score": 0.42978723404255326, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.3}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..c699123e6bc6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\n"}, {"commit_sha": "fe605cf708ea42d9be5525888404fcddadac892c", "labeled_review_comments": [], "total_score": 0.3914893617021276, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..a455ac6ef278 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {spring-framework-issues}/14870[spring-framework#14870]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\ndiff --git a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties b/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\ndeleted file mode 100644\nindex e1e20afb8446..000000000000\n--- a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-aot=core.aot\n-aot-basics=core.aot.basics\n-aot-refresh=core.aot.refresh\n-aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions\n-aot-bean-registration-contributions=core.aot.bean-registration-contributions\n-aot-hints=core.aot.hints\n-aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints\n-aot-hints-reflective=core.aot.hints.reflective\n-aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/DataAccessException.png b/framework-docs/src/docs/asciidoc/images/DataAccessException.png\ndeleted file mode 100644\nindex 746f17399b99..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/DataAccessException.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png\ndeleted file mode 100644\nindex de6be86ed543..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png\ndeleted file mode 100644\nindex 8ece077d3445..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/container-magic.png b/framework-docs/src/docs/asciidoc/images/container-magic.png\ndeleted file mode 100644\nindex 2628e59b00e8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/container-magic.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png b/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png\ndeleted file mode 100644\nindex 3cf93fa1439c..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png b/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png\ndeleted file mode 100644\nindex 9afd54f57c23..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png\ndeleted file mode 100644\nindex 9c4a950caadb..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\ndeleted file mode 100644\nindex 07148744b549..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\n+++ /dev/null\n@@ -1,612 +0,0 @@\n-\n-\n-\n-image/svg+xmlPage-1DispatcherServlet\n-Servlet WebApplicationContext\n-(containing controllers, view resolvers,and other web-related beans)\n-Controllers\n-ViewResolver\n-HandlerMapping\n-Root WebApplicationContext\n-(containing middle-tier services, datasources, etc.)\n-Services\n-Repositories\n-Delegates if no bean found\n-\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\ndeleted file mode 100644\nindex 4b72bf45285b..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\n+++ /dev/null\n@@ -1,1619 +0,0 @@\n-\n-\n-\n-\n-\tActiveLayerIndex\n-\t0\n-\tApplicationVersion\n-\t\n-\t\tcom.omnigroup.OmniGraffle\n-\t\t137.11.0.108132\n-\t\n-\tAutoAdjust\n-\t\n-\tBackgroundGraphic\n-\t\n-\t\tBounds\n-\t\t{{0, 0}, {756, 553}}\n-\t\tClass\n-\t\tSolidGraphic\n-\t\tID\n-\t\t2\n-\t\tStyle\n-\t\t\n-\t\t\tshadow\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\tstroke\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\n-\t\n-\tCanvasOrigin\n-\t{0, 0}\n-\tColumnAlign\n-\t1\n-\tColumnSpacing\n-\t36\n-\tCreationDate\n-\t2009-09-11 10:15:26 -0400\n-\tCreator\n-\tThomas Risberg\n-\tDisplayScale\n-\t1 0/72 in = 1 0/72 in\n-\tGraphDocumentVersion\n-\t6\n-\tGraphicsList\n-\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t42\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{334.726, 144}\n-\t\t\t\t{394.042, 102.288}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t41\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{489.5, 143.713}\n-\t\t\t\t{430.452, 102.287}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t40\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{230, 217}\n-\t\t\t\t{275.683, 175.337}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t39\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{430.381, 216.81}\n-\t\t\t\t{329.369, 175.19}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\tTail\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t5\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{56, 217}, {249, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t6\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{325.5, 217}, {283.5, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t5\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 UnmarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{184, 145}, {217, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t4\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{430, 145}, {239, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t3\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 ValidationFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{294, 72}, {244, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t1\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tStyle\n-\t\t\t\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\i\\fs36 \\cf0 XmlMappingException}\n-\t\t\t\n-\t\t\tWrap\n-\t\t\tNO\n-\t\t\n-\t\n-\tGridInfo\n-\t\n-\tGuidesLocked\n-\tNO\n-\tGuidesVisible\n-\tYES\n-\tHPages\n-\t1\n-\tImageCounter\n-\t1\n-\tKeepToScale\n-\t\n-\tLayers\n-\t\n-\t\t\n-\t\t\tLock\n-\t\t\tNO\n-\t\t\tName\n-\t\t\tLayer 1\n-\t\t\tPrint\n-\t\t\tYES\n-\t\t\tView\n-\t\t\tYES\n-\t\t\n-\t\n-\tLayoutInfo\n-\t\n-\t\tAnimate\n-\t\tNO\n-\t\tcircoMinDist\n-\t\t18\n-\t\tcircoSeparation\n-\t\t0.0\n-\t\tlayoutEngine\n-\t\tdot\n-\t\tneatoSeparation\n-\t\t0.0\n-\t\ttwopiSeparation\n-\t\t0.0\n-\t\n-\tLinksVisible\n-\tNO\n-\tMagnetsVisible\n-\tNO\n-\tMasterSheets\n-\t\n-\tModificationDate\n-\t2009-09-11 10:38:54 -0400\n-\tModifier\n-\tThomas Risberg\n-\tNotesVisible\n-\tNO\n-\tOrientation\n-\t2\n-\tOriginVisible\n-\tNO\n-\tPageBreaks\n-\tYES\n-\tPrintInfo\n-\t\n-\t\tNSBottomMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t41\n-\t\t\n-\t\tNSLeftMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSOrientation\n-\t\t\n-\t\t\tint\n-\t\t\t1\n-\t\t\n-\t\tNSPaperSize\n-\t\t\n-\t\t\tsize\n-\t\t\t{792, 612}\n-\t\t\n-\t\tNSRightMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSTopMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\n-\tPrintOnePage\n-\t\n-\tQuickLookPreview\n-\t\n-\tJVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls\n-\tdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA\n-\tDRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p\n-\tT84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf\n-\thIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk\n-\tc56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9\n-\tBPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt\n-\toO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj\n-\tAHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY\n-\tv19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT\n-\tz2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm\n-\ts9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O\n-\t5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W\n-\tcvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI\n-\tx6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW\n-\t6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN\n-\t5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp\n-\thZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf\n-\twCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N\n-\tYfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i\n-\tago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50\n-\tIDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb\n-\tMCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv\n-\tVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg\n-\tMTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw\n-\tIDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0\n-\tIDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8\n-\tPCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp\n-\tZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg\n-\tUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh\n-\tbQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz\n-\tNAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg\n-\tL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK\n-\tMjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G\n-\tbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox\n-\tMyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl\n-\tIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D\n-\tb2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg\n-\tL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK\n-\tZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T\n-\tdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw\n-\tIDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh\n-\tdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i\n-\tago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg\n-\tL0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T\n-\tTWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k\n-\tZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0\n-\tcmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg\n-\tMjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I\n-\tZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50\n-\tIDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2\n-\t9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG\n-\tzfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA\n-\tHfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9\n-\tCPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp\n-\t4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW\n-\tFxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg\n-\tNBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW\n-\tpBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I\n-\thGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD\n-\trJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih\n-\tbEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1\n-\tSi4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2\n-\t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\n-\tWlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN\n-\tVm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa\n-\tUMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS\n-\tKZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a\n-\tBLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF\n-\tvAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD\n-\te9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK\n-\tZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv\n-\tTGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo\n-\tIDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv\n-\tbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH\n-\tBQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF\n-\txohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk\n-\tgASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw\n-\tXgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt\n-\t1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os\n-\tWsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj\n-\t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\n-\tWX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B\n-\tgwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl\n-\tbmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw\n-\tIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo\n-\tdCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv\n-\tRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu\n-\tueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521\n-\tCzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB\n-\tdJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5\n-\tkBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR\n-\tCf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo\n-\tIh2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q\n-\tU0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke\n-\t6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH\n-\tlA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C\n-\tpQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo\n-\tHRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF\n-\t42hrOSgdcoBDb7I5GDfrrfQHasN1DZGm5pbzKAIdaGluijTUhWsD/kov62YcNq56qOTJ\n-\tigdHB/QVDcBhdTCecl9NMFTf2NLa3tHVHUUR6UB3V0d7a0tjfShY4yv3MA6uuWiUUDyO\n-\ttRZoLNkSuSqHMlrtTJm3OhCONLd1Ri/19Pb1x2IDKOIciMX6+3p7LkU725oj4UC1t4yx\n-\tW41UDlc8jrWW9Ax4moXSYbDQxe7y6mBd04Wuiz19sWuDPw2PXB9FEefA9ZHhnwavxfp6\n-\tLnZdaKoLVpe7i2mLAYoHPNUeHTy4xgJTB2W0FbpYX6CuuT16+crVweHRm7fit8dQBDpw\n-\tO37r5ujw4NUrl6PtzXUBH+sqtBkpbvKA1vL126UJOtS5egtdUuatCQMcvbHBkRvxsfG7\n-\t9ybuowh0YOLe3fGx+I2RwVgv4BGu8ZaV0BZ9rjopHdlShUaXb3W42Mpg5EK0d2BoND52\n-\td2LywdSjaRSBDjyaejA5cXcsPjo00Bu9EAlWsi6HNV+nUUizj9UOUbZUyTWWIrfXH2rp\n-\tuhwb+jk+PvHb1PSTp7PPUAQ6MPv0yfTUbxPj8Z+HYpe7WkJ+r7uIay1KKYylRzqLSCxT\n-\t5ejNdInH911928UrP47Gx+8/nJ6Zm19YWlpGEefA0tLC/NzM9MP74/HRH69cbKv/zucp\n-\toc36HJVMnIQOuQrGDruTrapt7Oy5OgxwTD2enV9ceb76cg1FnAMvV5+vLM7PPp4CPIav\n-\t9nQ21laxTjsMHip5EjrgkUWX/01haTk0lmjf4I2xXx8+nltYfrG2/mrjNYo4BzZera+9\n-\tWF6Ye/zw17Ebg31RaC3lpYXf5OvgoeVY7YAHWrWOGzsqztW1/hAbjt+ZnJ5dWFn9Y+PN\n-\t5tZbFHEObG2+2fhjdWVhdnryTnw49kNr3bkKbvDQcQ8tR+cOoEMDdBR7fIGG9p5ro2MT\n-\tUzPzy6vrr7febu/soohzYGf77dbr9dXl+ZmpibHRaz3tDQGfpxjo0CSlQ6HJMxbAUBqM\n-\tdPQO3vxlcnpu8QXAsb37bg9FoAPvdrcBjxeLc9OTv9wc7O2IBGEsLTDmaRTJaodCm2ei\n-\tmW+rapu6+oZu3Xnw5PeVtY3N7d299x/2UcQ58OH93u725sbayu9PHty5NdTX1VRb9S1D\n-\tm/K0J9BBmWmGrQ41d/cPx+9NzSw8X3/z587e+/2PKAId2H+/t/Pnm/XnCzNT9+LD/d3N\n-\toWqWoc3UyXTAAy3Q8X1s5PbEo6eLq682t98BHJ8+o4hz4NPH/ffvtjdfrS4+fTRxeyT2\n-\tPUeH034qHS3R2PWx+9NzSy83tnb2PgAcX1DEOfD508cPeztbGy+X5qbvj12PwSPtSXTA\n-\tB/gShZYyJ2pHEjr+QhHmwBd+Or767mB6ZhZ8zAJvlbrO+MPnowOjUDueLa+9fru7t//x\n-\t8xfCnMFwwIEvnz/u7+2+fb22/Axqx+hA9HzYf8YFb5bCBy1ZmUiHsCFBOoSdf/7okQ5+\n-\tf4R9inQIO//80SMd/P4I+xTpEHb++aNHOvj9EfYp0iHs/PNHj3Tw+yPsU6RD2Pnnjx7p\n-\t4PdH2KdIh7Dzzx890sHvj7BPkQ5h558/eqSD3x9hnyIdws4/f/RIB78/wj5FOoSdf/7o\n-\tkQ5+f4R9inQIO//80SMd/P4I+xTpEHb++aNHOvj9EfYp0iHs/PNHj3Tw+yPsU6RD2Pnn\n-\tjx7p4PdH2Kep0IG/shYYK6n8yjrtFDqIu58AA+L/Df6R22z/44YGvN2FuKtckgT0X9zu\n-\tgjdDEXgF1AkhpXozFN4qR9zdcScHlOqtcngjJYH3Tp4cUmo3UuJttsTdWMsXUIq32eJN\n-\t2MTdds0XUEo3YYvwFn3iLsrnDSilW/RFYtzAQdyWDb6AUtvAgdt7iFvQwxtQatt7cPMX\n-\tgdu9+EJKZfNXJm4NJHAzIF9IqWwN5PbR4sZRAheLnhhSShtHcVsxgRuJ+UJKYVsxbjon\n-\tbpX5KQGlsuk8PUOUDe945FBGq50p81YHwpHmts7opZ7evv5YbABFnAOxWH9fb8+laGdb\n-\tcyQcqPaWMXarkcqBnYGwjvara9LT0tK5VecypUanN1kdjKfcVxMM1Te2tLZ3dHVHUUQ6\n-\t0N3V0d7a0lgfCtb4yj2Mw2rS6zRKmSQrMxkdXPHQAh42B+NmvZX+QG24riHS1NxyHkWg\n-\tAy3NTZGGunBtwF/pZd2MwwZwaLnScZwOKB4iKB4KwMNgstqLXWWs11flPxcI1oZCoTCK\n-\tOAcgrbXBwDl/lc/LlrmK7VaTAeBQQOk41lgOWks29BY1Vz2sdGGJy+1hyyvO+qqqQX4U\n-\tYQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA\n-\tJNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji\n-\tHHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK\n-\tUAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo\n-\t5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K\n-\tO/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I\n-\tpDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als\n-\tJB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv\n-\t8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu\n-\tZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg\n-\tUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0\n-\tIDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G\n-\taWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z\n-\tUui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+\n-\tZ4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K\n-\tIQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo\n-\tIh34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ\n-\t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\n-\tKjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz\n-\tiHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW\n-\tIsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY\n-\tEqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy\n-\tcsFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p\n-\tcvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX\n-\tmVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O\n-\tFJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb\n-\tuFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV\n-\t7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL\n-\tVPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL\n-\tv8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k\n-\tb2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS\n-\tIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg\n-\tMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7\n-\tpXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn\n-\t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\n-\tkC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C\n-\tL4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz\n-\tNyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k\n-\tb2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2\n-\taWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ\n-\t953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99\n-\t+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC\n-\tBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA\n-\tCDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ\n-\tABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh\n-\tBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT\n-\tgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB\n-\toGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp\n-\tfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS\n-\tVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f\n-\t/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4\n-\tv3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc\n-\tJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8\n-\tLKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc\n-\tph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ\n-\tUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu\n-\tH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+\n-\tOL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC\n-\tr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E\n-\tQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz\n-\tQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC\n-\tqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+\n-\tqr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y\n-\t5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr\n-\t+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy\n-\tejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV\n-\tLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9\n-\tTsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag\n-\t7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/\n-\tF3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9\n-\tt3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO\n-\tLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA\n-\tlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp\n-\tO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz\n-\tbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x\n-\tnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI\n-\t8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI\n-\taDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl\n-\tS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs\n-\tUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne\n-\tpb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik\n-\tc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi\n-\ttL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+\n-\tUIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs\n-\t5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+\n-\t7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k\n-\tnpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp\n-\tJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm\n-\tfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB\n-\t2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb\n-\tfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y\n-\t2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0\n-\tCmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv\n-\tYmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ\n-\tQ0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97\n-\tzue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw\n-\tyU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx\n-\tQcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1\n-\tCtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5\n-\tE4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk\n-\tBB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/\n-\t7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG\n-\twA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7\n-\tqbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D\n-\t+4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy\n-\tTPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx\n-\tRHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB\n-\tT01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64\n-\tcrm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn\n-\tE7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f\n-\te6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM\n-\t6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///\n-\tXfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj\n-\tdvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz\n-\tNMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE\n-\tKsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU\n-\trkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t\n-\tGe2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG\n-\tE5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd\n-\tKa2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV\n-\t/JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL\n-\tV6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H\n-\tg0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx\n-\t2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+\n-\tWLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3\n-\thi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN\n-\t1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ\n-\tfH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t\n-\taq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj\n-\t3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB\n-\t6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR\n-\trZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8\n-\t+KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3\n-\tJaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q\n-\tQMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf\n-\teJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF\n-\t9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa\n-\ttEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h\n-\tnaa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+\n-\tIwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN\n-\thsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI\n-\tq2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz\n-\tZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe\n-\tM3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri\n-\tJ7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn\n-\tN0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0\n-\tIDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu\n-\tZ3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2\n-\t2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf\n-\t5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i\n-\tTeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH\n-\ttSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU\n-\t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\n-\tqu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24\n-\tfagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1\n-\tYfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6\n-\tCekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P\n-\tgV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV\n-\t6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc\n-\tjvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q\n-\tteDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0\n-\tVDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS\n-\t9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH\n-\tT2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP\n-\txPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb\n-\tvo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ\n-\tCmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv\n-\tSUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS\n-\tIC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+\n-\tPgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj\n-\tszPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE\n-\tbZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2\n-\tPbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R\n-\tU+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j\n-\tnEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9\n-\tAHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e\n-\tLQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3\n-\t0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB\n-\tVnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE\n-\tj9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9\n-\tg0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx\n-\tW6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08\n-\tCT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK\n-\tZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD\n-\tQ0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv\n-\tTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz\n-\tdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC\n-\tkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN\n-\tAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN\n-\tkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC\n-\t72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV\n-\tA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY\n-\tgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC\n-\tLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A\n-\tZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn\n-\t4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv\n-\t0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv\n-\tWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh\n-\taZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y\n-\tjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW\n-\tS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D\n-\tqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA\n-\tn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s\n-\tLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v\n-\tDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu\n-\tf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I\n-\tuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ\n-\tnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j\n-\tx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG\n-\tK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns\n-\t2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2\n-\tUX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B\n-\tMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr\n-\tRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd\n-\tX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO\n-\t+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN\n-\tb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e\n-\tA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15\n-\tDLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc\n-\tQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg\n-\tIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD\n-\t0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh\n-\tbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU\n-\tm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn\n-\t840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek\n-\t1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z\n-\trsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp\n-\tfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj\n-\tD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6\n-\tRhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k\n-\tyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf\n-\tura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw\n-\t6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ\n-\tmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV\n-\tyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9\n-\tL3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0\n-\tmboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm\n-\tlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl\n-\tbmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg\n-\tMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy\n-\tbmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X\n-\tiTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR\n-\tvT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd\n-\tnZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT\n-\tTf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5\n-\tUnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI\n-\tbXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ\n-\twVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI\n-\teNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D\n-\toOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD\n-\tZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO\n-\tgC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd\n-\t2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD\n-\tbmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz\n-\tVdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT\n-\ttjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk\n-\t6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h\n-\tXREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5\n-\tiBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/\n-\tt8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU\n-\tzsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw\n-\tx8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB\n-\t/CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH\n-\tj2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt\n-\tumi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb\n-\tS4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2\n-\txT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15\n-\tlZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y\n-\tI67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf\n-\tdehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD\n-\tp+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ\n-\tl9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE\n-\tqy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc\n-\tUfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn\n-\tKhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz\n-\tE1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6\n-\tyRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ\n-\tn8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq\n-\tbOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r\n-\twozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub\n-\tvHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy\n-\terV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ\n-\tc1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+\n-\tUiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF\n-\tdVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2\n-\tYT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck\n-\teDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa\n-\tGBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv\n-\tMl78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o\n-\tWaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698\n-\tz2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p\n-\tzDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS\n-\tgMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw\n-\tIG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv\n-\tYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g\n-\tL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw\n-\tZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg\n-\tMCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF\n-\tTFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5\n-\tdWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta\n-\tmg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN\n-\tFHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv\n-\tkX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg\n-\tNa1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS\n-\tqo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr\n-\t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\n-\tMlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+\n-\tW73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1\n-\t8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT\n-\ti91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph\n-\tWq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d\n-\tCAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx\n-\thdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp\n-\toU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u\n-\tuo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr\n-\tAa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8\n-\trYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK\n-\tPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3\n-\tIC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg\n-\tMTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu\n-\tZ2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG\n-\taWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg\n-\tODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1\n-\tMDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg\n-\tMjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi\n-\tdHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg\n-\tL0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5\n-\tIC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i\n-\tago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg\n-\tL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD\n-\tSMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW\n-\tj2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n\n-\t4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u\n-\t7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM\n-\tF69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl\n-\tAN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq\n-\t6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn\n-\taby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO\n-\ttsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81\n-\t8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8\n-\t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\n-\tVrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a\n-\tiVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2\n-\tIDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv\n-\tciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz\n-\tMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT\n-\tK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg\n-\tL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK\n-\tNTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy\n-\tMiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1\n-\tNTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg\n-\tMCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry\n-\tdWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK\n-\tNTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv\n-\tRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp\n-\tdGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP\n-\tbW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv\n-\tbnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k\n-\tRGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK\n-\tMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg\n-\tMDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw\n-\tMDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw\n-\tMDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw\n-\tMDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw\n-\tMCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw\n-\tNDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg\n-\tbiAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw\n-\tNzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g\n-\tCjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0\n-\tIDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow\n-\tMDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw\n-\tMDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw\n-\tMDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw\n-\tMDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw\n-\tMjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw\n-\tIG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw\n-\tMTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu\n-\tIAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3\n-\tNyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK\n-\tMDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg\n-\tMDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw\n-\tMDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw\n-\tMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS\n-\tIC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk\n-\tYTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP\n-\tRgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo\n-\tRDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE\n-\tYXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR\n-\tdWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg\n-\tMQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3\n-\tZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm\n-\tMDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5\n-\tPj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==\n-\t\n-\tQuickLookThumbnail\n-\t\n-\tTU0AKgAACkCAP+BACCQWDQeEQmFQuGQ2HQ+IRGJROKRWLReMRmNRSBP+Nx+QSGJtaSR2\n-\tRSeUSAAysVS2Uy8ASaYTOaRNqzcVzmGvx5vN+AkAPd+A0IgiDPx4PB7hAIAl3ut7hEKg\n-\t2Gvh6PgCAwEASEO9zOJ5gQJB4LAyKPx8VgEUaLTdqzkVzWRTK5XW7Qa3XCHNhWIpkBck\n-\tCN3tpxvoGDASghhKlhiAkiltOkPCwAOgEhYAOV7BoQABzOwGBkOgp9NFyAAXhZ5t15P1\n-\tvtd7ksskB2M5pP4IgJ8AoLgVstUCCMQPF0v0GvJsPAHiABvl+iMUgpltcAFInDi2Qu8z\n-\tq7xq6d3wTPt3GFvNwr5fst9A4PhEEgMAPp4PF5v0DAh7uBtu4RC0MGQWhpAmFQRA2C4H\n-\tHqdZ5AIAgBgSCoKAcALiHYeR8AEAB+gIDoeBqCxXk2W4KhIDgUBiDJlFmaYLAsBJ/AwE\n-\tQRAafZznaegBgMCIFAUAADACAoTh6HAIoa8bwow78jyUkMjJq8xwnwD4Jn2bh5AcEgNL\n-\tMgp+HUYZbGcD4jCQzCsAIrauIUfBummcoNhaEbsgAtC1TiiMmyWickzxPaLpIa09Jef1\n-\tBHpQgHUMiJ80SftFx3HjwpWAKWhVPiJUBSlL0wgiOlFTheU8TVQATUSHGdUpC1OSFUg7\n-\tVdM1ag9LVdWK7rSfByVsA1cAbXQI14iNBH8dtgndYddAaDNj0hWU+VhZVmpQdloWCdtj\n-\tgzQwHJBX50W0etuA5b1RKBZzwWZcVyoofd0VsclIW8DkGTQmCenmc16AlewK3xcy5XJf\n-\tV+oUeOAW0dAKYICeDSOfmEnLhdfg3h1cANfy5oHiWKoRX96HNWlVg6A+PUzYZ3HXkcWA\n-\ttXkiYtJGKZTlJw5djwDgvmVk2UfWbXVmQLgXneWI5ldyz9fmeotSFJIXoOf6GmmipboV\n-\tMTugp3mcWRqAmF5xkyXgajEH4KA4Cd5nofR/HuaBamYGwzisBByHAfMMHgdZzHqCYTAg\n-\te54AoC4CHYfgEGoVZaAYHogBuDgJR6fp0nQf4LgUex7gUAx2nOfQIAAeTlAqB54nqBAS\n-\tg4dxtnIDgWhRLSEagg7xnUZxkHkCgFnCcgCA+Ch2msdoJBoDoBGwb4CBiD4APqeh1Ho5\n-\tYLn7vqzHQdaxgSZBgG4FQdheAB6gGBZ9mmZB4BMJIYgqfB3HUe4CgAfZ/gUcJhGAAoWB\n-\tuEQHAOAoFcVxnHchyXKctzDmnOOedA6J0jpktHjacpd1TxBwjJFaLgZI4xzD9ASPIZwB\n-\tQkhoByBEfAwBbjbAmZgAYDgMj4GWKwd4Ow0BMAkOcaY+ANAiAkAIfI+B+gCK2OMYQ1wU\n-\tBSCEOoTwhRvAjB6iYFI4xWCaGeAgE4NgbA1BGUUfo+R1DsHgAMBgEkdAEH+BQE4NASAR\n-\tXgQWBcZCcE6HwNgSIihnA4B4PoYI2gAgZA8CgzA8gFASAsPUYQsR1gzCGCEBgDwCgCHo\n-\tOkZoyBpj5ACCEFINAMAOAmCUBI4BPixHcEcH4BhpDnAqC0DYDQAj7H0AAegyRcjfA2Dg\n-\tE5YwXAhFyIEUYJQkAkAQB8E8SIlRMidFCKUVIrRYi0AqLkXowRigQ0lZ0ZS0DvHeT5OQ\n-\t8x2jxAQBhw4CB9jgHAO8B4FwInwH6PgdI7AANeAkAgfA9m/AOK2OcZorhcjtBcFIFQBB\n-\t5AGAWBMBABwAG6HSPABDiB3DtHQNIZ4+gXBOBsBcfAAAAjwG+OMBwIQSgOTQmYrZCYyk\n-\tESalwdRuwADuHIPQfq9wDD3W0PsCgEh9DojwBByQDAHD+W0PgCE7B/AFAMAoBoECzD0H\n-\tMNwcg/AKAYAUP6dM/wCAhBABaew5qhgSAcPYchuwIFbAFTqcQ7KA0hoJQahFCqGUOohR\n-\tKilFiCUYK5Mkjy+qNtKIxW+t9cCRVsX60itpMGRjrFvX0Klf1GkXGvYNTgog22HZyAOx\n-\tRF2mKTIVXiuhNbGwJsiQ5dA+xdWZHPZsMdnWaEVI6W5k68lir2AkuCytdLKWpIQrRlw4\n-\tQMWxAfbMmiv5nDvZCAK3VpimAQs/axctq7gD2uIOO4wGrkLFTwtwerIbmW9tMxC4Cyrh\n-\tWRHldezY52OWBVcwkflt2QswtMta6al7qtDtvXsD962YMVuuPJkKiR8sntMu+8p3bzsW\n-\tuYxkEF/QC3/sizYfTISkjwZ2Atal9r7kwI7ZC6eBVi2KPgSKxpBcHF2I6vJd93LgYVYm\n-\tP9IyahfDRASDUDA7R1ASTeVS1o6hzJWA0BYtg9BxDTHOAIBgDAIAdKKmZeA5hkC+GkPs\n-\tCoNwcgtAilwbg6x+gOAqBnGSaRzDDGMN0DIMQcxhTQWgfmPktj4YS20c6uAIYxAbl4hS\n-\td07j4HeOoAADQHXwABVJBhRi0gAx9GMhA9HujoBSDgEiaM2DfGoN0eAEAPOgnYWvQQ08\n-\tqD7yuDKMI/B6DjGgN8f4NAWgeTSM4XAwB6gbBUD3TeX8u0ZIInMrg9x1j0zeU3OoAMwZ\n-\toLxGc8hIbQ62AAO8ZIcRBDJCCDUCgCAJgAG8PkEAFKIkEMsDEFg/cDAhAiN4Yo4HtATB\n-\tAB4Ao6hkjHGuB8GAJx7juH2A4dw3h8A6CwDgfYxBdbWAiBcEAHAKAQAuP8bYrhpgQBQP\n-\tEWw3wKg8kEA0GANgECoFEOcJAPgGDvHkOsYI0B7hPCQC4c44BsjRGsAEDwBh2D/BICoC\n-\t4Ax6D1AcCoJwPQSRmLedwACdx3jYGmPveY6Rqjf5wOQBYDgDD1HkOiCYIQKDhFyO8EgO\n-\twUgbAAM0a4AgHjaGWAAHwOx4ivF6CkNYSBzi9G0AMDuMj7gUAYchgYJgDDyA8DsE4tRA\n-\tChBSHAJA5BfDyB0EMEg+x2wSHlzEdIBADjiHUCsKwSgPjgFeLYeEkQFGcACN0Yg4h+gK\n-\tAWA8GIJQKD7ANPxuI5h1q1G4OAFAUQyhOyRywvWH0jHmGSNAbo+gFgaAoPocA1R7AMBF\n-\tmXbYzh3AbBuCkC4Bx4jkGcNEc4/lvApAcPvhyGACDzHiMwZI2QPAxBsD4IoMoLC4GN8U\n-\tDgGASgKHuN0cw+gFAWA8pMawuh4AfBiAVygDAKgLKeP8DoEh7DlRuOwdA/QXAoAAGkHI\n-\tAcA4AWH4H6HoWC3KBQBqBOAgAGAKRYZQ5e10o5AmTkHUGmFgF4GySCB+9+H+W4AAAgAW\n-\tHkGyG6HWHUGyGyAWBSB+BeAyHIFoGUH2Bm9u72HYHOHGHkBABsBWHw6AH6AWA8BSBCAQ\n-\tGqGEFcGkAAB4CqB8BWMwG2FgFsGzB3B6HWWGHKHaiIBw3uG8GAGsnKH0HUAGA4BgeGG4\n-\t3QAGHkHYAOBSA4HgGuHYHyGgGQHeCiDCB+AEHgUSHgHAHhAeckAA52BMBaBIdQrmIs1y\n-\t5a1uVmHEHEHcA0A8A0z0Lq1ULWIuzVAqUyK8HEzmA8KKPC0oHeH4AZE/EvEyI+waJKmU\n-\twWJQw8AAwvFYTxFcJAvzFjFtFuJOICAADgEAAAMAAAABAGsAAAEBAAMAAAABACEAAAEC\n-\tAAMAAAADAAAK7gEDAAMAAAABAAUAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAESAAMA\n-\tAAABAAEAAAEVAAMAAAABAAMAAAEWAAMAAAABAZgAAAEXAAQAAAABAAAKOAEcAAMAAAAB\n-\tAAEAAAE9AAMAAAABAAIAAAFTAAMAAAADAAAK9IdzAAcAAA9kAAAK+gAAAAAACAAIAAgA\n-\tAQABAAEAAA9kQVBQTAQAAABtbnRyUkdCIFhZWiAH2QAIAAUACQAIABFhY3NwQVBQTAAA\n-\tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLEdUTULFSMSs5/UDDo/MsBg6\n-\t75uEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5kZXNjAAABLAAAAGByWFla\n-\tAAACFAAAABRnWFlaAAACKAAAABRiWFlaAAACPAAAABRyVFJDAAACUAAAAgxnVFJDAAAE\n-\tXAAAAgxiVFJDAAAGaAAAAgx3dHB0AAAIdAAAABRjcHJ0AAAInAAAAIZia3B0AAAIiAAA\n-\tABR2Y2d0AAAJJAAABhJjaGFkAAAPOAAAACxkbW5kAAABjAAAAFJkbWRkAAAB4AAAADJt\n-\tbHVjAAAAAAAAAAEAAAAMZW5VUwAAAEQAAAAcAEgAdQBlAHkAUABSAE8AIABDAG8AbABv\n-\tAHIAIABMAEMARAAgACgARAA2ADUAIABHADIALgAyACAAQQAwAC4AMAAwACltbHVjAAAA\n-\tAAAAAAEAAAAMZW5VUwAAADYAAAAcAFgALQBSAGkAdABlACAASQBuAGMALgAgACgAdwB3\n-\tAHcALgB4AHIAaQB0AGUALgBjAG8AbQApAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABYA\n-\tAAAcAEMAbwBsAG8AcgAgAEwAQwBEACAAMAAAWFlaIAAAAAAAAG4ZAABCdAAACBZYWVog\n-\tAAAAAAAAWr4AAI0oAAAbLFhZWiAAAAAAAAAt/AAAMGIAAK/nY3VydgAAAAAAAAEAAAAA\n-\tAAABAAMABwALABEAGAAgACkANABBAE4AXQBuAIAAlACpAMAA2ADyAQ0BKgFJAWkBiwGv\n-\tAdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH\n-\tvggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe\n-\tEuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki\n-\t1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy\n-\tOSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU\n-\taFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF\n-\tdvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e\n-\tYaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB\n-\tzfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j\n-\tdXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY\n-\tAPIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F\n-\togXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l\n-\tD14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd\n-\t1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn\n-\tMpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M\n-\tMk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul\n-\tbQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS\n-\tuZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y\n-\twHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry\n-\t7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO\n-\tAF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD\n-\t4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ\n-\tDDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ\n-\tQxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO\n-\tLGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E\n-\tcUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+\n-\tY49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H\n-\tjokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu\n-\ts3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk\n-\tKOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog\n-\tAAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA\n-\teQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw\n-\tADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2\n-\tY2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh\n-\tF2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v\n-\thzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk\n-\tR+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh\n-\t+WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr\n-\tfcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV\n-\tpJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+\n-\trF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC\n-\tNcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq\n-\t1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o\n-\tBOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt\n-\tEogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l\n-\tKSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy\n-\tNqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ\n-\tikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V\n-\tYH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1\n-\tVHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK\n-\tiwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud\n-\tOp34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N\n-\tr3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA\n-\tUsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI\n-\tEoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm\n-\tkydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc\n-\tON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N\n-\tc05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj\n-\tZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+\n-\tcX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6\n-\tlp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut\n-\trq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7\n-\tyNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo\n-\t4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA\n-\t9SH////2AAABX////RUAARx2\n-\t\n-\tReadOnly\n-\tNO\n-\tRowAlign\n-\t1\n-\tRowSpacing\n-\t36\n-\tSheetTitle\n-\tCanvas 1\n-\tSmartAlignmentGuidesActive\n-\tYES\n-\tSmartDistanceGuidesActive\n-\tYES\n-\tUniqueID\n-\t1\n-\tUseEntirePage\n-\t\n-\tVPages\n-\t1\n-\tWindowInfo\n-\t\n-\t\tCurrentSheet\n-\t\t0\n-\t\tExpandedCanvases\n-\t\t\n-\t\t\t\n-\t\t\t\tname\n-\t\t\t\tCanvas 1\n-\t\t\t\n-\t\t\n-\t\tFrame\n-\t\t{{218, 52}, {999, 826}}\n-\t\tListView\n-\t\t\n-\t\tOutlineWidth\n-\t\t142\n-\t\tRightSidebar\n-\t\t\n-\t\tShowRuler\n-\t\t\n-\t\tSidebar\n-\t\t\n-\t\tSidebarWidth\n-\t\t120\n-\t\tVisibleRegion\n-\t\t{{-54, -59}, {864, 672}}\n-\t\tZoom\n-\t\t1\n-\t\tZoomValues\n-\t\t\n-\t\t\t\n-\t\t\t\tCanvas 1\n-\t\t\t\t1\n-\t\t\t\t1\n-\t\t\t\n-\t\t\n-\t\n-\tsaveQuickLookFiles\n-\tYES\n-\n-\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png\ndeleted file mode 100644\nindex 8515e7c4887a..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/prototype.png b/framework-docs/src/docs/asciidoc/images/prototype.png\ndeleted file mode 100644\nindex 26fa2c1cf2d9..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/prototype.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/singleton.png b/framework-docs/src/docs/asciidoc/images/singleton.png\ndeleted file mode 100644\nindex 591520ec1dcc..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/singleton.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png\ndeleted file mode 100644\nindex 6e0eeab744d4..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx.png b/framework-docs/src/docs/asciidoc/images/tx.png\ndeleted file mode 100644\nindex 06f2e77c76f8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png b/framework-docs/src/docs/asciidoc/images/tx_prop_required.png\ndeleted file mode 100644\nindex 218790aca635..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png b/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png\ndeleted file mode 100644\nindex a8ece48193f3..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/index-docinfo-header.html b/framework-docs/src/docs/asciidoc/index-docinfo-header.html\ndeleted file mode 100644\nindex 485f2e4e9803..000000000000\n--- a/framework-docs/src/docs/asciidoc/index-docinfo-header.html\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-
\n-

Spring Framework Documentation

\n-\n-{revnumber}\n-
\ndiff --git a/framework-docs/src/docs/asciidoc/spring-framework.adocbook b/framework-docs/src/docs/asciidoc/spring-framework.adocbook\ndeleted file mode 100644\nindex e020f7337c2d..000000000000\n--- a/framework-docs/src/docs/asciidoc/spring-framework.adocbook\n+++ /dev/null\n@@ -1,26 +0,0 @@\n-:noheader:\n-:toc:\n-:toclevels: 4\n-:tabsize: 4\n-include::attributes.adoc[]\n-= Spring Framework Documentation\n-Rod Johnson; Juergen Hoeller; Keith Donald; Colin Sampaleanu; Rob Harrop; Thomas Risberg; Alef Arendsen; Darren Davison; Dmitriy Kopylenko; Mark Pollack; Thierry Templier; Erwin Vervaet; Portia Tung; Ben Hale; Adrian Colyer; John Lewis; Costin Leau; Mark Fisher; Sam Brannen; Ramnivas Laddad; Arjen Poutsma; Chris Beams; Tareq Abedrabbo; Andy Clement; Dave Syer; Oliver Gierke; Rossen Stoyanchev; Phillip Webb; Rob Winch; Brian Clozel; Stephane Nicoll; Sebastien Deleuze; Jay Bryant; Mark Paluch\n-\n-NOTE: This documentation is also available in {docs-spring-framework}/reference/html/index.html[HTML] format.\n-\n-[[legal]]\n-== Legal\n-\n-Copyright \u00a9 2002 - 2023 VMware, Inc. All Rights Reserved.\n-\n-Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.\n-\n-include::overview.adoc[leveloffset=+1]\n-include::core.adoc[leveloffset=+1]\n-include::testing.adoc[leveloffset=+1]\n-include::data-access.adoc[leveloffset=+1]\n-include::web.adoc[leveloffset=+1]\n-include::web-reactive.adoc[leveloffset=+1]\n-include::integration.adoc[leveloffset=+1]\n-include::languages.adoc[leveloffset=+1]\n-include::appendix.adoc[leveloffset=+1]\n"}, {"commit_sha": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3", "labeled_review_comments": [], "total_score": 0.35319148936170214, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": true, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 652f492bdf65..9a9b4e831f50 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -439,4 +439,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\ndeleted file mode 100644\nindex 177a6ae44107..000000000000\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ /dev/null\n@@ -1,20 +0,0 @@\n-// Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n-// spring-asciidoctor-backends Settings\n-:chomp: default headers packages\n-:fold: all\n-// Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..a455ac6ef278 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {spring-framework-issues}/14870[spring-framework#14870]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 834cde1e30b8..13ca74ab1182 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex c8fc3c84597f..b3d4329ef227 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 7d6d1e4461b6..cd625209b35e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -48,7 +48,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -81,7 +81,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -127,7 +127,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -439,7 +439,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex 28ecf885b3e3..378d65ef5911 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d38563319ab3..8eaac910662d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,16 +7,16 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. For reactive-stack web applications, see \n xref:web-reactive.adoc[Web on Reactive Stack].\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\ndiff --git a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties b/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\ndeleted file mode 100644\nindex e1e20afb8446..000000000000\n--- a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-aot=core.aot\n-aot-basics=core.aot.basics\n-aot-refresh=core.aot.refresh\n-aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions\n-aot-bean-registration-contributions=core.aot.bean-registration-contributions\n-aot-hints=core.aot.hints\n-aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints\n-aot-hints-reflective=core.aot.hints.reflective\n-aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/DataAccessException.png b/framework-docs/src/docs/asciidoc/images/DataAccessException.png\ndeleted file mode 100644\nindex 746f17399b99..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/DataAccessException.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png\ndeleted file mode 100644\nindex de6be86ed543..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png\ndeleted file mode 100644\nindex 8ece077d3445..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/container-magic.png b/framework-docs/src/docs/asciidoc/images/container-magic.png\ndeleted file mode 100644\nindex 2628e59b00e8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/container-magic.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png b/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png\ndeleted file mode 100644\nindex 3cf93fa1439c..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png b/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png\ndeleted file mode 100644\nindex 9afd54f57c23..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png\ndeleted file mode 100644\nindex 9c4a950caadb..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\ndeleted file mode 100644\nindex 07148744b549..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\n+++ /dev/null\n@@ -1,612 +0,0 @@\n-\n-\n-\n-image/svg+xmlPage-1DispatcherServlet\n-Servlet WebApplicationContext\n-(containing controllers, view resolvers,and other web-related beans)\n-Controllers\n-ViewResolver\n-HandlerMapping\n-Root WebApplicationContext\n-(containing middle-tier services, datasources, etc.)\n-Services\n-Repositories\n-Delegates if no bean found\n-\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\ndeleted file mode 100644\nindex 4b72bf45285b..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\n+++ /dev/null\n@@ -1,1619 +0,0 @@\n-\n-\n-\n-\n-\tActiveLayerIndex\n-\t0\n-\tApplicationVersion\n-\t\n-\t\tcom.omnigroup.OmniGraffle\n-\t\t137.11.0.108132\n-\t\n-\tAutoAdjust\n-\t\n-\tBackgroundGraphic\n-\t\n-\t\tBounds\n-\t\t{{0, 0}, {756, 553}}\n-\t\tClass\n-\t\tSolidGraphic\n-\t\tID\n-\t\t2\n-\t\tStyle\n-\t\t\n-\t\t\tshadow\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\tstroke\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\n-\t\n-\tCanvasOrigin\n-\t{0, 0}\n-\tColumnAlign\n-\t1\n-\tColumnSpacing\n-\t36\n-\tCreationDate\n-\t2009-09-11 10:15:26 -0400\n-\tCreator\n-\tThomas Risberg\n-\tDisplayScale\n-\t1 0/72 in = 1 0/72 in\n-\tGraphDocumentVersion\n-\t6\n-\tGraphicsList\n-\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t42\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{334.726, 144}\n-\t\t\t\t{394.042, 102.288}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t41\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{489.5, 143.713}\n-\t\t\t\t{430.452, 102.287}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t40\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{230, 217}\n-\t\t\t\t{275.683, 175.337}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t39\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{430.381, 216.81}\n-\t\t\t\t{329.369, 175.19}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\tTail\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t5\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{56, 217}, {249, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t6\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{325.5, 217}, {283.5, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t5\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 UnmarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{184, 145}, {217, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t4\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{430, 145}, {239, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t3\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 ValidationFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{294, 72}, {244, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t1\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tStyle\n-\t\t\t\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\i\\fs36 \\cf0 XmlMappingException}\n-\t\t\t\n-\t\t\tWrap\n-\t\t\tNO\n-\t\t\n-\t\n-\tGridInfo\n-\t\n-\tGuidesLocked\n-\tNO\n-\tGuidesVisible\n-\tYES\n-\tHPages\n-\t1\n-\tImageCounter\n-\t1\n-\tKeepToScale\n-\t\n-\tLayers\n-\t\n-\t\t\n-\t\t\tLock\n-\t\t\tNO\n-\t\t\tName\n-\t\t\tLayer 1\n-\t\t\tPrint\n-\t\t\tYES\n-\t\t\tView\n-\t\t\tYES\n-\t\t\n-\t\n-\tLayoutInfo\n-\t\n-\t\tAnimate\n-\t\tNO\n-\t\tcircoMinDist\n-\t\t18\n-\t\tcircoSeparation\n-\t\t0.0\n-\t\tlayoutEngine\n-\t\tdot\n-\t\tneatoSeparation\n-\t\t0.0\n-\t\ttwopiSeparation\n-\t\t0.0\n-\t\n-\tLinksVisible\n-\tNO\n-\tMagnetsVisible\n-\tNO\n-\tMasterSheets\n-\t\n-\tModificationDate\n-\t2009-09-11 10:38:54 -0400\n-\tModifier\n-\tThomas Risberg\n-\tNotesVisible\n-\tNO\n-\tOrientation\n-\t2\n-\tOriginVisible\n-\tNO\n-\tPageBreaks\n-\tYES\n-\tPrintInfo\n-\t\n-\t\tNSBottomMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t41\n-\t\t\n-\t\tNSLeftMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSOrientation\n-\t\t\n-\t\t\tint\n-\t\t\t1\n-\t\t\n-\t\tNSPaperSize\n-\t\t\n-\t\t\tsize\n-\t\t\t{792, 612}\n-\t\t\n-\t\tNSRightMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSTopMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\n-\tPrintOnePage\n-\t\n-\tQuickLookPreview\n-\t\n-\tJVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls\n-\tdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA\n-\tDRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p\n-\tT84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf\n-\thIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk\n-\tc56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9\n-\tBPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt\n-\toO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj\n-\tAHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY\n-\tv19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT\n-\tz2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm\n-\ts9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O\n-\t5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W\n-\tcvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI\n-\tx6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW\n-\t6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN\n-\t5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp\n-\thZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf\n-\twCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N\n-\tYfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i\n-\tago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50\n-\tIDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb\n-\tMCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv\n-\tVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg\n-\tMTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw\n-\tIDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0\n-\tIDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8\n-\tPCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp\n-\tZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg\n-\tUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh\n-\tbQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz\n-\tNAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg\n-\tL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK\n-\tMjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G\n-\tbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox\n-\tMyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl\n-\tIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D\n-\tb2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg\n-\tL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK\n-\tZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T\n-\tdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw\n-\tIDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh\n-\tdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i\n-\tago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg\n-\tL0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T\n-\tTWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k\n-\tZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0\n-\tcmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg\n-\tMjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I\n-\tZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50\n-\tIDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2\n-\t9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG\n-\tzfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA\n-\tHfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9\n-\tCPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp\n-\t4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW\n-\tFxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg\n-\tNBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW\n-\tpBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I\n-\thGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD\n-\trJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih\n-\tbEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1\n-\tSi4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2\n-\t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\n-\tWlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN\n-\tVm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa\n-\tUMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS\n-\tKZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a\n-\tBLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF\n-\tvAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD\n-\te9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK\n-\tZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv\n-\tTGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo\n-\tIDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv\n-\tbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH\n-\tBQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF\n-\txohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk\n-\tgASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw\n-\tXgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt\n-\t1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os\n-\tWsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj\n-\t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\n-\tWX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B\n-\tgwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl\n-\tbmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw\n-\tIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo\n-\tdCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv\n-\tRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu\n-\tueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521\n-\tCzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB\n-\tdJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5\n-\tkBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR\n-\tCf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo\n-\tIh2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q\n-\tU0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke\n-\t6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH\n-\tlA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C\n-\tpQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo\n-\tHRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF\n-\t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\n-\tYQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA\n-\tJNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji\n-\tHHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK\n-\tUAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo\n-\t5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K\n-\tO/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I\n-\tpDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als\n-\tJB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv\n-\t8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu\n-\tZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg\n-\tUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0\n-\tIDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G\n-\taWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z\n-\tUui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+\n-\tZ4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K\n-\tIQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo\n-\tIh34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ\n-\tAliDkaJMNM2gCHaApk0UZQTGOgC8wzfD9pyCC7mV2BopE8MUFZvNFgvLWlFEOsCyFovZ\n-\tXFzEMCbKKPGF/ML2nB6vlFwpuBJbGsiyVlsJx9kdDieKSAccDjvHldisLBCmU3whvhLe\n-\tNJfnFFw4cPUGYAtogavT5XaX8h4UoQ7wpW63ywmMATDwNeil4zc93lzpzFVrIbhMMWvj\n-\tgCzv8ZZX+ATB7w+giHPA7xcEX0W518MDYc7GFjMQX61aulvtDS9EF+Bq9EYTY7ZyTjdf\n-\tVi74K4OhkCiKB1AEOgBgQqFgpV8oL+PdTs5qZkxGSG+BKs3eDNGFC5UuBdfu4r2+QDAk\n-\tVtceDNfVgxpQhDkgUakLH6ytFkPBgM/Lu+wpvDq4WqUJby5EV6MzUIzZZnd5KgJVYk24\n-\truFIY1NzS0tLK4o4BwBLc1PjkYa6cI1YFajwuOw2M0MZdBoI7+6teSe6eoBrtbvLhKBY\n-\tc6ihsbm17Vh7R2fXCRSBDnR1drQfa2ttbmw4VCMGhTK3lF5Kny68El3Yl2mA6yoTQtXh\n-\tw00tR493new+03MugiLSgXM9Z7pPdh0/2tJ0OFwdEsqkzZk2Qnj3bM2wMRdq9FQRy7k8\n-\tQlVNfWNre+fps5Hve/v6L0Wjl1HEORCNXurv6/0+cvZ0Z3trY31NleBxcWyRFN49W3Nu\n-\tHrwagujanHxFsLq+qa3jVM/53v7o1YEfh4avxVDEOXBteOjHgavR/t7zPac62prqq4MV\n-\tvNMG4YVXRbsPXmljhlOX5dzegBhubOvsjly4eGVgKHbjZvxWAkWgA7fiN2/EhgauXLwQ\n-\t6e5sawyLAa+bY6WTF7bmL9+uStE1FVudvK+q5nArwO2LDgxfjydG7twdvYci0IHRu3dG\n-\tEvHrwwPRPsDberimysc7rcWmtHQLtQbaXOIqC4iHmtpPRfouD8biiTujY/fHHyZRBDrw\n-\tcPz+2OidRDw2eLkvcqq96ZAYKHOVmGmDtnBPdlWFWqO0MZcHaxpaunouRAd/io+M/jqe\n-\tfPxk8imKQAcmnzxOjv86OhL/aTB6oaerpaEmWC5tzUYtXKt27cwqtY4qsjp4Xyj8zdHT\n-\t5y/+EIuP3HuQnJianpmbm0cR58Dc3Mz01ETywb2ReOyHi+dPH/0mHPLxDmsRpVOnoaun\n-\t4Nj1+MW65uNne68MAdzxR5PTswvPFl8soYhz4MXis4XZ6clH44B36Erv2ePNdaLfAwcv\n-\tpU9DF67M5pKvvJXVsDFH+geuJ3558GhqZv750vLLlVco4hxYebm89Hx+ZurRg18S1wf6\n-\tI7A1V1d6vyoxw6V5T3bhBZHJLB27tUfaTn4XHYrfHktOziws/r7yenXtDYo4B9ZWX6/8\n-\tvrgwM5kcux0fin53su1IrXTwmqVL8+5zF+jSQLciFG481t17NZYYHZ+Ynl9cfrX2Zn1j\n-\tE0WcAxvrb9ZeLS/OT0+MjyZiV3u7jzWGQxVAl05L10BbuFK4VDW1n+kbuPHzWHJq9jnA\n-\tXd98u4Ui0IG3m+uA9/nsVHLs5xsDfWfam+BaVcpZaEO67BoYi50Xvq5r7ujpH7x5+/7j\n-\t3xaWVlbXN7fevd9GEefA+3dbm+urK0sLvz2+f/vmYH9PR3Pd1wJvtzAZ6LIOXhDrWzrP\n-\tXRqK3x2fmHm2/PqPja132x9QBDqw/W5r44/Xy89mJsbvxocunetsqRcF3sFmpgsviIDu\n-\tt9HhW6MPn8wuvlxdfwtw//yIIs6BPz9sv3u7vvpycfbJw9Fbw9FvJbp+z750uyLRa4l7\n-\tyam5FytrG1vvAe4nFHEOfPzzw/utjbWVF3NTyXuJa1F4SZSJLvwCUGNgWEcqu2no/oUi\n-\tzIFP8nS/+OxNbn4BvM0Mb1UFDjS0nohcjkF2n84vvXqzubX94eMnwr4zLAcc+PTxw/bW\n-\t5ptXS/NPIbuxy5ETrQ0HAvBmFbzRXJCPdJX9Q4J0lc1PvnqkK++PsleRrrL5yVePdOX9\n-\tUfYq0lU2P/nqka68P8peRbrK5idfPdKV90fZq0hX2fzkq0e68v4oexXpKpuffPVIV94f\n-\tZa8iXWXzk68e6cr7o+xVpKtsfvLVI115f5S9inSVzU++eqQr74+yV5GusvnJV4905f1R\n-\t9irSVTY/+eqRrrw/yl5FusrmJ1890pX3R9mrSFfZ/OSrR7ry/ih7NRu6+JSYwlhn85RY\n-\tzj50iXu+EQuSfwZwVzeyfz3hiU9nE/codpqC/sPT2dhZgcAWChlKyrazAnZFIa73SeaC\n-\tsu2Kgh2NCOxblLmk7DoaYTcy4jqOyRWUZTcy7CRIXLdAuYKy6iSowi6gxDX6lC0oqy6g\n-\tKjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz\n-\tiHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW\n-\tIsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY\n-\tEqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy\n-\tcsFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p\n-\tcvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX\n-\tmVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O\n-\tFJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb\n-\tuFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV\n-\t7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL\n-\tVPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL\n-\tv8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k\n-\tb2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS\n-\tIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg\n-\tMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7\n-\tpXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn\n-\t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\n-\tkC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C\n-\tL4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz\n-\tNyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k\n-\tb2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2\n-\taWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ\n-\t953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99\n-\t+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC\n-\tBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA\n-\tCDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ\n-\tABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh\n-\tBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT\n-\tgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB\n-\toGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp\n-\tfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS\n-\tVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f\n-\t/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4\n-\tv3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc\n-\tJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8\n-\tLKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc\n-\tph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ\n-\tUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu\n-\tH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+\n-\tOL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC\n-\tr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E\n-\tQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz\n-\tQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC\n-\tqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+\n-\tqr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y\n-\t5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr\n-\t+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy\n-\tejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV\n-\tLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9\n-\tTsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag\n-\t7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/\n-\tF3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9\n-\tt3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO\n-\tLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA\n-\tlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp\n-\tO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz\n-\tbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x\n-\tnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI\n-\t8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI\n-\taDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl\n-\tS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs\n-\tUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne\n-\tpb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik\n-\tc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi\n-\ttL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+\n-\tUIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs\n-\t5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+\n-\t7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k\n-\tnpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp\n-\tJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm\n-\tfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB\n-\t2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb\n-\tfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y\n-\t2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0\n-\tCmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv\n-\tYmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ\n-\tQ0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97\n-\tzue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw\n-\tyU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx\n-\tQcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1\n-\tCtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5\n-\tE4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk\n-\tBB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/\n-\t7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG\n-\twA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7\n-\tqbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D\n-\t+4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy\n-\tTPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx\n-\tRHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB\n-\tT01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64\n-\tcrm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn\n-\tE7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f\n-\te6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM\n-\t6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///\n-\tXfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj\n-\tdvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz\n-\tNMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE\n-\tKsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU\n-\trkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t\n-\tGe2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG\n-\tE5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd\n-\tKa2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV\n-\t/JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL\n-\tV6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H\n-\tg0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx\n-\t2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+\n-\tWLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3\n-\thi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN\n-\t1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ\n-\tfH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t\n-\taq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj\n-\t3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB\n-\t6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR\n-\trZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8\n-\t+KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3\n-\tJaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q\n-\tQMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf\n-\teJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF\n-\t9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa\n-\ttEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h\n-\tnaa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+\n-\tIwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN\n-\thsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI\n-\tq2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz\n-\tZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe\n-\tM3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri\n-\tJ7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn\n-\tN0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0\n-\tIDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu\n-\tZ3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2\n-\t2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf\n-\t5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i\n-\tTeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH\n-\ttSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU\n-\t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\n-\tqu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24\n-\tfagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1\n-\tYfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6\n-\tCekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P\n-\tgV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV\n-\t6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc\n-\tjvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q\n-\tteDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0\n-\tVDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS\n-\t9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH\n-\tT2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP\n-\txPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb\n-\tvo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ\n-\tCmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv\n-\tSUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS\n-\tIC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+\n-\tPgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj\n-\tszPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE\n-\tbZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2\n-\tPbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R\n-\tU+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j\n-\tnEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9\n-\tAHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e\n-\tLQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3\n-\t0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB\n-\tVnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE\n-\tj9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9\n-\tg0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx\n-\tW6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08\n-\tCT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK\n-\tZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD\n-\tQ0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv\n-\tTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz\n-\tdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC\n-\tkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN\n-\tAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN\n-\tkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC\n-\t72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV\n-\tA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY\n-\tgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC\n-\tLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A\n-\tZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn\n-\t4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv\n-\t0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv\n-\tWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh\n-\taZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y\n-\tjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW\n-\tS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D\n-\tqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA\n-\tn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s\n-\tLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v\n-\tDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu\n-\tf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I\n-\tuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ\n-\tnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j\n-\tx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG\n-\tK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns\n-\t2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2\n-\tUX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B\n-\tMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr\n-\tRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd\n-\tX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO\n-\t+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN\n-\tb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e\n-\tA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15\n-\tDLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc\n-\tQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg\n-\tIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD\n-\t0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh\n-\tbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU\n-\tm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn\n-\t840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek\n-\t1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z\n-\trsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp\n-\tfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj\n-\tD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6\n-\tRhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k\n-\tyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf\n-\tura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw\n-\t6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ\n-\tmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV\n-\tyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9\n-\tL3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0\n-\tmboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm\n-\tlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl\n-\tbmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg\n-\tMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy\n-\tbmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X\n-\tiTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR\n-\tvT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd\n-\tnZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT\n-\tTf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5\n-\tUnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI\n-\tbXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ\n-\twVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI\n-\teNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D\n-\toOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD\n-\tZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO\n-\tgC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd\n-\t2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD\n-\tbmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz\n-\tVdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT\n-\ttjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk\n-\t6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h\n-\tXREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5\n-\tiBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/\n-\tt8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU\n-\tzsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw\n-\tx8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB\n-\t/CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH\n-\tj2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt\n-\tumi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb\n-\tS4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2\n-\txT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15\n-\tlZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y\n-\tI67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf\n-\tdehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD\n-\tp+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ\n-\tl9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE\n-\tqy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc\n-\tUfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn\n-\tKhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz\n-\tE1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6\n-\tyRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ\n-\tn8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq\n-\tbOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r\n-\twozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub\n-\tvHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy\n-\terV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ\n-\tc1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+\n-\tUiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF\n-\tdVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2\n-\tYT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck\n-\teDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa\n-\tGBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv\n-\tMl78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o\n-\tWaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698\n-\tz2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p\n-\tzDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS\n-\tgMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw\n-\tIG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv\n-\tYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g\n-\tL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw\n-\tZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg\n-\tMCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF\n-\tTFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5\n-\tdWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta\n-\tmg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN\n-\tFHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv\n-\tkX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg\n-\tNa1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS\n-\tqo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr\n-\t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\n-\tMlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+\n-\tW73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1\n-\t8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT\n-\ti91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph\n-\tWq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d\n-\tCAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx\n-\thdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp\n-\toU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u\n-\tuo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr\n-\tAa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8\n-\trYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK\n-\tPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3\n-\tIC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg\n-\tMTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu\n-\tZ2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG\n-\taWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg\n-\tODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1\n-\tMDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg\n-\tMjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi\n-\tdHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg\n-\tL0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5\n-\tIC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i\n-\tago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg\n-\tL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD\n-\tSMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW\n-\tj2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n\n-\t4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u\n-\t7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM\n-\tF69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl\n-\tAN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq\n-\t6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn\n-\taby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO\n-\ttsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81\n-\t8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8\n-\t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\n-\tVrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a\n-\tiVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2\n-\tIDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv\n-\tciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz\n-\tMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT\n-\tK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg\n-\tL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK\n-\tNTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy\n-\tMiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1\n-\tNTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg\n-\tMCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry\n-\tdWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK\n-\tNTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv\n-\tRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp\n-\tdGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP\n-\tbW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv\n-\tbnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k\n-\tRGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK\n-\tMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg\n-\tMDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw\n-\tMDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw\n-\tMDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw\n-\tMDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw\n-\tMCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw\n-\tNDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg\n-\tbiAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw\n-\tNzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g\n-\tCjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0\n-\tIDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow\n-\tMDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw\n-\tMDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw\n-\tMDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw\n-\tMDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw\n-\tMjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw\n-\tIG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw\n-\tMTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu\n-\tIAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3\n-\tNyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK\n-\tMDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg\n-\tMDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw\n-\tMDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw\n-\tMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS\n-\tIC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk\n-\tYTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP\n-\tRgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo\n-\tRDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE\n-\tYXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR\n-\tdWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg\n-\tMQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3\n-\tZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm\n-\tMDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5\n-\tPj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==\n-\t\n-\tQuickLookThumbnail\n-\t\n-\t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\n-\tAdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH\n-\tvggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe\n-\tEuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki\n-\t1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy\n-\tOSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU\n-\taFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF\n-\tdvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e\n-\tYaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB\n-\tzfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j\n-\tdXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY\n-\tAPIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F\n-\togXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l\n-\tD14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd\n-\t1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn\n-\tMpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M\n-\tMk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul\n-\tbQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS\n-\tuZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y\n-\twHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry\n-\t7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO\n-\tAF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD\n-\t4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ\n-\tDDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ\n-\tQxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO\n-\tLGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E\n-\tcUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+\n-\tY49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H\n-\tjokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu\n-\ts3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk\n-\tKOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog\n-\tAAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA\n-\teQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw\n-\tADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2\n-\tY2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh\n-\tF2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v\n-\thzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk\n-\tR+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh\n-\t+WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr\n-\tfcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV\n-\tpJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+\n-\trF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC\n-\tNcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq\n-\t1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o\n-\tBOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt\n-\tEogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l\n-\tKSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy\n-\tNqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ\n-\tikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V\n-\tYH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1\n-\tVHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK\n-\tiwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud\n-\tOp34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N\n-\tr3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA\n-\tUsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI\n-\tEoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm\n-\tkydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc\n-\tON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N\n-\tc05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj\n-\tZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+\n-\tcX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6\n-\tlp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut\n-\trq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7\n-\tyNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo\n-\t4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA\n-\t9SH////2AAABX////RUAARx2\n-\t\n-\tReadOnly\n-\tNO\n-\tRowAlign\n-\t1\n-\tRowSpacing\n-\t36\n-\tSheetTitle\n-\tCanvas 1\n-\tSmartAlignmentGuidesActive\n-\tYES\n-\tSmartDistanceGuidesActive\n-\tYES\n-\tUniqueID\n-\t1\n-\tUseEntirePage\n-\t\n-\tVPages\n-\t1\n-\tWindowInfo\n-\t\n-\t\tCurrentSheet\n-\t\t0\n-\t\tExpandedCanvases\n-\t\t\n-\t\t\t\n-\t\t\t\tname\n-\t\t\t\tCanvas 1\n-\t\t\t\n-\t\t\n-\t\tFrame\n-\t\t{{218, 52}, {999, 826}}\n-\t\tListView\n-\t\t\n-\t\tOutlineWidth\n-\t\t142\n-\t\tRightSidebar\n-\t\t\n-\t\tShowRuler\n-\t\t\n-\t\tSidebar\n-\t\t\n-\t\tSidebarWidth\n-\t\t120\n-\t\tVisibleRegion\n-\t\t{{-54, -59}, {864, 672}}\n-\t\tZoom\n-\t\t1\n-\t\tZoomValues\n-\t\t\n-\t\t\t\n-\t\t\t\tCanvas 1\n-\t\t\t\t1\n-\t\t\t\t1\n-\t\t\t\n-\t\t\n-\t\n-\tsaveQuickLookFiles\n-\tYES\n-\n-\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png\ndeleted file mode 100644\nindex 8515e7c4887a..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/prototype.png b/framework-docs/src/docs/asciidoc/images/prototype.png\ndeleted file mode 100644\nindex 26fa2c1cf2d9..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/prototype.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/singleton.png b/framework-docs/src/docs/asciidoc/images/singleton.png\ndeleted file mode 100644\nindex 591520ec1dcc..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/singleton.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png\ndeleted file mode 100644\nindex 6e0eeab744d4..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx.png b/framework-docs/src/docs/asciidoc/images/tx.png\ndeleted file mode 100644\nindex 06f2e77c76f8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png b/framework-docs/src/docs/asciidoc/images/tx_prop_required.png\ndeleted file mode 100644\nindex 218790aca635..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png b/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png\ndeleted file mode 100644\nindex a8ece48193f3..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/index-docinfo-header.html b/framework-docs/src/docs/asciidoc/index-docinfo-header.html\ndeleted file mode 100644\nindex 485f2e4e9803..000000000000\n--- a/framework-docs/src/docs/asciidoc/index-docinfo-header.html\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-
\n-

Spring Framework Documentation

\n-\n-{revnumber}\n-
\ndiff --git a/framework-docs/src/docs/asciidoc/spring-framework.adocbook b/framework-docs/src/docs/asciidoc/spring-framework.adocbook\ndeleted file mode 100644\nindex e020f7337c2d..000000000000\n--- a/framework-docs/src/docs/asciidoc/spring-framework.adocbook\n+++ /dev/null\n@@ -1,26 +0,0 @@\n-:noheader:\n-:toc:\n-:toclevels: 4\n-:tabsize: 4\n-include::attributes.adoc[]\n-= Spring Framework Documentation\n-Rod Johnson; Juergen Hoeller; Keith Donald; Colin Sampaleanu; Rob Harrop; Thomas Risberg; Alef Arendsen; Darren Davison; Dmitriy Kopylenko; Mark Pollack; Thierry Templier; Erwin Vervaet; Portia Tung; Ben Hale; Adrian Colyer; John Lewis; Costin Leau; Mark Fisher; Sam Brannen; Ramnivas Laddad; Arjen Poutsma; Chris Beams; Tareq Abedrabbo; Andy Clement; Dave Syer; Oliver Gierke; Rossen Stoyanchev; Phillip Webb; Rob Winch; Brian Clozel; Stephane Nicoll; Sebastien Deleuze; Jay Bryant; Mark Paluch\n-\n-NOTE: This documentation is also available in {docs-spring-framework}/reference/html/index.html[HTML] format.\n-\n-[[legal]]\n-== Legal\n-\n-Copyright \u00a9 2002 - 2023 VMware, Inc. All Rights Reserved.\n-\n-Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.\n-\n-include::overview.adoc[leveloffset=+1]\n-include::core.adoc[leveloffset=+1]\n-include::testing.adoc[leveloffset=+1]\n-include::data-access.adoc[leveloffset=+1]\n-include::web.adoc[leveloffset=+1]\n-include::web-reactive.adoc[leveloffset=+1]\n-include::integration.adoc[leveloffset=+1]\n-include::languages.adoc[leveloffset=+1]\n-include::appendix.adoc[leveloffset=+1]\n"}, {"commit_sha": "c7ce9fdc3f7c3147388e2ae3472fef965ddeba2a", "labeled_review_comments": [], "total_score": 0.26382978723404255, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": false, "exclude_base_merge_commit": true, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 652f492bdf65..9a9b4e831f50 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -439,4 +439,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..a455ac6ef278 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {spring-framework-issues}/14870[spring-framework#14870]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 834cde1e30b8..13ca74ab1182 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex c8fc3c84597f..b3d4329ef227 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 7d6d1e4461b6..cd625209b35e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -48,7 +48,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -81,7 +81,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -127,7 +127,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -439,7 +439,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex 28ecf885b3e3..378d65ef5911 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d38563319ab3..8eaac910662d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,16 +7,16 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. For reactive-stack web applications, see \n xref:web-reactive.adoc[Web on Reactive Stack].\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\ndiff --git a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties b/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\ndeleted file mode 100644\nindex e1e20afb8446..000000000000\n--- a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-aot=core.aot\n-aot-basics=core.aot.basics\n-aot-refresh=core.aot.refresh\n-aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions\n-aot-bean-registration-contributions=core.aot.bean-registration-contributions\n-aot-hints=core.aot.hints\n-aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints\n-aot-hints-reflective=core.aot.hints.reflective\n-aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/DataAccessException.png b/framework-docs/src/docs/asciidoc/images/DataAccessException.png\ndeleted file mode 100644\nindex 746f17399b99..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/DataAccessException.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png\ndeleted file mode 100644\nindex de6be86ed543..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png\ndeleted file mode 100644\nindex 8ece077d3445..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/container-magic.png b/framework-docs/src/docs/asciidoc/images/container-magic.png\ndeleted file mode 100644\nindex 2628e59b00e8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/container-magic.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png b/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png\ndeleted file mode 100644\nindex 3cf93fa1439c..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png b/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png\ndeleted file mode 100644\nindex 9afd54f57c23..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png\ndeleted file mode 100644\nindex 9c4a950caadb..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\ndeleted file mode 100644\nindex 07148744b549..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\n+++ /dev/null\n@@ -1,612 +0,0 @@\n-\n-\n-\n-image/svg+xmlPage-1DispatcherServlet\n-Servlet WebApplicationContext\n-(containing controllers, view resolvers,and other web-related beans)\n-Controllers\n-ViewResolver\n-HandlerMapping\n-Root WebApplicationContext\n-(containing middle-tier services, datasources, etc.)\n-Services\n-Repositories\n-Delegates if no bean found\n-\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\ndeleted file mode 100644\nindex 4b72bf45285b..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\n+++ /dev/null\n@@ -1,1619 +0,0 @@\n-\n-\n-\n-\n-\tActiveLayerIndex\n-\t0\n-\tApplicationVersion\n-\t\n-\t\tcom.omnigroup.OmniGraffle\n-\t\t137.11.0.108132\n-\t\n-\tAutoAdjust\n-\t\n-\tBackgroundGraphic\n-\t\n-\t\tBounds\n-\t\t{{0, 0}, {756, 553}}\n-\t\tClass\n-\t\tSolidGraphic\n-\t\tID\n-\t\t2\n-\t\tStyle\n-\t\t\n-\t\t\tshadow\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\tstroke\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\n-\t\n-\tCanvasOrigin\n-\t{0, 0}\n-\tColumnAlign\n-\t1\n-\tColumnSpacing\n-\t36\n-\tCreationDate\n-\t2009-09-11 10:15:26 -0400\n-\tCreator\n-\tThomas Risberg\n-\tDisplayScale\n-\t1 0/72 in = 1 0/72 in\n-\tGraphDocumentVersion\n-\t6\n-\tGraphicsList\n-\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t42\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{334.726, 144}\n-\t\t\t\t{394.042, 102.288}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t41\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{489.5, 143.713}\n-\t\t\t\t{430.452, 102.287}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t40\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{230, 217}\n-\t\t\t\t{275.683, 175.337}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t39\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{430.381, 216.81}\n-\t\t\t\t{329.369, 175.19}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\tTail\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t5\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{56, 217}, {249, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t6\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{325.5, 217}, {283.5, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t5\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 UnmarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{184, 145}, {217, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t4\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{430, 145}, {239, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t3\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 ValidationFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{294, 72}, {244, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t1\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tStyle\n-\t\t\t\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\i\\fs36 \\cf0 XmlMappingException}\n-\t\t\t\n-\t\t\tWrap\n-\t\t\tNO\n-\t\t\n-\t\n-\tGridInfo\n-\t\n-\tGuidesLocked\n-\tNO\n-\tGuidesVisible\n-\tYES\n-\tHPages\n-\t1\n-\tImageCounter\n-\t1\n-\tKeepToScale\n-\t\n-\tLayers\n-\t\n-\t\t\n-\t\t\tLock\n-\t\t\tNO\n-\t\t\tName\n-\t\t\tLayer 1\n-\t\t\tPrint\n-\t\t\tYES\n-\t\t\tView\n-\t\t\tYES\n-\t\t\n-\t\n-\tLayoutInfo\n-\t\n-\t\tAnimate\n-\t\tNO\n-\t\tcircoMinDist\n-\t\t18\n-\t\tcircoSeparation\n-\t\t0.0\n-\t\tlayoutEngine\n-\t\tdot\n-\t\tneatoSeparation\n-\t\t0.0\n-\t\ttwopiSeparation\n-\t\t0.0\n-\t\n-\tLinksVisible\n-\tNO\n-\tMagnetsVisible\n-\tNO\n-\tMasterSheets\n-\t\n-\tModificationDate\n-\t2009-09-11 10:38:54 -0400\n-\tModifier\n-\tThomas Risberg\n-\tNotesVisible\n-\tNO\n-\tOrientation\n-\t2\n-\tOriginVisible\n-\tNO\n-\tPageBreaks\n-\tYES\n-\tPrintInfo\n-\t\n-\t\tNSBottomMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t41\n-\t\t\n-\t\tNSLeftMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSOrientation\n-\t\t\n-\t\t\tint\n-\t\t\t1\n-\t\t\n-\t\tNSPaperSize\n-\t\t\n-\t\t\tsize\n-\t\t\t{792, 612}\n-\t\t\n-\t\tNSRightMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSTopMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\n-\tPrintOnePage\n-\t\n-\tQuickLookPreview\n-\t\n-\tJVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls\n-\tdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA\n-\tDRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p\n-\tT84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf\n-\thIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk\n-\tc56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9\n-\tBPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt\n-\toO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj\n-\tAHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY\n-\tv19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT\n-\tz2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm\n-\ts9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O\n-\t5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W\n-\tcvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI\n-\tx6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW\n-\t6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN\n-\t5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp\n-\thZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf\n-\twCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N\n-\tYfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i\n-\tago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50\n-\tIDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb\n-\tMCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv\n-\tVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg\n-\tMTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw\n-\tIDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0\n-\tIDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8\n-\tPCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp\n-\tZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg\n-\tUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh\n-\tbQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz\n-\tNAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg\n-\tL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK\n-\tMjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G\n-\tbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox\n-\tMyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl\n-\tIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D\n-\tb2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg\n-\tL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK\n-\tZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T\n-\tdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw\n-\tIDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh\n-\tdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i\n-\tago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg\n-\tL0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T\n-\tTWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k\n-\tZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0\n-\tcmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg\n-\tMjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I\n-\tZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50\n-\tIDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2\n-\t9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG\n-\tzfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA\n-\tHfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9\n-\tCPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp\n-\t4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW\n-\tFxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg\n-\tNBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW\n-\tpBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I\n-\thGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD\n-\trJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih\n-\tbEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1\n-\tSi4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2\n-\t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\n-\tWlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN\n-\tVm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa\n-\tUMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS\n-\tKZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a\n-\tBLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF\n-\tvAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD\n-\te9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK\n-\tZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv\n-\tTGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo\n-\tIDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv\n-\tbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH\n-\tBQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF\n-\txohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk\n-\tgASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw\n-\tXgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt\n-\t1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os\n-\tWsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj\n-\t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\n-\tWX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B\n-\tgwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl\n-\tbmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw\n-\tIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo\n-\tdCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv\n-\tRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu\n-\tueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521\n-\tCzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB\n-\tdJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5\n-\tkBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR\n-\tCf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo\n-\tIh2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q\n-\tU0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke\n-\t6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH\n-\tlA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C\n-\tpQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo\n-\tHRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF\n-\t42hrOSgdcoBDb7I5GDfrrfQHasN1DZGm5pbzKAIdaGluijTUhWsD/kov62YcNq56qOTJ\n-\tigdHB/QVDcBhdTCecl9NMFTf2NLa3tHVHUUR6UB3V0d7a0tjfShY4yv3MA6uuWiUUDyO\n-\ttRZoLNkSuSqHMlrtTJm3OhCONLd1Ri/19Pb1x2IDKOIciMX6+3p7LkU725oj4UC1t4yx\n-\tW41UDlc8jrWW9Ax4moXSYbDQxe7y6mBd04Wuiz19sWuDPw2PXB9FEefA9ZHhnwavxfp6\n-\tLnZdaKoLVpe7i2mLAYoHPNUeHTy4xgJTB2W0FbpYX6CuuT16+crVweHRm7fit8dQBDpw\n-\tO37r5ujw4NUrl6PtzXUBH+sqtBkpbvKA1vL126UJOtS5egtdUuatCQMcvbHBkRvxsfG7\n-\t9ybuowh0YOLe3fGx+I2RwVgv4BGu8ZaV0BZ9rjopHdlShUaXb3W42Mpg5EK0d2BoND52\n-\td2LywdSjaRSBDjyaejA5cXcsPjo00Bu9EAlWsi6HNV+nUUizj9UOUbZUyTWWIrfXH2rp\n-\tuhwb+jk+PvHb1PSTp7PPUAQ6MPv0yfTUbxPj8Z+HYpe7WkJ+r7uIay1KKYylRzqLSCxT\n-\t5ejNdInH911928UrP47Gx+8/nJ6Zm19YWlpGEefA0tLC/NzM9MP74/HRH69cbKv/zucp\n-\toc36HJVMnIQOuQrGDruTrapt7Oy5OgxwTD2enV9ceb76cg1FnAMvV5+vLM7PPp4CPIav\n-\t9nQ21laxTjsMHip5EjrgkUWX/01haTk0lmjf4I2xXx8+nltYfrG2/mrjNYo4BzZera+9\n-\tWF6Ye/zw17Ebg31RaC3lpYXf5OvgoeVY7YAHWrWOGzsqztW1/hAbjt+ZnJ5dWFn9Y+PN\n-\t5tZbFHEObG2+2fhjdWVhdnryTnw49kNr3bkKbvDQcQ8tR+cOoEMDdBR7fIGG9p5ro2MT\n-\tUzPzy6vrr7febu/soohzYGf77dbr9dXl+ZmpibHRaz3tDQGfpxjo0CSlQ6HJMxbAUBqM\n-\tdPQO3vxlcnpu8QXAsb37bg9FoAPvdrcBjxeLc9OTv9wc7O2IBGEsLTDmaRTJaodCm2ei\n-\tmW+rapu6+oZu3Xnw5PeVtY3N7d299x/2UcQ58OH93u725sbayu9PHty5NdTX1VRb9S1D\n-\tm/K0J9BBmWmGrQ41d/cPx+9NzSw8X3/z587e+/2PKAId2H+/t/Pnm/XnCzNT9+LD/d3N\n-\toWqWoc3UyXTAAy3Q8X1s5PbEo6eLq682t98BHJ8+o4hz4NPH/ffvtjdfrS4+fTRxeyT2\n-\tPUeH034qHS3R2PWx+9NzSy83tnb2PgAcX1DEOfD508cPeztbGy+X5qbvj12PwSPtSXTA\n-\tB/gShZYyJ2pHEjr+QhHmwBd+Or767mB6ZhZ8zAJvlbrO+MPnowOjUDueLa+9fru7t//x\n-\t8xfCnMFwwIEvnz/u7+2+fb22/Axqx+hA9HzYf8YFb5bCBy1ZmUiHsCFBOoSdf/7okQ5+\n-\tf4R9inQIO//80SMd/P4I+xTpEHb++aNHOvj9EfYp0iHs/PNHj3Tw+yPsU6RD2Pnnjx7p\n-\t4PdH2KdIh7Dzzx890sHvj7BPkQ5h558/eqSD3x9hnyIdws4/f/RIB78/wj5FOoSdf/7o\n-\tkQ5+f4R9inQIO//80SMd/P4I+xTpEHb++aNHOvj9EfYp0iHs/PNHj3Tw+yPsU6RD2Pnn\n-\tjx7p4PdH2Kep0IG/shYYK6n8yjrtFDqIu58AA+L/Df6R22z/44YGvN2FuKtckgT0X9zu\n-\tgjdDEXgF1AkhpXozFN4qR9zdcScHlOqtcngjJYH3Tp4cUmo3UuJttsTdWMsXUIq32eJN\n-\t2MTdds0XUEo3YYvwFn3iLsrnDSilW/RFYtzAQdyWDb6AUtvAgdt7iFvQwxtQatt7cPMX\n-\tgdu9+EJKZfNXJm4NJHAzIF9IqWwN5PbR4sZRAheLnhhSShtHcVsxgRuJ+UJKYVsxbjon\n-\tbpX5KQGlsuk8PUOUDe945FBGq50p81YHwpHmts7opZ7evv5YbABFnAOxWH9fb8+laGdb\n-\tcyQcqPaWMXarkcqBnYGwjvara9LT0tK5VecypUanN1kdjKfcVxMM1Te2tLZ3dHVHUUQ6\n-\t0N3V0d7a0lgfCtb4yj2Mw2rS6zRKmSQrMxkdXPHQAh42B+NmvZX+QG24riHS1NxyHkWg\n-\tAy3NTZGGunBtwF/pZd2MwwZwaLnScZwOKB4iKB4KwMNgstqLXWWs11flPxcI1oZCoTCK\n-\tOAcgrbXBwDl/lc/LlrmK7VaTAeBQQOk41lgOWks29BY1Vz2sdGGJy+1hyyvO+qqqQX4U\n-\tYQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA\n-\tJNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji\n-\tHHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK\n-\tUAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo\n-\t5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K\n-\tO/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I\n-\tpDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als\n-\tJB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv\n-\t8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu\n-\tZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg\n-\tUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0\n-\tIDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G\n-\taWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z\n-\tUui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+\n-\tZ4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K\n-\tIQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo\n-\tIh34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ\n-\t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\n-\tKjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz\n-\tiHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW\n-\tIsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY\n-\tEqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy\n-\tcsFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p\n-\tcvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX\n-\tmVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O\n-\tFJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb\n-\tuFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV\n-\t7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL\n-\tVPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL\n-\tv8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k\n-\tb2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS\n-\tIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg\n-\tMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7\n-\tpXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn\n-\t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\n-\tkC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C\n-\tL4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz\n-\tNyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k\n-\tb2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2\n-\taWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ\n-\t953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99\n-\t+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC\n-\tBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA\n-\tCDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ\n-\tABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh\n-\tBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT\n-\tgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB\n-\toGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp\n-\tfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS\n-\tVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f\n-\t/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4\n-\tv3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc\n-\tJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8\n-\tLKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc\n-\tph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ\n-\tUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu\n-\tH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+\n-\tOL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC\n-\tr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E\n-\tQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz\n-\tQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC\n-\tqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+\n-\tqr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y\n-\t5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr\n-\t+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy\n-\tejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV\n-\tLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9\n-\tTsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag\n-\t7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/\n-\tF3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9\n-\tt3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO\n-\tLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA\n-\tlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp\n-\tO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz\n-\tbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x\n-\tnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI\n-\t8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI\n-\taDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl\n-\tS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs\n-\tUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne\n-\tpb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik\n-\tc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi\n-\ttL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+\n-\tUIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs\n-\t5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+\n-\t7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k\n-\tnpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp\n-\tJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm\n-\tfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB\n-\t2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb\n-\tfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y\n-\t2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0\n-\tCmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv\n-\tYmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ\n-\tQ0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97\n-\tzue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw\n-\tyU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx\n-\tQcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1\n-\tCtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5\n-\tE4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk\n-\tBB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/\n-\t7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG\n-\twA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7\n-\tqbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D\n-\t+4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy\n-\tTPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx\n-\tRHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB\n-\tT01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64\n-\tcrm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn\n-\tE7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f\n-\te6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM\n-\t6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///\n-\tXfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj\n-\tdvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz\n-\tNMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE\n-\tKsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU\n-\trkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t\n-\tGe2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG\n-\tE5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd\n-\tKa2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV\n-\t/JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL\n-\tV6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H\n-\tg0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx\n-\t2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+\n-\tWLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3\n-\thi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN\n-\t1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ\n-\tfH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t\n-\taq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj\n-\t3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB\n-\t6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR\n-\trZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8\n-\t+KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3\n-\tJaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q\n-\tQMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf\n-\teJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF\n-\t9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa\n-\ttEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h\n-\tnaa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+\n-\tIwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN\n-\thsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI\n-\tq2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz\n-\tZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe\n-\tM3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri\n-\tJ7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn\n-\tN0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0\n-\tIDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu\n-\tZ3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2\n-\t2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf\n-\t5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i\n-\tTeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH\n-\ttSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU\n-\t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\n-\tqu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24\n-\tfagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1\n-\tYfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6\n-\tCekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P\n-\tgV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV\n-\t6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc\n-\tjvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q\n-\tteDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0\n-\tVDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS\n-\t9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH\n-\tT2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP\n-\txPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb\n-\tvo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ\n-\tCmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv\n-\tSUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS\n-\tIC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+\n-\tPgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj\n-\tszPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE\n-\tbZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2\n-\tPbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R\n-\tU+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j\n-\tnEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9\n-\tAHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e\n-\tLQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3\n-\t0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB\n-\tVnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE\n-\tj9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9\n-\tg0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx\n-\tW6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08\n-\tCT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK\n-\tZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD\n-\tQ0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv\n-\tTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz\n-\tdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC\n-\tkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN\n-\tAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN\n-\tkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC\n-\t72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV\n-\tA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY\n-\tgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC\n-\tLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A\n-\tZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn\n-\t4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv\n-\t0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv\n-\tWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh\n-\taZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y\n-\tjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW\n-\tS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D\n-\tqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA\n-\tn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s\n-\tLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v\n-\tDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu\n-\tf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I\n-\tuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ\n-\tnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j\n-\tx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG\n-\tK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns\n-\t2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2\n-\tUX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B\n-\tMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr\n-\tRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd\n-\tX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO\n-\t+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN\n-\tb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e\n-\tA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15\n-\tDLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc\n-\tQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg\n-\tIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD\n-\t0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh\n-\tbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU\n-\tm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn\n-\t840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek\n-\t1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z\n-\trsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp\n-\tfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj\n-\tD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6\n-\tRhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k\n-\tyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf\n-\tura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw\n-\t6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ\n-\tmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV\n-\tyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9\n-\tL3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0\n-\tmboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm\n-\tlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl\n-\tbmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg\n-\tMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy\n-\tbmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X\n-\tiTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR\n-\tvT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd\n-\tnZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT\n-\tTf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5\n-\tUnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI\n-\tbXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ\n-\twVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI\n-\teNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D\n-\toOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD\n-\tZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO\n-\tgC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd\n-\t2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD\n-\tbmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz\n-\tVdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT\n-\ttjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk\n-\t6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h\n-\tXREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5\n-\tiBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/\n-\tt8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU\n-\tzsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw\n-\tx8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB\n-\t/CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH\n-\tj2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt\n-\tumi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb\n-\tS4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2\n-\txT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15\n-\tlZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y\n-\tI67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf\n-\tdehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD\n-\tp+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ\n-\tl9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE\n-\tqy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc\n-\tUfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn\n-\tKhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz\n-\tE1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6\n-\tyRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ\n-\tn8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq\n-\tbOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r\n-\twozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub\n-\tvHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy\n-\terV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ\n-\tc1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+\n-\tUiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF\n-\tdVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2\n-\tYT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck\n-\teDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa\n-\tGBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv\n-\tMl78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o\n-\tWaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698\n-\tz2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p\n-\tzDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS\n-\tgMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw\n-\tIG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv\n-\tYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g\n-\tL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw\n-\tZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg\n-\tMCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF\n-\tTFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5\n-\tdWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta\n-\tmg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN\n-\tFHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv\n-\tkX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg\n-\tNa1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS\n-\tqo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr\n-\t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\n-\tMlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+\n-\tW73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1\n-\t8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT\n-\ti91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph\n-\tWq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d\n-\tCAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx\n-\thdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp\n-\toU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u\n-\tuo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr\n-\tAa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8\n-\trYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK\n-\tPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3\n-\tIC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg\n-\tMTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu\n-\tZ2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG\n-\taWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg\n-\tODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1\n-\tMDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg\n-\tMjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi\n-\tdHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg\n-\tL0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5\n-\tIC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i\n-\tago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg\n-\tL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD\n-\tSMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW\n-\tj2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n\n-\t4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u\n-\t7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM\n-\tF69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl\n-\tAN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq\n-\t6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn\n-\taby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO\n-\ttsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81\n-\t8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8\n-\t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\n-\tVrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a\n-\tiVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2\n-\tIDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv\n-\tciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz\n-\tMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT\n-\tK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg\n-\tL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK\n-\tNTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy\n-\tMiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1\n-\tNTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg\n-\tMCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry\n-\tdWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK\n-\tNTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv\n-\tRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp\n-\tdGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP\n-\tbW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv\n-\tbnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k\n-\tRGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK\n-\tMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg\n-\tMDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw\n-\tMDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw\n-\tMDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw\n-\tMDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw\n-\tMCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw\n-\tNDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg\n-\tbiAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw\n-\tNzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g\n-\tCjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0\n-\tIDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow\n-\tMDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw\n-\tMDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw\n-\tMDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw\n-\tMDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw\n-\tMjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw\n-\tIG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw\n-\tMTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu\n-\tIAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3\n-\tNyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK\n-\tMDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg\n-\tMDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw\n-\tMDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw\n-\tMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS\n-\tIC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk\n-\tYTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP\n-\tRgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo\n-\tRDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE\n-\tYXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR\n-\tdWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg\n-\tMQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3\n-\tZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm\n-\tMDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5\n-\tPj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==\n-\t\n-\tQuickLookThumbnail\n-\t\n-\t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\n-\tAdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH\n-\tvggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe\n-\tEuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki\n-\t1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy\n-\tOSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU\n-\taFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF\n-\tdvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e\n-\tYaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB\n-\tzfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j\n-\tdXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY\n-\tAPIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F\n-\togXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l\n-\tD14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd\n-\t1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn\n-\tMpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M\n-\tMk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul\n-\tbQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS\n-\tuZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y\n-\twHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry\n-\t7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO\n-\tAF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD\n-\t4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ\n-\tDDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ\n-\tQxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO\n-\tLGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E\n-\tcUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+\n-\tY49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H\n-\tjokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu\n-\ts3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk\n-\tKOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog\n-\tAAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA\n-\teQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw\n-\tADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2\n-\tY2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh\n-\tF2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v\n-\thzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk\n-\tR+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh\n-\t+WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr\n-\tfcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV\n-\tpJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+\n-\trF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC\n-\tNcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq\n-\t1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o\n-\tBOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt\n-\tEogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l\n-\tKSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy\n-\tNqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ\n-\tikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V\n-\tYH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1\n-\tVHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK\n-\tiwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud\n-\tOp34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N\n-\tr3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA\n-\tUsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI\n-\tEoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm\n-\tkydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc\n-\tON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N\n-\tc05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj\n-\tZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+\n-\tcX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6\n-\tlp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut\n-\trq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7\n-\tyNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo\n-\t4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA\n-\t9SH////2AAABX////RUAARx2\n-\t\n-\tReadOnly\n-\tNO\n-\tRowAlign\n-\t1\n-\tRowSpacing\n-\t36\n-\tSheetTitle\n-\tCanvas 1\n-\tSmartAlignmentGuidesActive\n-\tYES\n-\tSmartDistanceGuidesActive\n-\tYES\n-\tUniqueID\n-\t1\n-\tUseEntirePage\n-\t\n-\tVPages\n-\t1\n-\tWindowInfo\n-\t\n-\t\tCurrentSheet\n-\t\t0\n-\t\tExpandedCanvases\n-\t\t\n-\t\t\t\n-\t\t\t\tname\n-\t\t\t\tCanvas 1\n-\t\t\t\n-\t\t\n-\t\tFrame\n-\t\t{{218, 52}, {999, 826}}\n-\t\tListView\n-\t\t\n-\t\tOutlineWidth\n-\t\t142\n-\t\tRightSidebar\n-\t\t\n-\t\tShowRuler\n-\t\t\n-\t\tSidebar\n-\t\t\n-\t\tSidebarWidth\n-\t\t120\n-\t\tVisibleRegion\n-\t\t{{-54, -59}, {864, 672}}\n-\t\tZoom\n-\t\t1\n-\t\tZoomValues\n-\t\t\n-\t\t\t\n-\t\t\t\tCanvas 1\n-\t\t\t\t1\n-\t\t\t\t1\n-\t\t\t\n-\t\t\n-\t\n-\tsaveQuickLookFiles\n-\tYES\n-\n-\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png\ndeleted file mode 100644\nindex 8515e7c4887a..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/prototype.png b/framework-docs/src/docs/asciidoc/images/prototype.png\ndeleted file mode 100644\nindex 26fa2c1cf2d9..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/prototype.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/singleton.png b/framework-docs/src/docs/asciidoc/images/singleton.png\ndeleted file mode 100644\nindex 591520ec1dcc..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/singleton.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png\ndeleted file mode 100644\nindex 6e0eeab744d4..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx.png b/framework-docs/src/docs/asciidoc/images/tx.png\ndeleted file mode 100644\nindex 06f2e77c76f8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png b/framework-docs/src/docs/asciidoc/images/tx_prop_required.png\ndeleted file mode 100644\nindex 218790aca635..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png b/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png\ndeleted file mode 100644\nindex a8ece48193f3..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/index-docinfo-header.html b/framework-docs/src/docs/asciidoc/index-docinfo-header.html\ndeleted file mode 100644\nindex 485f2e4e9803..000000000000\n--- a/framework-docs/src/docs/asciidoc/index-docinfo-header.html\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-
\n-

Spring Framework Documentation

\n-\n-{revnumber}\n-
\ndiff --git a/framework-docs/src/docs/asciidoc/spring-framework.adocbook b/framework-docs/src/docs/asciidoc/spring-framework.adocbook\ndeleted file mode 100644\nindex e020f7337c2d..000000000000\n--- a/framework-docs/src/docs/asciidoc/spring-framework.adocbook\n+++ /dev/null\n@@ -1,26 +0,0 @@\n-:noheader:\n-:toc:\n-:toclevels: 4\n-:tabsize: 4\n-include::attributes.adoc[]\n-= Spring Framework Documentation\n-Rod Johnson; Juergen Hoeller; Keith Donald; Colin Sampaleanu; Rob Harrop; Thomas Risberg; Alef Arendsen; Darren Davison; Dmitriy Kopylenko; Mark Pollack; Thierry Templier; Erwin Vervaet; Portia Tung; Ben Hale; Adrian Colyer; John Lewis; Costin Leau; Mark Fisher; Sam Brannen; Ramnivas Laddad; Arjen Poutsma; Chris Beams; Tareq Abedrabbo; Andy Clement; Dave Syer; Oliver Gierke; Rossen Stoyanchev; Phillip Webb; Rob Winch; Brian Clozel; Stephane Nicoll; Sebastien Deleuze; Jay Bryant; Mark Paluch\n-\n-NOTE: This documentation is also available in {docs-spring-framework}/reference/html/index.html[HTML] format.\n-\n-[[legal]]\n-== Legal\n-\n-Copyright \u00a9 2002 - 2023 VMware, Inc. All Rights Reserved.\n-\n-Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.\n-\n-include::overview.adoc[leveloffset=+1]\n-include::core.adoc[leveloffset=+1]\n-include::testing.adoc[leveloffset=+1]\n-include::data-access.adoc[leveloffset=+1]\n-include::web.adoc[leveloffset=+1]\n-include::web-reactive.adoc[leveloffset=+1]\n-include::integration.adoc[leveloffset=+1]\n-include::languages.adoc[leveloffset=+1]\n-include::appendix.adoc[leveloffset=+1]\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30534, "url": "https://github.com/spring-projects/spring-framework/pull/30534", "commits": [{"commit_sha": "ef73ba93c87a83e481a5c9918440c5d162c4cfa9", "labeled_review_comments": [], "total_score": 0.30638297872340425, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java\nindex 10ed76efd52c..68f3883aebc4 100644\n--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java\n+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java\n@@ -78,6 +78,7 @@\n * @author Juergen Hoeller\n * @author Ramnivas Laddad\n * @author Dave Syer\n+ * @author Yanming Zhou\n * @since 2.0\n */\n @SuppressWarnings(\"serial\")\n@@ -470,8 +471,7 @@ private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {\n \t\t\t\t\t\t\t\tfallbackExpression = null;\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t}\n-\t\t\t\t\t\tif (targetMethod != originalMethod && (shadowMatch == null ||\n-\t\t\t\t\t\t\t\t(shadowMatch.neverMatches() && Proxy.isProxyClass(targetMethod.getDeclaringClass())))) {\n+\t\t\t\t\t\tif (targetMethod != originalMethod && (shadowMatch == null || shouldFallback(targetMethod))) {\n \t\t\t\t\t\t\t// Fall back to the plain original method in case of no resolvable match or a\n \t\t\t\t\t\t\t// negative match on a proxy class (which doesn't carry any annotations on its\n \t\t\t\t\t\t\t// redeclared methods).\n@@ -513,6 +513,12 @@ else if (shadowMatch.maybeMatches() && fallbackExpression != null) {\n \t\treturn shadowMatch;\n \t}\n \n+\tprivate boolean shouldFallback(Method targetMethod) {\n+\t\tif (!Proxy.isProxyClass(targetMethod.getDeclaringClass())) {\n+\t\t\treturn false;\n+\t\t}\n+\t\treturn this.resolveExpression().contains(\"@annotation\");\n+\t}\n \n \t@Override\n \tpublic boolean equals(@Nullable Object other) {\ndiff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java\nindex e1b2a93b9589..27aac8409128 100644\n--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java\n+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJExpressionPointcutTests.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2022 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -50,6 +50,7 @@\n * @author Rob Harrop\n * @author Rod Johnson\n * @author Chris Beams\n+ * @author Yanming Zhou\n */\n public class AspectJExpressionPointcutTests {\n \n@@ -424,6 +425,19 @@ public void testAnnotationOnCglibProxyMethod() throws Exception {\n \t\tassertThat(ajexp.matches(BeanA.class.getMethod(\"getAge\"), proxy.getClass())).isTrue();\n \t}\n \n+\n+\t@Test\n+\tpublic void testNotAnnotationOnCglibProxyMethod() throws Exception {\n+\t\tString expression = \"!@annotation(test.annotation.transaction.Tx)\";\n+\t\tAspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();\n+\t\tajexp.setExpression(expression);\n+\n+\t\tProxyFactory factory = new ProxyFactory(new BeanA());\n+\t\tfactory.setProxyTargetClass(true);\n+\t\tBeanA proxy = (BeanA) factory.getProxy();\n+\t\tassertThat(ajexp.matches(BeanA.class.getMethod(\"getAge\"), proxy.getClass())).isFalse();\n+\t}\n+\n \t@Test\n \tpublic void testAnnotationOnDynamicProxyMethod() throws Exception {\n \t\tString expression = \"@annotation(test.annotation.transaction.Tx)\";\n@@ -436,6 +450,18 @@ public void testAnnotationOnDynamicProxyMethod() throws Exception {\n \t\tassertThat(ajexp.matches(IBeanA.class.getMethod(\"getAge\"), proxy.getClass())).isTrue();\n \t}\n \n+\t@Test\n+\tpublic void testNotAnnotationOnDynamicProxyMethod() throws Exception {\n+\t\tString expression = \"!@annotation(test.annotation.transaction.Tx)\";\n+\t\tAspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();\n+\t\tajexp.setExpression(expression);\n+\n+\t\tProxyFactory factory = new ProxyFactory(new BeanA());\n+\t\tfactory.setProxyTargetClass(false);\n+\t\tIBeanA proxy = (IBeanA) factory.getProxy();\n+\t\tassertThat(ajexp.matches(IBeanA.class.getMethod(\"getAge\"), proxy.getClass())).isFalse();\n+\t}\n+\n \t@Test\n \tpublic void testAnnotationOnMethodWithWildcard() throws Exception {\n \t\tString expression = \"execution(@(test.annotation..*) * *(..))\";\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30238, "url": "https://github.com/spring-projects/spring-framework/pull/30238", "commits": [{"commit_sha": "a44bc02ba83a5e71c4b08d20fb00398b36c06620", "labeled_review_comments": [], "total_score": 0.4340425531914893, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\nindex cf0d39b17eb1..efa97c27194c 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n@@ -125,11 +125,11 @@ public static RequestMatcher requestTo(URI uri) {\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param matcher the Hamcrest matcher to apply to the entire list of values\n \t * for the given query parameter\n-\t * @since 5.3.26\n+\t * @since 5.3.27\n \t * @see #queryParam(String, Matcher...)\n \t * @see #queryParam(String, String...)\n \t */\n-\tpublic static RequestMatcher queryParam(String name, Matcher> matcher) {\n+\tpublic static RequestMatcher queryParamList(String name, Matcher> matcher) {\n \t\treturn request -> {\n \t\t\tMultiValueMap params = getQueryParams(request);\n \t\t\tList paramValues = params.get(name);\n@@ -147,14 +147,14 @@ public static RequestMatcher queryParam(String name, MatcherSee {@link #queryParam(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #queryParamList(String, Matcher)} for a variant which accepts a\n \t * {@code Matcher} that applies to the entire list of values as opposed to\n \t * applying only to individual values.\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param matchers the Hamcrest matchers to apply to individual query parameter\n \t * values; the nth matcher is applied to the nth query\n \t * parameter value\n-\t * @see #queryParam(String, Matcher)\n+\t * @see #queryParamList(String, Matcher)\n \t * @see #queryParam(String, String...)\n \t */\n \t@SafeVarargs\n@@ -175,14 +175,14 @@ public static RequestMatcher queryParam(String name, Matcher...\n \t * parameter values, effectively ignoring the additional parameter values. If\n \t * the number of {@code expectedValues} exceeds the number of query parameter\n \t * values, an {@link AssertionError} will be thrown to signal the mismatch.\n-\t *

See {@link #queryParam(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #queryParamList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as opposed\n \t * to asserting only individual values.\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param expectedValues the expected values of individual query parameter values;\n \t * the nth expected value is compared to the nth query\n \t * parameter value\n-\t * @see #queryParam(String, Matcher)\n+\t * @see #queryParamList(String, Matcher)\n \t * @see #queryParam(String, Matcher...)\n \t */\n \tpublic static RequestMatcher queryParam(String name, String... expectedValues) {\n@@ -211,11 +211,11 @@ private static MultiValueMap getQueryParams(ClientHttpRequest re\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param matcher the Hamcrest matcher to apply to the entire list of values\n \t * for the given header\n-\t * @since 5.3.26\n+\t * @since 5.3.27\n \t * @see #header(String, Matcher...)\n \t * @see #header(String, String...)\n \t */\n-\tpublic static RequestMatcher header(String name, Matcher> matcher) {\n+\tpublic static RequestMatcher headerList(String name, Matcher> matcher) {\n \t\treturn request -> {\n \t\t\tList headerValues = request.getHeaders().get(name);\n \t\t\tif (headerValues == null) {\n@@ -232,13 +232,13 @@ public static RequestMatcher header(String name, Matcher> m\n \t * effectively ignoring the additional header values. If the number of\n \t * provided {@code matchers} exceeds the number of header values, an\n \t * {@link AssertionError} will be thrown to signal the mismatch.\n-\t *

See {@link #header(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #headerList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as\n \t * opposed to applying only to individual values.\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param matchers the Hamcrest matchers to apply to individual header values;\n \t * the nth matcher is applied to the nth header value\n-\t * @see #header(String, Matcher)\n+\t * @see #headerList(String, Matcher)\n \t * @see #header(String, String...)\n \t */\n \t@SafeVarargs\n@@ -260,13 +260,13 @@ public static RequestMatcher header(String name, Matcher... matc\n \t * additional header values. If the number of {@code expectedValues} exceeds the\n \t * number of header values, an {@link AssertionError} will be thrown to signal the\n \t * mismatch.\n-\t *

See {@link #header(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #headerList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as\n \t * opposed to applying only to individual values.\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param expectedValues the expected values of individual header values; the\n \t * nth expected value is compared to the nth header value\n-\t * @see #header(String, Matcher)\n+\t * @see #headerList(String, Matcher)\n \t * @see #header(String, Matcher...)\n \t */\n \tpublic static RequestMatcher header(String name, String... expectedValues) {\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\nindex 3c8272f9f39d..0d036c54e624 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n@@ -35,6 +35,7 @@\n import static org.hamcrest.Matchers.containsString;\n import static org.hamcrest.Matchers.either;\n import static org.hamcrest.Matchers.endsWith;\n+import static org.hamcrest.Matchers.equalTo;\n import static org.hamcrest.Matchers.everyItem;\n import static org.hamcrest.Matchers.hasItem;\n import static org.hamcrest.Matchers.hasSize;\n@@ -163,7 +164,7 @@ void headerContainsWithMissingValue() {\n \t@Test\n \tvoid headerListMissing() {\n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", hasSize(2)).match(this.request))\n \t\t\t.withMessage(\"Expected header to exist but was null\");\n \t}\n \n@@ -171,29 +172,18 @@ void headerListMissing() {\n \tvoid headerListMatchers() throws IOException {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n \n-\t\tMockRestRequestMatchers.header(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request);\n-\n-\t\t// These can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n-\t\tMockRestRequestMatchers.header(\"foo\", notNullValue()).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is(anything())).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n-\n-\t\t// These are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n-\t\t// string-oriented, or obviously a vararg of matchers\n-\n-\t\t// list matcher version\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n-\n-\t\t// vararg version\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is((any(String.class)))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\tMockRestRequestMatchers.headerList(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\tMockRestRequestMatchers.headerList(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n \t}\n \n \t@Test\n@@ -201,27 +191,41 @@ void headerListContainsMismatch() {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: iterable containing [a string containing \\\"ba\\\"]\",\n \t\t\t\t\t\"but: not matched: \\\"baz\\\"\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: a collection containing a string ending with \\\"ba\\\"\",\n \t\t\t\t\t\"but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: every item is a string ending with \\\"ar\\\"\",\n \t\t\t\t\t\"but: an item was \\\"baz\\\"\");\n \t}\n \n+\t@Test\n+\tvoid headerListDoesntHideHeaderWithSingleMatcher() throws IOException {\n+\t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n+\n+\t\tMockRestRequestMatchers.header(\"foo\", equalTo(\"bar\")).match(this.request);\n+\n+\t\tassertThatAssertionError()\n+\t\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", equalTo(\"bar\")).match(this.request))\n+\t\t\t\t.withMessageContainingAll(\n+\t\t\t\t\t\t\"Request header [foo] values\",\n+\t\t\t\t\t\t\"Expected: \\\"bar\\\"\",\n+\t\t\t\t\t\t\"but: was <[bar, baz]>\");\n+\t}\n+\n \t@Test\n \tvoid headers() throws Exception {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n@@ -290,7 +294,7 @@ void queryParamContainsWithMissingValue() {\n \t@Test\n \tvoid queryParamListMissing() {\n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", hasSize(2)).match(this.request))\n \t\t\t.withMessage(\"Expected query param to exist but was null\");\n \t}\n \n@@ -298,29 +302,18 @@ void queryParamListMissing() {\n \tvoid queryParamListMatchers() throws IOException {\n \t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n \n-\t\tMockRestRequestMatchers.queryParam(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request);\n-\n-\t\t// These can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", notNullValue()).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is(anything())).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n-\n-\t\t// These are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n-\t\t// string-oriented, or obviously a vararg of matchers\n-\n-\t\t// list matcher version\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n-\n-\t\t// vararg version\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is((any(String.class)))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n \t}\n \n \t@Test\n@@ -328,27 +321,41 @@ void queryParamListContainsMismatch() {\n \t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: iterable containing [a string containing \\\"ba\\\"]\",\n \t\t\t\t\"but: not matched: \\\"baz\\\"\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: a collection containing a string ending with \\\"ba\\\"\",\n \t\t\t\t\"but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: every item is a string ending with \\\"ar\\\"\",\n \t\t\t\t\"but: an item was \\\"baz\\\"\");\n \t}\n \n+\t@Test\n+\tvoid queryParamListDoesntHideQueryParamWithSingleMatcher() throws IOException {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", equalTo(\"bar\")).match(this.request);\n+\n+\t\tassertThatAssertionError()\n+\t\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", equalTo(\"bar\")).match(this.request))\n+\t\t\t\t.withMessageContainingAll(\n+\t\t\t\t\t\t\"Query param [foo] values\",\n+\t\t\t\t\t\t\"Expected: \\\"bar\\\"\",\n+\t\t\t\t\t\t\"but: was <[bar, baz]>\");\n+\t}\n+\n \tprivate static ThrowableTypeAssert assertThatAssertionError() {\n \t\treturn assertThatExceptionOfType(AssertionError.class);\n \t}\n"}, {"commit_sha": "596f3559e09a656f75df464bec4166bd91ba84df", "labeled_review_comments": [], "total_score": 0.26382978723404255, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\nindex cf0d39b17eb1..efa97c27194c 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n@@ -125,11 +125,11 @@ public static RequestMatcher requestTo(URI uri) {\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param matcher the Hamcrest matcher to apply to the entire list of values\n \t * for the given query parameter\n-\t * @since 5.3.26\n+\t * @since 5.3.27\n \t * @see #queryParam(String, Matcher...)\n \t * @see #queryParam(String, String...)\n \t */\n-\tpublic static RequestMatcher queryParam(String name, Matcher> matcher) {\n+\tpublic static RequestMatcher queryParamList(String name, Matcher> matcher) {\n \t\treturn request -> {\n \t\t\tMultiValueMap params = getQueryParams(request);\n \t\t\tList paramValues = params.get(name);\n@@ -147,14 +147,14 @@ public static RequestMatcher queryParam(String name, MatcherSee {@link #queryParam(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #queryParamList(String, Matcher)} for a variant which accepts a\n \t * {@code Matcher} that applies to the entire list of values as opposed to\n \t * applying only to individual values.\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param matchers the Hamcrest matchers to apply to individual query parameter\n \t * values; the nth matcher is applied to the nth query\n \t * parameter value\n-\t * @see #queryParam(String, Matcher)\n+\t * @see #queryParamList(String, Matcher)\n \t * @see #queryParam(String, String...)\n \t */\n \t@SafeVarargs\n@@ -175,14 +175,14 @@ public static RequestMatcher queryParam(String name, Matcher...\n \t * parameter values, effectively ignoring the additional parameter values. If\n \t * the number of {@code expectedValues} exceeds the number of query parameter\n \t * values, an {@link AssertionError} will be thrown to signal the mismatch.\n-\t *

See {@link #queryParam(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #queryParamList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as opposed\n \t * to asserting only individual values.\n \t * @param name the name of the query parameter whose value(s) will be asserted\n \t * @param expectedValues the expected values of individual query parameter values;\n \t * the nth expected value is compared to the nth query\n \t * parameter value\n-\t * @see #queryParam(String, Matcher)\n+\t * @see #queryParamList(String, Matcher)\n \t * @see #queryParam(String, Matcher...)\n \t */\n \tpublic static RequestMatcher queryParam(String name, String... expectedValues) {\n@@ -211,11 +211,11 @@ private static MultiValueMap getQueryParams(ClientHttpRequest re\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param matcher the Hamcrest matcher to apply to the entire list of values\n \t * for the given header\n-\t * @since 5.3.26\n+\t * @since 5.3.27\n \t * @see #header(String, Matcher...)\n \t * @see #header(String, String...)\n \t */\n-\tpublic static RequestMatcher header(String name, Matcher> matcher) {\n+\tpublic static RequestMatcher headerList(String name, Matcher> matcher) {\n \t\treturn request -> {\n \t\t\tList headerValues = request.getHeaders().get(name);\n \t\t\tif (headerValues == null) {\n@@ -232,13 +232,13 @@ public static RequestMatcher header(String name, Matcher> m\n \t * effectively ignoring the additional header values. If the number of\n \t * provided {@code matchers} exceeds the number of header values, an\n \t * {@link AssertionError} will be thrown to signal the mismatch.\n-\t *

See {@link #header(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #headerList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as\n \t * opposed to applying only to individual values.\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param matchers the Hamcrest matchers to apply to individual header values;\n \t * the nth matcher is applied to the nth header value\n-\t * @see #header(String, Matcher)\n+\t * @see #headerList(String, Matcher)\n \t * @see #header(String, String...)\n \t */\n \t@SafeVarargs\n@@ -260,13 +260,13 @@ public static RequestMatcher header(String name, Matcher... matc\n \t * additional header values. If the number of {@code expectedValues} exceeds the\n \t * number of header values, an {@link AssertionError} will be thrown to signal the\n \t * mismatch.\n-\t *

See {@link #header(String, Matcher)} for a variant which accepts a\n+\t *

See {@link #headerList(String, Matcher)} for a variant which accepts a\n \t * Hamcrest {@code Matcher} that applies to the entire list of values as\n \t * opposed to applying only to individual values.\n \t * @param name the name of the header whose value(s) will be asserted\n \t * @param expectedValues the expected values of individual header values; the\n \t * nth expected value is compared to the nth header value\n-\t * @see #header(String, Matcher)\n+\t * @see #headerList(String, Matcher)\n \t * @see #header(String, Matcher...)\n \t */\n \tpublic static RequestMatcher header(String name, String... expectedValues) {\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\nindex 3c8272f9f39d..f91b66f2f6dc 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n@@ -28,19 +28,17 @@\n \n import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.hamcrest.Matchers.allOf;\n-import static org.hamcrest.Matchers.any;\n import static org.hamcrest.Matchers.anything;\n import static org.hamcrest.Matchers.contains;\n import static org.hamcrest.Matchers.containsInAnyOrder;\n import static org.hamcrest.Matchers.containsString;\n-import static org.hamcrest.Matchers.either;\n import static org.hamcrest.Matchers.endsWith;\n+import static org.hamcrest.Matchers.equalTo;\n import static org.hamcrest.Matchers.everyItem;\n import static org.hamcrest.Matchers.hasItem;\n import static org.hamcrest.Matchers.hasSize;\n import static org.hamcrest.Matchers.is;\n import static org.hamcrest.Matchers.notNullValue;\n-import static org.hamcrest.Matchers.nullValue;\n import static org.hamcrest.Matchers.startsWith;\n \n /**\n@@ -163,7 +161,7 @@ void headerContainsWithMissingValue() {\n \t@Test\n \tvoid headerListMissing() {\n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", hasSize(2)).match(this.request))\n \t\t\t.withMessage(\"Expected header to exist but was null\");\n \t}\n \n@@ -171,29 +169,18 @@ void headerListMissing() {\n \tvoid headerListMatchers() throws IOException {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n \n-\t\tMockRestRequestMatchers.header(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request);\n-\n-\t\t// These can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n-\t\tMockRestRequestMatchers.header(\"foo\", notNullValue()).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is(anything())).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n-\n-\t\t// These are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n-\t\t// string-oriented, or obviously a vararg of matchers\n-\n-\t\t// list matcher version\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n-\n-\t\t// vararg version\n-\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is((any(String.class)))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n-\t\tMockRestRequestMatchers.header(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\tMockRestRequestMatchers.headerList(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.headerList(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\tMockRestRequestMatchers.headerList(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n \t}\n \n \t@Test\n@@ -201,27 +188,41 @@ void headerListContainsMismatch() {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: iterable containing [a string containing \\\"ba\\\"]\",\n \t\t\t\t\t\"but: not matched: \\\"baz\\\"\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: a collection containing a string ending with \\\"ba\\\"\",\n \t\t\t\t\t\"but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.header(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\t\"Request header [foo] values\",\n \t\t\t\t\t\"Expected: every item is a string ending with \\\"ar\\\"\",\n \t\t\t\t\t\"but: an item was \\\"baz\\\"\");\n \t}\n \n+\t@Test\n+\tvoid headerListDoesntHideHeaderWithSingleMatcher() throws IOException {\n+\t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n+\n+\t\tMockRestRequestMatchers.header(\"foo\", equalTo(\"bar\")).match(this.request);\n+\n+\t\tassertThatAssertionError()\n+\t\t\t\t.isThrownBy(() -> MockRestRequestMatchers.headerList(\"foo\", equalTo(\"bar\")).match(this.request))\n+\t\t\t\t.withMessageContainingAll(\n+\t\t\t\t\t\t\"Request header [foo] values\",\n+\t\t\t\t\t\t\"Expected: \\\"bar\\\"\",\n+\t\t\t\t\t\t\"but: was <[bar, baz]>\");\n+\t}\n+\n \t@Test\n \tvoid headers() throws Exception {\n \t\tthis.request.getHeaders().put(\"foo\", List.of(\"bar\", \"baz\"));\n@@ -290,7 +291,7 @@ void queryParamContainsWithMissingValue() {\n \t@Test\n \tvoid queryParamListMissing() {\n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", hasSize(2)).match(this.request))\n \t\t\t.withMessage(\"Expected query param to exist but was null\");\n \t}\n \n@@ -298,29 +299,18 @@ void queryParamListMissing() {\n \tvoid queryParamListMatchers() throws IOException {\n \t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n \n-\t\tMockRestRequestMatchers.queryParam(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request);\n-\n-\t\t// These can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", notNullValue()).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is(anything())).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n-\n-\t\t// These are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n-\t\t// string-oriented, or obviously a vararg of matchers\n-\n-\t\t// list matcher version\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n-\n-\t\t// vararg version\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is((any(String.class)))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n-\t\tMockRestRequestMatchers.queryParam(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", contains(is(\"bar\"), anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\tMockRestRequestMatchers.queryParamList(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n \t}\n \n \t@Test\n@@ -328,27 +318,41 @@ void queryParamListContainsMismatch() {\n \t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: iterable containing [a string containing \\\"ba\\\"]\",\n \t\t\t\t\"but: not matched: \\\"baz\\\"\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: a collection containing a string ending with \\\"ba\\\"\",\n \t\t\t\t\"but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n \n \t\tassertThatAssertionError()\n-\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n \t\t\t.withMessageContainingAll(\n \t\t\t\t\"Query param [foo] values\",\n \t\t\t\t\"Expected: every item is a string ending with \\\"ar\\\"\",\n \t\t\t\t\"but: an item was \\\"baz\\\"\");\n \t}\n \n+\t@Test\n+\tvoid queryParamListDoesntHideQueryParamWithSingleMatcher() throws IOException {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", equalTo(\"bar\")).match(this.request);\n+\n+\t\tassertThatAssertionError()\n+\t\t\t\t.isThrownBy(() -> MockRestRequestMatchers.queryParamList(\"foo\", equalTo(\"bar\")).match(this.request))\n+\t\t\t\t.withMessageContainingAll(\n+\t\t\t\t\t\t\"Query param [foo] values\",\n+\t\t\t\t\t\t\"Expected: \\\"bar\\\"\",\n+\t\t\t\t\t\t\"but: was <[bar, baz]>\");\n+\t}\n+\n \tprivate static ThrowableTypeAssert assertThatAssertionError() {\n \t\treturn assertThatExceptionOfType(AssertionError.class);\n \t}\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30216, "url": "https://github.com/spring-projects/spring-framework/pull/30216", "commits": [{"commit_sha": "38a31f6dd8b5e2dd15187ef6f2f63c811500555e", "labeled_review_comments": [], "total_score": 0.2936170212765958, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.7}, "patch": "diff --git a/build.gradle b/build.gradle\nindex 8406fcb690a4..d26a360ee64e 100644\n--- a/build.gradle\n+++ b/build.gradle\n@@ -105,7 +105,7 @@ configure([rootProject] + javaProjects) { project ->\n \t\ttestRuntimeOnly(\"org.junit.platform:junit-platform-suite-engine\")\n \t\ttestRuntimeOnly(\"org.apache.logging.log4j:log4j-core\")\n \t\ttestRuntimeOnly(\"org.apache.logging.log4j:log4j-jul\")\n-\t\ttestRuntimeOnly(\"org.apache.logging.log4j:log4j-slf4j-impl\")\n+\t\ttestRuntimeOnly(\"org.apache.logging.log4j:log4j-slf4j2-impl\")\n \t\t// JSR-305 only used for non-required meta-annotations\n \t\tcompileOnly(\"com.google.code.findbugs:jsr305\")\n \t\ttestCompileOnly(\"com.google.code.findbugs:jsr305\")\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30108, "url": "https://github.com/spring-projects/spring-framework/pull/30108", "commits": [{"commit_sha": "7027e43cc9d2b195157849a7e2a5afc113b13b27", "labeled_review_comments": [], "total_score": 0.374468085106383, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.30000000000000004, "conventional_commit": true, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/framework-docs/src/docs/asciidoc/data-access.adoc b/framework-docs/src/docs/asciidoc/data-access.adoc\nindex 9b853f36623a..28dd4b85a32e 100644\n--- a/framework-docs/src/docs/asciidoc/data-access.adoc\n+++ b/framework-docs/src/docs/asciidoc/data-access.adoc\n@@ -1028,7 +1028,23 @@ the call stack and makes a determination whether to mark the transaction for rol\n In its default configuration, the Spring Framework's transaction infrastructure code\n marks a transaction for rollback only in the case of runtime, unchecked exceptions.\n That is, when the thrown exception is an instance or subclass of `RuntimeException`.\n-(`Error` instances also, by default, result in a rollback). Checked exceptions that are\n+(`Error` instances also, by default, result in a rollback).\n+\n+However, starting with Spring Framework 5.2.0 the default configuration also provides support for Vavr's `Try` method to trigger transaction rollbacks when it returns a 'Failure'. This allows you to handle functional-style errors using Try and have the transaction automatically rolled back in case of a failure.\n+\n+Here's an example of how to use Vavr's Try:\n+[source,java,indent=0,subs=\"verbatim,quotes\",role=\"primary\"]\n+.Java\n+----\n+ @Transactional\n+ public Try myTransactionalMethod() {\n+ // If transactionMethod throws an exception, it will be caught by the Try instance created with Try.of() and wrapped inside the Failure class, which can be checked using the isFailure() method on the Try instance.\n+ return Try.of(serviceA::transactionalMethod);\n+ }\n+----\n+For more information on Vavr's Try, refer to the [official Vavr documentation](https://www.vavr.io/vavr-docs/#_try).\n+\n+Checked exceptions that are\n thrown from a transactional method do not result in rollback in the default\n configuration.\n \n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30045, "url": "https://github.com/spring-projects/spring-framework/pull/30045", "commits": [{"commit_sha": "88a5167bf0cd6388310d716f7983ddbbe91156c5", "labeled_review_comments": [], "total_score": 0.39574468085106385, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": true, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex a87addc06f54..cfde855e6d3c 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -47,7 +47,9 @@ The expression language supports the following functionality:\n * Inline maps\n * Ternary operator\n * Variables\n-* User-defined functions\n+* User-defined functions added to the context\n+ * reflective invocation of `Method`\n+ * various cases of `MethodHandle`\n * Collection projection\n * Collection selection\n * Templated expressions\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc\nindex f920ac60470e..c69ffaf6bc1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref.adoc\n@@ -15,7 +15,7 @@ topics:\n * xref:core/expressions/language-ref/types.adoc[Types]\n * xref:core/expressions/language-ref/constructors.adoc[Constructors]\n * xref:core/expressions/language-ref/variables.adoc[Variables]\n-* xref:core/expressions/language-ref/functions.adoc[Functions]\n+* xref:core/expressions/language-ref/functions.adoc[User-Defined Functions]\n * xref:core/expressions/language-ref/bean-references.adoc[Bean References]\n * xref:core/expressions/language-ref/operator-ternary.adoc[Ternary Operator (If-Then-Else)]\n * xref:core/expressions/language-ref/operator-elvis.adoc[The Elvis Operator]\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc\nindex 014d6e8b8c44..4621b2a19aaa 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/functions.adoc\n@@ -3,7 +3,8 @@\n \n You can extend SpEL by registering user-defined functions that can be called within the\n expression string. The function is registered through the `EvaluationContext`. The\n-following example shows how to register a user-defined function:\n+following example shows how to register a user-defined function to be invoked via reflection\n+(i.e. a `Method`):\n \n [tabs]\n ======\n@@ -94,5 +95,97 @@ Kotlin::\n ----\n ======\n \n+The use of `MethodHandle` is also supported. This enables potentially more efficient use\n+cases if the `MethodHandle` target and parameters have been fully bound prior to\n+registration, but partially bound handles are also supported.\n+\n+Consider the `String#formatted(String, Object...)` instance method, which produces a\n+message according to a template and a variable number of arguments.\n+\n+You can register and use the `formatted` method as a `MethodHandle`, as the following\n+example shows:\n+\n+[tabs]\n+======\n+Java::\n++\n+[source,java,indent=0,subs=\"verbatim,quotes\",role=\"primary\"]\n+----\n+\tExpressionParser parser = new SpelExpressionParser();\n+\tEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();\n+\n+\tMethodHandle mh = MethodHandles.lookup().findVirtual(String.class, \"formatted\",\n+\t\t\tMethodType.methodType(String.class, Object[].class));\n+\tcontext.setVariable(\"message\", mh);\n+\n+\tString message = parser.parseExpression(\"#message('Simple message: <%s>', 'Hello World', 'ignored')\")\n+\t\t\t.getValue(context, String.class);\n+\t//returns \"Simple message: \"\n+----\n+\n+Kotlin::\n++\n+[source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n+----\n+\tval parser = SpelExpressionParser()\n+\tval context = SimpleEvaluationContext.forReadOnlyDataBinding().build()\n+\n+\tval mh = MethodHandles.lookup().findVirtual(String::class.java, \"formatted\",\n+\t\t\tMethodType.methodType(String::class.java, Array::class.java))\n+\tcontext.setVariable(\"message\", mh)\n+\n+\tval message = parser.parseExpression(\"#message('Simple message: <%s>', 'Hello World', 'ignored')\")\n+\t\t\t.getValue(context, String::class.java)\n+----\n+======\n+\n+As hinted above, binding a `MethodHandle` and registering the bound `MethodHandle` is also\n+supported. This is likely to be more performant if both the target and all the arguments\n+are bound. In that case no arguments are necessary in the SpEL expression, as the\n+following example shows:\n+\n+[tabs]\n+======\n+Java::\n++\n+[source,java,indent=0,subs=\"verbatim,quotes\",role=\"primary\"]\n+----\n+\tExpressionParser parser = new SpelExpressionParser();\n+\tEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();\n+\n+\tString template = \"This is a %s message with %s words: <%s>\";\n+\tObject varargs = new Object[] { \"prerecorded\", 3, \"Oh Hello World!\", \"ignored\" };\n+\tMethodHandle mh = MethodHandles.lookup().findVirtual(String.class, \"formatted\",\n+\t\t\tMethodType.methodType(String.class, Object[].class))\n+\t\t\t.bindTo(template)\n+\t\t\t.bindTo(varargs); //here we have to provide arguments in a single array binding\n+\tcontext.setVariable(\"message\", mh);\n+\n+\tString message = parser.parseExpression(\"#message()\")\n+\t\t\t.getValue(context, String.class);\n+\t//returns \"This is a prerecorded message with 3 words: \"\n+----\n+\n+Kotlin::\n++\n+[source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n+----\n+\tval parser = SpelExpressionParser()\n+\tval context = SimpleEvaluationContext.forReadOnlyDataBinding().build()\n+\n+\tval template = \"This is a %s message with %s words: <%s>\"\n+\tval varargs = arrayOf(\"prerecorded\", 3, \"Oh Hello World!\", \"ignored\")\n+\n+\tval mh = MethodHandles.lookup().findVirtual(String::class.java, \"formatted\",\n+\t\t\tMethodType.methodType(String::class.java, Array::class.java))\n+\t\t\t.bindTo(template)\n+\t\t\t.bindTo(varargs) //here we have to provide arguments in a single array binding\n+\tcontext.setVariable(\"message\", mh)\n+\n+\tval message = parser.parseExpression(\"#message()\")\n+\t\t\t.getValue(context, String::class.java)\n+----\n+======\n+\n \n \ndiff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java\nindex 4ad5b0dda907..766ac2704bbd 100644\n--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java\n+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java\n@@ -16,6 +16,8 @@\n \n package org.springframework.expression.spel.ast;\n \n+import java.lang.invoke.MethodHandle;\n+import java.lang.invoke.MethodType;\n import java.lang.reflect.Method;\n import java.lang.reflect.Modifier;\n import java.util.StringJoiner;\n@@ -70,7 +72,17 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep\n \t\tif (value == TypedValue.NULL) {\n \t\t\tthrow new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_NOT_DEFINED, this.name);\n \t\t}\n-\t\tif (!(value.getValue() instanceof Method function)) {\n+\t\tObject resolvedValue = value.getValue();\n+\t\tif (resolvedValue instanceof MethodHandle methodHandle) {\n+\t\t\ttry {\n+\t\t\t\treturn executeFunctionBoundMethodHandle(state, methodHandle);\n+\t\t\t}\n+\t\t\tcatch (SpelEvaluationException ex) {\n+\t\t\t\tex.setPosition(getStartPosition());\n+\t\t\t\tthrow ex;\n+\t\t\t}\n+\t\t}\n+\t\tif (!(resolvedValue instanceof Method function)) {\n \t\t\t// Possibly a static Java method registered as a function\n \t\t\tthrow new SpelEvaluationException(\n \t\t\t\t\tSpelMessage.FUNCTION_REFERENCE_CANNOT_BE_INVOKED, this.name, value.getClass());\n@@ -138,6 +150,78 @@ private TypedValue executeFunctionJLRMethod(ExpressionState state, Method method\n \t\t}\n \t}\n \n+\t/**\n+\t * Execute a function represented as {@code java.lang.invoke.MethodHandle}.\n+\t * Method types that take no arguments (fully bound handles or static methods\n+\t * with no parameters) can use {@code #invoke()} which is the most efficient.\n+\t * Otherwise, {@code #invokeWithArguments)} is used.\n+\t * @param state the expression evaluation state\n+\t * @param methodHandle the method to invoke\n+\t * @return the return value of the invoked Java method\n+\t * @throws EvaluationException if there is any problem invoking the method\n+\t * @since 6.1.0\n+\t */\n+\tprivate TypedValue executeFunctionBoundMethodHandle(ExpressionState state, MethodHandle methodHandle) throws EvaluationException {\n+\t\tObject[] functionArgs = getArguments(state);\n+\t\tMethodType declaredParams = methodHandle.type();\n+\t\tint spelParamCount = functionArgs.length;\n+\t\tint declaredParamCount = declaredParams.parameterCount();\n+\n+\t\tboolean isSuspectedVarargs = declaredParams.lastParameterType().isArray();\n+\n+\t\tif (spelParamCount < declaredParamCount || (spelParamCount > declaredParamCount\n+\t\t\t\t&& !isSuspectedVarargs)) {\n+\t\t\t//incorrect number, including more arguments and not a vararg\n+\t\t\tthrow new SpelEvaluationException(SpelMessage.INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION,\n+\t\t\t\t\tfunctionArgs.length, declaredParamCount);\n+\t\t\t//perhaps a subset of arguments was provided but the MethodHandle wasn't bound?\n+\t\t}\n+\n+\t\t// simplest case: the MethodHandle is fully bound or represents a static method with no params:\n+\t\tif (declaredParamCount == 0) {\n+\t\t\t//note we consider MethodHandles not compilable\n+\t\t\ttry {\n+\t\t\t\treturn new TypedValue(methodHandle.invoke());\n+\t\t\t}\n+\t\t\tcatch (Throwable ex) {\n+\t\t\t\tthrow new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL,\n+\t\t\t\t\t\tthis.name, ex.getMessage());\n+\t\t\t}\n+\t\t\tfinally {\n+\t\t\t\tthis.exitTypeDescriptor = null;\n+\t\t\t\tthis.method = null;\n+\t\t\t}\n+\t\t}\n+\n+\t\t// more complex case, we need to look at conversion and vararg repacking\n+\t\tInteger varArgPosition = null;\n+\t\tif (isSuspectedVarargs) {\n+\t\t\tvarArgPosition = declaredParamCount - 1;\n+\t\t}\n+\t\tTypeConverter converter = state.getEvaluationContext().getTypeConverter();\n+\t\tboolean conversionOccurred = ReflectionHelper.convertAllMethodHandleArguments(converter,\n+\t\t\t\tfunctionArgs, methodHandle, varArgPosition);\n+\n+\t\tif (isSuspectedVarargs && declaredParamCount == 1) {\n+\t\t\t//we only repack the varargs if it is the ONLY argument\n+\t\t\tfunctionArgs = ReflectionHelper.setupArgumentsForVarargsInvocation(\n+\t\t\t\t\tmethodHandle.type().parameterArray(), functionArgs);\n+\t\t}\n+\n+\t\t//note we consider MethodHandles not compilable\n+\t\ttry {\n+\t\t\treturn new TypedValue(methodHandle.invokeWithArguments(functionArgs));\n+\t\t}\n+\t\tcatch (Throwable ex) {\n+\t\t\tthrow new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL,\n+\t\t\t\t\tthis.name, ex.getMessage());\n+\t\t}\n+\t\tfinally {\n+\t\t\tthis.exitTypeDescriptor = null;\n+\t\t\tthis.method = null;\n+\t\t}\n+\t}\n+\n \t@Override\n \tpublic String toStringAST() {\n \t\tStringJoiner sj = new StringJoiner(\",\", \"(\", \")\");\ndiff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java\nindex e9b62ec2adbb..2e44a02fce96 100644\n--- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java\n+++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java\n@@ -16,6 +16,8 @@\n \n package org.springframework.expression.spel.support;\n \n+import java.lang.invoke.MethodHandle;\n+import java.lang.invoke.MethodType;\n import java.lang.reflect.Array;\n import java.lang.reflect.Executable;\n import java.lang.reflect.Method;\n@@ -23,6 +25,7 @@\n import java.util.Optional;\n \n import org.springframework.core.MethodParameter;\n+import org.springframework.core.ResolvableType;\n import org.springframework.core.convert.TypeDescriptor;\n import org.springframework.expression.EvaluationException;\n import org.springframework.expression.TypeConverter;\n@@ -330,6 +333,91 @@ else if (!sourceType.equals(targetType.getElementTypeDescriptor())) {\n \t\treturn conversionOccurred;\n \t}\n \n+\t/**\n+\t * Takes an input set of argument values and converts them to the types specified as the\n+\t * required parameter types. The arguments are converted 'in-place' in the input array.\n+\t * @param converter the type converter to use for attempting conversions\n+\t * @param arguments the actual arguments that need conversion\n+\t * @param methodHandle the target MethodHandle\n+\t * @param varargsPosition the known position of the varargs argument, if any\n+\t * ({@code null} if not varargs)\n+\t * @return {@code true} if some kind of conversion occurred on an argument\n+\t * @throws EvaluationException if a problem occurs during conversion\n+\t * @since 6.1.0\n+\t */\n+\tpublic static boolean convertAllMethodHandleArguments(TypeConverter converter, Object[] arguments,\n+\t\t\tMethodHandle methodHandle, @Nullable Integer varargsPosition) throws EvaluationException {\n+\t\tboolean conversionOccurred = false;\n+\t\tfinal MethodType methodHandleArgumentTypes = methodHandle.type();\n+\t\tif (varargsPosition == null) {\n+\t\t\tfor (int i = 0; i < arguments.length; i++) {\n+\t\t\t\tClass argumentClass = methodHandleArgumentTypes.parameterType(i);\n+\t\t\t\tResolvableType resolvableType = ResolvableType.forClass(argumentClass);\n+\t\t\t\tTypeDescriptor targetType = new TypeDescriptor(resolvableType, argumentClass, null);\n+\n+\t\t\t\tObject argument = arguments[i];\n+\t\t\t\targuments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);\n+\t\t\t\tconversionOccurred |= (argument != arguments[i]);\n+\t\t\t}\n+\t\t}\n+\t\telse {\n+\t\t\t// Convert everything up to the varargs position\n+\t\t\tfor (int i = 0; i < varargsPosition; i++) {\n+\t\t\t\tClass argumentClass = methodHandleArgumentTypes.parameterType(i);\n+\t\t\t\tResolvableType resolvableType = ResolvableType.forClass(argumentClass);\n+\t\t\t\tTypeDescriptor targetType = new TypeDescriptor(resolvableType, argumentClass, null);\n+\n+\t\t\t\tObject argument = arguments[i];\n+\t\t\t\targuments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);\n+\t\t\t\tconversionOccurred |= (argument != arguments[i]);\n+\t\t\t}\n+\n+\t\t\tfinal Class varArgClass = methodHandleArgumentTypes.lastParameterType().getComponentType();\n+\t\t\tResolvableType varArgResolvableType = ResolvableType.forClass(varArgClass);\n+\t\t\tTypeDescriptor varArgContentType = new TypeDescriptor(varArgResolvableType, varArgClass, null);\n+\n+\t\t\t// If the target is varargs and there is just one more argument, then convert it here.\n+\t\t\tif (varargsPosition == arguments.length - 1) {\n+\t\t\t\tObject argument = arguments[varargsPosition];\n+\t\t\t\tTypeDescriptor sourceType = TypeDescriptor.forObject(argument);\n+\t\t\t\tif (argument == null) {\n+\t\t\t\t\t// Perform the equivalent of GenericConversionService.convertNullSource() for a single argument.\n+\t\t\t\t\tif (varArgContentType.getElementTypeDescriptor().getObjectType() == Optional.class) {\n+\t\t\t\t\t\targuments[varargsPosition] = Optional.empty();\n+\t\t\t\t\t\tconversionOccurred = true;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t// If the argument type is equal to the varargs element type, there is no need to\n+\t\t\t\t// convert it or wrap it in an array. For example, using StringToArrayConverter to\n+\t\t\t\t// convert a String containing a comma would result in the String being split and\n+\t\t\t\t// repackaged in an array when it should be used as-is.\n+\t\t\t\telse if (!sourceType.equals(varArgContentType.getElementTypeDescriptor())) {\n+\t\t\t\t\targuments[varargsPosition] = converter.convertValue(argument, sourceType, varArgContentType);\n+\t\t\t\t}\n+\t\t\t\t// Possible outcomes of the above if-else block:\n+\t\t\t\t// 1) the input argument was null, and nothing was done.\n+\t\t\t\t// 2) the input argument was null; the varargs element type is Optional; and the argument was converted to Optional.empty().\n+\t\t\t\t// 3) the input argument was correct type but not wrapped in an array, and nothing was done.\n+\t\t\t\t// 4) the input argument was already compatible (i.e., array of valid type), and nothing was done.\n+\t\t\t\t// 5) the input argument was the wrong type and got converted and wrapped in an array.\n+\t\t\t\tif (argument != arguments[varargsPosition] &&\n+\t\t\t\t\t\t!isFirstEntryInArray(argument, arguments[varargsPosition])) {\n+\t\t\t\t\tconversionOccurred = true; // case 5\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\t// Otherwise, convert remaining arguments to the varargs element type.\n+\t\t\telse {\n+\t\t\t\tAssert.state(varArgContentType != null, \"No element type\");\n+\t\t\t\tfor (int i = varargsPosition; i < arguments.length; i++) {\n+\t\t\t\t\tObject argument = arguments[i];\n+\t\t\t\t\targuments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), varArgContentType);\n+\t\t\t\t\tconversionOccurred |= (argument != arguments[i]);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\treturn conversionOccurred;\n+\t}\n+\n \t/**\n \t * Check if the supplied value is the first entry in the array represented by the possibleArray value.\n \t * @param value the value to check for in the array\ndiff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java\nindex 7cde54692e0d..4940861a369a 100644\n--- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java\n+++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java\n@@ -16,6 +16,7 @@\n \n package org.springframework.expression.spel.support;\n \n+import java.lang.invoke.MethodHandle;\n import java.lang.reflect.Method;\n import java.util.ArrayList;\n import java.util.List;\n@@ -251,6 +252,10 @@ public void registerFunction(String name, Method method) {\n \t\tthis.variables.put(name, method);\n \t}\n \n+\tpublic void registerFunction(String name, MethodHandle methodHandle) {\n+\t\tthis.variables.put(name, methodHandle);\n+\t}\n+\n \t@Override\n \t@Nullable\n \tpublic Object lookupVariable(String name) {\ndiff --git a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java\nindex aa6bf033f52e..3fbc0af024fd 100644\n--- a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java\n+++ b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java\n@@ -188,6 +188,45 @@ public void testScenario_RegisteringJavaMethodsAsFunctionsAndCallingThem() throw\n \t\t}\n \t}\n \n+\t/**\n+\t * Scenario: looking up your own MethodHandles and calling them from the expression\n+\t */\n+\t@Test\n+\tpublic void testScenario_RegisteringJavaMethodsAsMethodHandlesAndCallingThem() throws SecurityException, NoSuchMethodException {\n+\t\ttry {\n+\t\t\t// Create a parser\n+\t\t\tSpelExpressionParser parser = new SpelExpressionParser();\n+\t\t\t//this.context is already populated with all relevant MethodHandle examples\n+\n+\t\t\tExpression expr = parser.parseRaw(\"#message('Message with %s words: <%s>', 2, 'Hello World', 'ignored')\");\n+\t\t\tObject value = expr.getValue(this.context);\n+\t\t\tassertThat(value).isEqualTo(\"Message with 2 words: \");\n+\n+\t\t\texpr = parser.parseRaw(\"#messageTemplate('bound', 2, 'Hello World', 'ignored')\");\n+\t\t\tvalue = expr.getValue(this.context);\n+\t\t\tassertThat(value).isEqualTo(\"This is a bound message with 2 words: \");\n+\n+\t\t\texpr = parser.parseRaw(\"#messageBound()\");\n+\t\t\tvalue = expr.getValue(this.context);\n+\t\t\tassertThat(value).isEqualTo(\"This is a prerecorded message with 3 words: \");\n+\n+\t\t\tExpression staticExpr = parser.parseRaw(\"#messageStatic('Message with %s words: <%s>', 2, 'Hello World', 'ignored')\");\n+\t\t\tObject staticValue = staticExpr.getValue(this.context);\n+\t\t\tassertThat(staticValue).isEqualTo(\"Message with 2 words: \");\n+\n+\t\t\tstaticExpr = parser.parseRaw(\"#messageStaticTemplate('bound', 2, 'Hello World', 'ignored')\");\n+\t\t\tstaticValue = staticExpr.getValue(this.context);\n+\t\t\tassertThat(staticValue).isEqualTo(\"This is a bound message with 2 words: \");\n+\n+\t\t\tstaticExpr = parser.parseRaw(\"#messageStaticBound()\");\n+\t\t\tstaticValue = staticExpr.getValue(this.context);\n+\t\t\tassertThat(staticValue).isEqualTo(\"This is a prerecorded message with 3 words: \");\n+\t\t}\n+\t\tcatch (EvaluationException | ParseException ex) {\n+\t\t\tthrow new AssertionError(ex.getMessage(), ex);\n+\t\t}\n+\t}\n+\n \t/**\n \t * Scenario: add a property resolver that will get called in the resolver chain, this one only supports reading.\n \t */\ndiff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java\nindex 3e9d3bc92a95..1ba488ccab0b 100644\n--- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java\n+++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java\n@@ -16,6 +16,9 @@\n \n package org.springframework.expression.spel;\n \n+import java.lang.invoke.MethodHandle;\n+import java.lang.invoke.MethodHandles;\n+import java.lang.invoke.MethodType;\n import java.util.ArrayList;\n import java.util.Arrays;\n import java.util.Date;\n@@ -415,6 +418,38 @@ void functions() throws Exception {\n \t\tassertThat(helloWorldReversed).isEqualTo(\"dlrow olleh\");\n \t}\n \n+\t@Test\n+\tvoid methodHandlesNotBound() throws Throwable {\n+\t\tExpressionParser parser = new SpelExpressionParser();\n+\t\tStandardEvaluationContext context = new StandardEvaluationContext();\n+\n+\t\tMethodHandle mh = MethodHandles.lookup().findVirtual(String.class, \"formatted\",\n+\t\t\t\tMethodType.methodType(String.class, Object[].class));\n+\t\tcontext.setVariable(\"message\", mh);\n+\n+\t\tString message = parser.parseExpression(\"#message('Simple message: <%s>', 'Hello World', 'ignored')\")\n+\t\t\t\t.getValue(context, String.class);\n+\t\tassertThat(message).isEqualTo(\"Simple message: \");\n+\t}\n+\n+\t@Test\n+\tvoid methodHandlesFullyBound() throws Throwable {\n+\t\tExpressionParser parser = new SpelExpressionParser();\n+\t\tStandardEvaluationContext context = new StandardEvaluationContext();\n+\n+\t\tString template = \"This is a %s message with %s words: <%s>\";\n+\t\tObject varargs = new Object[] { \"prerecorded\", 3, \"Oh Hello World!\", \"ignored\" };\n+\t\tMethodHandle mh = MethodHandles.lookup().findVirtual(String.class, \"formatted\",\n+\t\t\t\t\t\tMethodType.methodType(String.class, Object[].class))\n+\t\t\t\t.bindTo(template)\n+\t\t\t\t.bindTo(varargs); //here we have to provide arguments in a single array binding\n+\t\tcontext.setVariable(\"message\", mh);\n+\n+\t\tString message = parser.parseExpression(\"#message()\")\n+\t\t\t\t.getValue(context, String.class);\n+\t\tassertThat(message).isEqualTo(\"This is a prerecorded message with 3 words: \");\n+\t}\n+\n \t// 7.5.10\n \n \t@Test\ndiff --git a/spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java b/spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java\nindex ebeebcf7e0ce..2d626013f076 100644\n--- a/spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java\n+++ b/spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java\n@@ -16,6 +16,9 @@\n \n package org.springframework.expression.spel;\n \n+import java.lang.invoke.MethodHandle;\n+import java.lang.invoke.MethodHandles;\n+import java.lang.invoke.MethodType;\n import java.util.Arrays;\n import java.util.GregorianCalendar;\n \n@@ -37,6 +40,12 @@ public static StandardEvaluationContext getTestEvaluationContext() {\n \t\tsetupRootContextObject(testContext);\n \t\tpopulateVariables(testContext);\n \t\tpopulateFunctions(testContext);\n+\t\ttry {\n+\t\t\tpopulateMethodHandles(testContext);\n+\t\t}\n+\t\tcatch (NoSuchMethodException | IllegalAccessException e) {\n+\t\t\tthrow new RuntimeException(e);\n+\t\t}\n \t\treturn testContext;\n \t}\n \n@@ -62,6 +71,36 @@ private static void populateFunctions(StandardEvaluationContext testContext) {\n \t\t}\n \t}\n \n+\t/**\n+\t * Register some Java {@code MethodHandle} as well known functions that can be called from an expression.\n+\t * @param testContext the test evaluation context\n+\t */\n+\tprivate static void populateMethodHandles(StandardEvaluationContext testContext) throws NoSuchMethodException, IllegalAccessException {\n+\t\t// #message(template, args...)\n+\t\tMethodHandle message = MethodHandles.lookup().findVirtual(String.class, \"formatted\",\n+\t\t\t\tMethodType.methodType(String.class, Object[].class));\n+\t\ttestContext.registerFunction(\"message\", message);\n+\t\t// #messageTemplate(args...)\n+\t\tMethodHandle messageWithParameters = message.bindTo(\"This is a %s message with %s words: <%s>\");\n+\t\ttestContext.registerFunction(\"messageTemplate\", messageWithParameters);\n+\t\t// #messageTemplateBound()\n+\t\tMethodHandle messageBound = messageWithParameters\n+\t\t\t\t.bindTo(new Object[] { \"prerecorded\", 3, \"Oh Hello World\", \"ignored\"});\n+\t\ttestContext.registerFunction(\"messageBound\", messageBound);\n+\n+\t\t//#messageStatic(template, args...)\n+\t\tMethodHandle messageStatic = MethodHandles.lookup().findStatic(TestScenarioCreator.class,\n+\t\t\t\t\"message\", MethodType.methodType(String.class, String.class, String[].class));\n+\t\ttestContext.registerFunction(\"messageStatic\", messageStatic);\n+\t\t//#messageStaticTemplate(args...)\n+\t\tMethodHandle messageStaticPartiallyBound = messageStatic.bindTo(\"This is a %s message with %s words: <%s>\");\n+\t\ttestContext.registerFunction(\"messageStaticTemplate\", messageStaticPartiallyBound);\n+\t\t//#messageStaticBound()\n+\t\tMethodHandle messageStaticFullyBound = messageStaticPartiallyBound\n+\t\t\t\t.bindTo(new String[] { \"prerecorded\", \"3\", \"Oh Hello World\", \"ignored\"});\n+\t\ttestContext.registerFunction(\"messageStaticBound\", messageStaticFullyBound);\n+\t}\n+\n \t/**\n \t * Register some variables that can be referenced from the tests\n \t * @param testContext the test evaluation context\n@@ -117,4 +156,8 @@ public static String varargsFunction2(int i, String... strings) {\n \t\treturn String.valueOf(i) + \"-\" + Arrays.toString(strings);\n \t}\n \n+\tpublic static String message(String template, String... args) {\n+\t\treturn template.formatted((Object[]) args);\n+\t}\n+\n }\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 30020, "url": "https://github.com/spring-projects/spring-framework/pull/30020", "commits": [{"commit_sha": "f269a80ef76dcddb1529345b221e9a35ced68e92", "labeled_review_comments": [], "total_score": 0.33191489361702126, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle\nindex 70263f972a6c..98bcdee87db3 100644\n--- a/spring-test/spring-test.gradle\n+++ b/spring-test/spring-test.gradle\n@@ -76,6 +76,7 @@ dependencies {\n \t}\n \ttestImplementation(\"io.projectreactor.netty:reactor-netty-http\")\n \ttestImplementation(\"de.bechte.junit:junit-hierarchicalcontextrunner\")\n+\ttestImplementation(\"org.awaitility:awaitility\")\n \ttestRuntimeOnly(\"org.junit.vintage:junit-vintage-engine\") {\n \t\texclude group: \"junit\", module: \"junit\"\n \t}\ndiff --git a/spring-test/src/main/java/org/springframework/test/context/event/ApplicationEventsHolder.java b/spring-test/src/main/java/org/springframework/test/context/event/ApplicationEventsHolder.java\nindex ad8276acae96..91c4a9a8b217 100644\n--- a/spring-test/src/main/java/org/springframework/test/context/event/ApplicationEventsHolder.java\n+++ b/spring-test/src/main/java/org/springframework/test/context/event/ApplicationEventsHolder.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2021 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -37,6 +37,7 @@\n *\n * @author Sam Brannen\n * @author Oliver Drotbohm\n+ * @author Simon Basl\u00e9\n * @since 5.3.3\n * @see ApplicationEvents\n * @see RecordApplicationEvents\n@@ -44,7 +45,7 @@\n */\n public abstract class ApplicationEventsHolder {\n \n-\tprivate static final ThreadLocal applicationEvents = new ThreadLocal<>();\n+\tprivate static final ThreadLocal applicationEvents = new InheritableThreadLocal<>();\n \n \n \tprivate ApplicationEventsHolder() {\ndiff --git a/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java b/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java\nindex b7638ba2d551..ecce47266c52 100644\n--- a/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java\n+++ b/spring-test/src/main/java/org/springframework/test/context/event/DefaultApplicationEvents.java\n@@ -16,8 +16,8 @@\n \n package org.springframework.test.context.event;\n \n-import java.util.ArrayList;\n import java.util.List;\n+import java.util.concurrent.CopyOnWriteArrayList;\n import java.util.stream.Stream;\n \n import org.springframework.context.ApplicationEvent;\n@@ -32,7 +32,7 @@\n */\n class DefaultApplicationEvents implements ApplicationEvents {\n \n-\tprivate final List events = new ArrayList<>();\n+\tprivate final List events = new CopyOnWriteArrayList<>();\n \n \n \tvoid addEvent(ApplicationEvent event) {\ndiff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java\nindex f9ba801e8241..aebf7280ec5d 100644\n--- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java\n+++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2022 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -29,6 +29,7 @@\n import org.junit.jupiter.api.AfterEach;\n import org.junit.jupiter.api.BeforeAll;\n import org.junit.jupiter.api.BeforeEach;\n+import org.junit.jupiter.api.TestInstance;\n import org.junit.jupiter.api.extension.AfterAllCallback;\n import org.junit.jupiter.api.extension.AfterEachCallback;\n import org.junit.jupiter.api.extension.AfterTestExecutionCallback;\n@@ -41,6 +42,8 @@\n import org.junit.jupiter.api.extension.ParameterContext;\n import org.junit.jupiter.api.extension.ParameterResolver;\n import org.junit.jupiter.api.extension.TestInstancePostProcessor;\n+import org.junit.jupiter.api.parallel.Execution;\n+import org.junit.jupiter.api.parallel.ExecutionMode;\n import org.junit.platform.commons.annotation.Testable;\n \n import org.springframework.beans.factory.annotation.Autowired;\n@@ -51,8 +54,10 @@\n import org.springframework.core.annotation.RepeatableContainers;\n import org.springframework.lang.Nullable;\n import org.springframework.test.context.TestConstructor;\n+import org.springframework.test.context.TestContextAnnotationUtils;\n import org.springframework.test.context.TestContextManager;\n import org.springframework.test.context.event.ApplicationEvents;\n+import org.springframework.test.context.event.RecordApplicationEvents;\n import org.springframework.test.context.support.PropertyProvider;\n import org.springframework.test.context.support.TestConstructorUtils;\n import org.springframework.util.Assert;\n@@ -68,6 +73,7 @@\n * {@code @SpringJUnitWebConfig}.\n *\n * @author Sam Brannen\n+ * @author Simon Basl\u00e9\n * @since 5.0\n * @see org.springframework.test.context.junit.jupiter.EnabledIf\n * @see org.springframework.test.context.junit.jupiter.DisabledIf\n@@ -94,6 +100,13 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes\n \n \tprivate static final String NO_AUTOWIRED_VIOLATIONS_DETECTED = \"NO AUTOWIRED VIOLATIONS DETECTED\";\n \n+\t/**\n+\t * {@link Namespace} in which {@code @RecordApplicationEvents} validation error messages\n+\t * are stored, keyed by test class.\n+\t */\n+\tprivate static final Namespace RECORD_APPLICATION_EVENTS_VALIDATION_NAMESPACE =\n+\t\t\tNamespace.create(SpringExtension.class.getName() + \"#recordApplicationEvents.validation\");\n+\n \t// Note that @Test, @TestFactory, @TestTemplate, @RepeatedTest, and @ParameterizedTest\n \t// are all meta-annotated with @Testable.\n \tprivate static final List> JUPITER_ANNOTATION_TYPES =\n@@ -135,9 +148,51 @@ public void afterAll(ExtensionContext context) throws Exception {\n \t@Override\n \tpublic void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {\n \t\tvalidateAutowiredConfig(context);\n+\t\tvalidateRecordApplicationEventsConfig(context);\n \t\tgetTestContextManager(context).prepareTestInstance(testInstance);\n \t}\n \n+\t/**\n+\t * Validate that test class or its enclosing class doesn't attempt to record\n+\t * application events in a parallel mode that makes it un-deterministic\n+\t * ({@code @TestInstance(PER_CLASS)} and {@code @Execution(CONCURRENT)}\n+\t * combination).\n+\t * @since 6.1.0\n+\t */\n+\tprivate void validateRecordApplicationEventsConfig(ExtensionContext context) {\n+\t\t// We save the result in the ExtensionContext.Store so that we don't\n+\t\t// re-validate all methods for the same test class multiple times.\n+\t\tStore store = context.getStore(RECORD_APPLICATION_EVENTS_VALIDATION_NAMESPACE);\n+\n+\t\tString errorMessage = store.getOrComputeIfAbsent(context.getRequiredTestClass(), testClass -> {\n+\t\t\tboolean record = TestContextAnnotationUtils.hasAnnotation(testClass, RecordApplicationEvents.class);\n+\t\t\tif (!record) {\n+\t\t\t\treturn NO_AUTOWIRED_VIOLATIONS_DETECTED;\n+\t\t\t}\n+\t\t\tfinal TestInstance testInstance = TestContextAnnotationUtils.findMergedAnnotation(testClass, TestInstance.class);\n+\n+\t\t\tif (testInstance == null || testInstance.value() != TestInstance.Lifecycle.PER_CLASS) {\n+\t\t\t\treturn NO_AUTOWIRED_VIOLATIONS_DETECTED;\n+\t\t\t}\n+\n+\t\t\tfinal Execution execution = TestContextAnnotationUtils.findMergedAnnotation(testClass, Execution.class);\n+\n+\t\t\tif (execution == null || execution.value() != ExecutionMode.CONCURRENT) {\n+\t\t\t\treturn NO_AUTOWIRED_VIOLATIONS_DETECTED;\n+\t\t\t}\n+\n+\t\t\treturn \"Test classes or inner classes that @RecordApplicationEvents must not be run in parallel \"\n+\t\t\t\t\t+ \"with the @TestInstance(Lifecycle.PER_CLASS) configuration. Use either @Execution(SAME_THREAD), \"\n+\t\t\t\t\t+ \"@TestInstance(PER_METHOD) or disable parallel execution altogether. Note that when recording \"\n+\t\t\t\t\t+ \"events in parallel, one might see events published by other tests as the application context \"\n+\t\t\t\t\t+ \"can be common.\";\n+\t\t}, String.class);\n+\n+\t\tif (errorMessage != NO_AUTOWIRED_VIOLATIONS_DETECTED) {\n+\t\t\tthrow new IllegalStateException(errorMessage);\n+\t\t}\n+\t}\n+\n \t/**\n \t * Validate that test methods and test lifecycle methods in the supplied\n \t * test class are not annotated with {@link Autowired @Autowired}.\ndiff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/JUnitJupiterApplicationEventsIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/JUnitJupiterApplicationEventsIntegrationTests.java\nindex 5e5ee6921ce5..468fb6c7438b 100644\n--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/JUnitJupiterApplicationEventsIntegrationTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/JUnitJupiterApplicationEventsIntegrationTests.java\n@@ -18,6 +18,9 @@\n \n import java.util.stream.Stream;\n \n+import org.assertj.core.api.InstanceOfAssertFactories;\n+import org.awaitility.Awaitility;\n+import org.awaitility.Durations;\n import org.junit.jupiter.api.AfterEach;\n import org.junit.jupiter.api.BeforeEach;\n import org.junit.jupiter.api.Nested;\n@@ -237,6 +240,38 @@ void afterEach(@Autowired ApplicationEvents events, TestInfo testInfo) {\n \t\t}\n \t}\n \n+\t@Nested\n+\t@TestInstance(PER_CLASS)\n+\tclass AsyncEventTests {\n+\n+\t\t@Autowired\n+\t\tApplicationEvents applicationEvents;\n+\n+\t\t@Test\n+\t\tvoid asyncPublication() throws InterruptedException {\n+\t\t\tThread t = new Thread(() -> context.publishEvent(new CustomEvent(\"async\")));\n+\t\t\tt.start();\n+\t\t\tt.join();\n+\n+\t\t\tassertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t\t.singleElement()\n+\t\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t\t.isEqualTo(\"async\");\n+\t\t}\n+\n+\t\t@Test\n+\t\tvoid asyncConsumption() {\n+\t\t\tcontext.publishEvent(new CustomEvent(\"sync\"));\n+\n+\t\t\tAwaitility.await().atMost(Durations.ONE_SECOND)\n+\t\t\t\t\t.untilAsserted(() -> assertThat(assertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t\t\t\t.singleElement()\n+\t\t\t\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t\t\t\t.isEqualTo(\"sync\")));\n+\t\t}\n+\n+\t}\n+\n \n \tprivate static void assertEventTypes(ApplicationEvents applicationEvents, String... types) {\n \t\tassertThat(applicationEvents.stream().map(event -> event.getClass().getSimpleName()))\ndiff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/ParallelApplicationEventsIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/ParallelApplicationEventsIntegrationTests.java\nindex bf12679653f8..fd1a27973d93 100644\n--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/ParallelApplicationEventsIntegrationTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/event/ParallelApplicationEventsIntegrationTests.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2021 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -18,9 +18,15 @@\n \n import java.util.Set;\n import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ExecutorService;\n+import java.util.concurrent.Executors;\n+import java.util.concurrent.TimeUnit;\n import java.util.stream.Collectors;\n import java.util.stream.Stream;\n \n+import org.assertj.core.api.InstanceOfAssertFactories;\n+import org.awaitility.Awaitility;\n+import org.awaitility.Durations;\n import org.junit.jupiter.api.AfterEach;\n import org.junit.jupiter.api.Test;\n import org.junit.jupiter.api.TestInfo;\n@@ -28,15 +34,19 @@\n import org.junit.jupiter.api.TestInstance.Lifecycle;\n import org.junit.jupiter.api.parallel.Execution;\n import org.junit.jupiter.api.parallel.ExecutionMode;\n-import org.junit.jupiter.params.ParameterizedTest;\n-import org.junit.jupiter.params.provider.ValueSource;\n+import org.junit.platform.engine.TestExecutionResult;\n+import org.junit.platform.testkit.engine.EngineExecutionResults;\n import org.junit.platform.testkit.engine.EngineTestKit;\n+import org.junit.platform.testkit.engine.Events;\n \n import org.springframework.beans.factory.annotation.Autowired;\n import org.springframework.context.ApplicationContext;\n+import org.springframework.context.PayloadApplicationEvent;\n import org.springframework.context.annotation.Configuration;\n import org.springframework.test.context.event.ApplicationEvents;\n+import org.springframework.test.context.event.ApplicationEventsHolder;\n import org.springframework.test.context.event.RecordApplicationEvents;\n+import org.springframework.test.context.event.TestContextEvent;\n import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;\n \n import static org.assertj.core.api.Assertions.assertThat;\n@@ -47,23 +57,52 @@\n * in conjunction with JUnit Jupiter.\n *\n * @author Sam Brannen\n+ * @author Simon Basl\u00e9\n * @since 5.3.3\n */\n class ParallelApplicationEventsIntegrationTests {\n \n \tprivate static final Set payloads = ConcurrentHashMap.newKeySet();\n \n+\t@Test\n+\tvoid rejectTestsInParallelWithInstancePerClassAndRecordApplicationEvents() {\n+\t\tClass testClass = TestInstancePerClassTestCase.class;\n \n-\t@ParameterizedTest\n-\t@ValueSource(classes = {TestInstancePerMethodTestCase.class, TestInstancePerClassTestCase.class})\n-\tvoid executeTestsInParallel(Class testClass) {\n-\t\tEngineTestKit.engine(\"junit-jupiter\")//\n+\t\tfinal EngineExecutionResults results = EngineTestKit.engine(\"junit-jupiter\")//\n+\t\t\t\t.selectors(selectClass(testClass))//\n+\t\t\t\t.configurationParameter(\"junit.jupiter.execution.parallel.enabled\", \"true\")//\n+\t\t\t\t.configurationParameter(\"junit.jupiter.execution.parallel.config.dynamic.factor\", \"10\")//\n+\t\t\t\t.execute();\n+\n+\t\t//extract the messages from failed TextExecutionResults\n+\t\tassertThat(results.containerEvents().failed()//\n+\t\t\t\t.stream().map(e -> e.getRequiredPayload(TestExecutionResult.class)//\n+\t\t\t\t.getThrowable().get().getMessage()))//\n+\t\t\t\t.singleElement(InstanceOfAssertFactories.STRING)\n+\t\t\t\t.isEqualToIgnoringNewLines(\"\"\"\n+\t\tTest classes or inner classes that @RecordApplicationEvents\\s\n+\t\tmust not be run in parallel with the @TestInstance(Lifecycle.PER_CLASS) configuration.\\s\n+\t\tUse either @Execution(SAME_THREAD), @TestInstance(PER_METHOD) or disable parallel\\s\n+\t\texecution altogether. Note that when recording events in parallel, one might see events\\s\n+\t\tpublished by other tests as the application context can be common.\n+\t\t\"\"\");\n+\t}\n+\n+\t@Test\n+\tvoid executeTestsInParallelInstancePerMethod() {\n+\t\tClass testClass = TestInstancePerMethodTestCase.class;\n+\t\tEvents testEvents = EngineTestKit.engine(\"junit-jupiter\")//\n \t\t\t\t.selectors(selectClass(testClass))//\n \t\t\t\t.configurationParameter(\"junit.jupiter.execution.parallel.enabled\", \"true\")//\n \t\t\t\t.configurationParameter(\"junit.jupiter.execution.parallel.config.dynamic.factor\", \"10\")//\n \t\t\t\t.execute()//\n-\t\t\t\t.testEvents()//\n-\t\t\t\t.assertStatistics(stats -> stats.started(10).succeeded(10).failed(0));\n+\t\t\t\t.testEvents();\n+\t\t//list failed events in case of test errors to get a sense of which tests failed\n+\t\tEvents failedTests = testEvents.failed();\n+\t\tif (failedTests.count() > 0) {\n+\t\t\tfailedTests.debug();\n+\t\t}\n+\t\ttestEvents.assertStatistics(stats -> stats.started(13).succeeded(13).failed(0));\n \n \t\tSet testNames = payloads.stream()//\n \t\t\t\t.map(payload -> payload.substring(0, payload.indexOf(\"-\")))//\n@@ -162,6 +201,39 @@ void test10(ApplicationEvents events, TestInfo testInfo) {\n \t\t\tassertTestExpectations(events, testInfo);\n \t\t}\n \n+\t\t@Test\n+\t\tvoid compareToApplicationEventsHolder(ApplicationEvents applicationEvents) {\n+\t\t\tApplicationEvents fromThreadHolder = ApplicationEventsHolder.getRequiredApplicationEvents();\n+\t\t\tassertThat(fromThreadHolder.stream())\n+\t\t\t\t\t.hasSameElementsAs(this.events.stream().toList())\n+\t\t\t\t\t.hasSameElementsAs(applicationEvents.stream().toList());\n+\t\t}\n+\n+\t\t@Test\n+\t\tvoid asyncPublication(ApplicationEvents events) throws InterruptedException {\n+\t\t\tfinal ExecutorService executorService = Executors.newSingleThreadExecutor();\n+\t\t\texecutorService.execute(() -> this.context.publishEvent(\"asyncPublication\"));\n+\t\t\texecutorService.shutdown();\n+\t\t\texecutorService.awaitTermination(10, TimeUnit.SECONDS);\n+\n+\t\t\tassertThat(events.stream().filter(e -> !(e instanceof TestContextEvent))\n+\t\t\t\t\t.map(e -> (e instanceof PayloadApplicationEvent pae ? pae.getPayload().toString() : e.toString())))\n+\t\t\t\t\t.containsExactly(\"asyncPublication\");\n+\t\t}\n+\n+\t\t@Test\n+\t\tvoid asyncConsumption() {\n+\t\t\tthis.context.publishEvent(\"asyncConsumption\");\n+\n+\t\t\tAwaitility.await().atMost(Durations.ONE_SECOND).untilAsserted(() ->//\n+\t\t\t\t\tassertThat(ApplicationEventsHolder//\n+\t\t\t\t\t\t\t.getRequiredApplicationEvents()//\n+\t\t\t\t\t\t\t.stream()//\n+\t\t\t\t\t\t\t.filter(e -> !(e instanceof TestContextEvent))//\n+\t\t\t\t\t\t\t.map(e -> (e instanceof PayloadApplicationEvent pae ? pae.getPayload().toString() : e.toString()))//\n+\t\t\t\t\t).containsExactly(\"asyncConsumption\"));\n+\t\t}\n+\n \t\tprivate void assertTestExpectations(ApplicationEvents events, TestInfo testInfo) {\n \t\t\tString testName = testInfo.getTestMethod().get().getName();\n \t\t\tString threadName = Thread.currentThread().getName();\ndiff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/event/JUnit4ApplicationEventsAsyncIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/event/JUnit4ApplicationEventsAsyncIntegrationTests.java\nnew file mode 100644\nindex 000000000000..1fc656416701\n--- /dev/null\n+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/event/JUnit4ApplicationEventsAsyncIntegrationTests.java\n@@ -0,0 +1,84 @@\n+/*\n+ * Copyright 2002-2023 the original author or authors.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * https://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.springframework.test.context.junit4.event;\n+\n+import org.assertj.core.api.InstanceOfAssertFactories;\n+import org.awaitility.Awaitility;\n+import org.awaitility.Durations;\n+import org.junit.Rule;\n+import org.junit.Test;\n+import org.junit.rules.TestName;\n+import org.junit.runner.RunWith;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationContext;\n+import org.springframework.context.annotation.Configuration;\n+import org.springframework.test.context.event.ApplicationEvents;\n+import org.springframework.test.context.event.RecordApplicationEvents;\n+import org.springframework.test.context.junit4.SpringRunner;\n+import org.springframework.test.context.junit4.event.JUnit4ApplicationEventsIntegrationTests.CustomEvent;\n+\n+import static org.assertj.core.api.Assertions.assertThat;\n+\n+/**\n+ * Integration tests for {@link ApplicationEvents} that record async events\n+ * or assert the events from a separate thread, in conjunction with JUnit 4.\n+ *\n+ * @author Simon Basl\u00e9\n+ * @since 6.1.0\n+ */\n+@RunWith(SpringRunner.class)\n+@RecordApplicationEvents\n+public class JUnit4ApplicationEventsAsyncIntegrationTests {\n+\n+\t@Rule\n+\tpublic final TestName testName = new TestName();\n+\n+\t@Autowired\n+\tApplicationContext context;\n+\n+\t@Autowired\n+\tApplicationEvents applicationEvents;\n+\n+\t@Test\n+\tpublic void asyncPublication() throws InterruptedException {\n+\t\tThread t = new Thread(() -> context.publishEvent(new CustomEvent(\"async\")));\n+\t\tt.start();\n+\t\tt.join();\n+\n+\t\tassertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t.singleElement()\n+\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t.isEqualTo(\"async\");\n+\t}\n+\n+\t@Test\n+\tpublic void asyncConsumption() {\n+\t\tcontext.publishEvent(new CustomEvent(\"sync\"));\n+\n+\t\tAwaitility.await().atMost(Durations.ONE_SECOND)\n+\t\t\t\t.untilAsserted(() -> assertThat(assertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t\t\t.singleElement()\n+\t\t\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t\t\t.isEqualTo(\"sync\")));\n+\t}\n+\n+\n+\t@Configuration\n+\tstatic class Config {\n+\t}\n+}\ndiff --git a/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsAsyncIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsAsyncIntegrationTests.java\nnew file mode 100644\nindex 000000000000..67a75c3229df\n--- /dev/null\n+++ b/spring-test/src/test/java/org/springframework/test/context/testng/event/TestNGApplicationEventsAsyncIntegrationTests.java\n@@ -0,0 +1,77 @@\n+/*\n+ * Copyright 2002-2023 the original author or authors.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * https://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.springframework.test.context.testng.event;\n+\n+import org.assertj.core.api.InstanceOfAssertFactories;\n+import org.awaitility.Awaitility;\n+import org.awaitility.Durations;\n+import org.testng.annotations.Test;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationContext;\n+import org.springframework.context.annotation.Configuration;\n+import org.springframework.test.context.event.ApplicationEvents;\n+import org.springframework.test.context.event.RecordApplicationEvents;\n+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;\n+import org.springframework.test.context.testng.event.TestNGApplicationEventsIntegrationTests.CustomEvent;\n+\n+import static org.assertj.core.api.Assertions.assertThat;\n+\n+/**\n+ * Integration tests for {@link ApplicationEvents} that record async events\n+ * or assert the events from a separate thread, in conjunction with TestNG.\n+ *\n+ * @author Simon Basl\u00e9\n+ * @since 6.1.0\n+ */\n+@RecordApplicationEvents\n+class TestNGApplicationEventsAsyncIntegrationTests extends AbstractTestNGSpringContextTests {\n+\n+\t@Autowired\n+\tApplicationContext context;\n+\n+\t@Autowired\n+\tApplicationEvents applicationEvents;\n+\n+\n+\t@Test\n+\tpublic void asyncPublication() throws InterruptedException {\n+\t\tThread t = new Thread(() -> context.publishEvent(new CustomEvent(\"asyncPublication\")));\n+\t\tt.start();\n+\t\tt.join();\n+\n+\t\tassertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t.singleElement()\n+\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t.isEqualTo(\"asyncPublication\");\n+\t}\n+\n+\t@Test\n+\tpublic void asyncConsumption() {\n+\t\tcontext.publishEvent(new CustomEvent(\"asyncConsumption\"));\n+\n+\t\tAwaitility.await().atMost(Durations.ONE_SECOND)\n+\t\t\t\t.untilAsserted(() -> assertThat(assertThat(this.applicationEvents.stream(CustomEvent.class))\n+\t\t\t\t\t\t.singleElement()\n+\t\t\t\t\t\t.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING)\n+\t\t\t\t\t\t.isEqualTo(\"asyncConsumption\")));\n+\t}\n+\n+\n+\t@Configuration\n+\tstatic class Config { }\n+}\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 29953, "url": "https://github.com/spring-projects/spring-framework/pull/29953", "commits": [{"commit_sha": "d9a60b9386861010408762b03fcb3c3059ebeb2e", "labeled_review_comments": [], "total_score": 0.45957446808510644, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\nindex ff3f6c27a7df..f995ebed8ccf 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2020 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -23,6 +23,7 @@\n import javax.xml.xpath.XPathExpressionException;\n \n import org.hamcrest.Matcher;\n+import org.hamcrest.Matchers;\n \n import org.springframework.http.HttpMethod;\n import org.springframework.http.client.ClientHttpRequest;\n@@ -114,6 +115,11 @@ public static RequestMatcher requestTo(URI uri) {\n \n \t/**\n \t * Assert request query parameter values with the given Hamcrest matcher(s).\n+\t *

Note that if the queryParam value list is larger than the number of provided\n+\t * {@code matchers}, extra values are considered acceptable.\n+\t * See {@link #queryParam(String, Matcher)} for a variant that takes a {@code Matcher} over\n+\t * the whole list of values.\n+\t * @see #queryParam(String, Matcher)\n \t */\n \t@SafeVarargs\n \tpublic static RequestMatcher queryParam(String name, Matcher... matchers) {\n@@ -128,6 +134,11 @@ public static RequestMatcher queryParam(String name, Matcher...\n \n \t/**\n \t * Assert request query parameter values.\n+\t *

Note that if the queryParam value list is larger than {@code expectedValues},\n+\t * extra values are considered acceptable.\n+\t * See {@link #queryParam(String, Matcher)} for a variant that takes a {@code Matcher} over\n+\t * the whole list of values.\n+\t * @see #queryParam(String, Matcher)\n \t */\n \tpublic static RequestMatcher queryParam(String name, String... expectedValues) {\n \t\treturn request -> {\n@@ -139,6 +150,28 @@ public static RequestMatcher queryParam(String name, String... expectedValues) {\n \t\t};\n \t}\n \n+\t/**\n+\t * Assert request query parameter, matching on the whole {@code List} of values.\n+\t *

This can be used to check that the list has at least one value matching a criteria ({@link Matchers#hasItem(Matcher)}),\n+\t * or that every value in the list matches a common criteria ({@link Matchers#everyItem(Matcher)}),\n+\t * or that each value in the list matches its corresponding dedicated criteria ({@link Matchers#contains(Matcher[])},\n+\t * and more.\n+\t * @param name the name of the queryParam to consider\n+\t * @param matcher the matcher to apply to the whole list of values for that header\n+\t * @since 6.0.5\n+\t */\n+\tpublic static RequestMatcher queryParam(String name, Matcher> matcher) {\n+\t\treturn request -> {\n+\t\t\tMultiValueMap params = getQueryParams(request);\n+\t\t\tList paramValues = params.get(name);\n+\t\t\tif (paramValues == null) {\n+\t\t\t\tfail(\"No queryParam [\" + name + \"]\");\n+\t\t\t}\n+\t\t\tassertThat(\"Request queryParam values for [\" + name + \"]\", paramValues, matcher);\n+\t\t};\n+\t}\n+\n+\n \tprivate static MultiValueMap getQueryParams(ClientHttpRequest request) {\n \t\treturn UriComponentsBuilder.fromUri(request.getURI()).build().getQueryParams();\n \t}\n@@ -158,6 +191,11 @@ private static void assertValueCount(\n \n \t/**\n \t * Assert request header values with the given Hamcrest matcher(s).\n+\t *

Note that if the header's value list is larger than the number of provided\n+\t * {@code matchers}, extra values are considered acceptable.\n+\t * See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher} over\n+\t * the whole list of values.\n+\t * @see #header(String, Matcher)\n \t */\n \t@SafeVarargs\n \tpublic static RequestMatcher header(String name, Matcher... matchers) {\n@@ -173,6 +211,11 @@ public static RequestMatcher header(String name, Matcher... matc\n \n \t/**\n \t * Assert request header values.\n+\t *

Note that if the header's value list is larger than {@code expectedValues},\n+\t * extra values are considered acceptable.\n+\t * See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher} over\n+\t * the whole list of values.\n+\t * @see #header(String, Matcher)\n \t */\n \tpublic static RequestMatcher header(String name, String... expectedValues) {\n \t\treturn request -> {\n@@ -185,6 +228,26 @@ public static RequestMatcher header(String name, String... expectedValues) {\n \t\t};\n \t}\n \n+\t/**\n+\t * Assert request header, matching on the whole {@code List} of values.\n+\t *

This can be used to check that the list has at least one value matching a criteria ({@link Matchers#hasItem(Matcher)}),\n+\t * or that every value in the list matches a common criteria ({@link Matchers#everyItem(Matcher)}),\n+\t * or that each value in the list matches its corresponding dedicated criteria ({@link Matchers#contains(Matcher[])},\n+\t * and more.\n+\t * @param name the name of the header to consider\n+\t * @param matcher the matcher to apply to the whole list of values for that header\n+\t * @since 6.0.5\n+\t */\n+\tpublic static RequestMatcher header(String name, Matcher> matcher) {\n+\t\treturn request -> {\n+\t\t\tList headerValues = request.getHeaders().get(name);\n+\t\t\tif (headerValues == null) {\n+\t\t\t\tfail(\"No header values for header [\" + name + \"]\");\n+\t\t\t}\n+\t\t\tassertThat(\"Request header values for [\" + name + \"]\", headerValues, matcher);\n+\t\t};\n+\t}\n+\n \t/**\n \t * Assert that the given request header does not exist.\n \t * @since 5.2\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\nindex 562324593966..1e7dc6b26278 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2022 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -16,18 +16,35 @@\n \n package org.springframework.test.web.client.match;\n \n+import java.io.IOException;\n import java.net.URI;\n import java.util.Arrays;\n import java.util.Collections;\n import java.util.List;\n \n+import org.hamcrest.CoreMatchers;\n+import org.hamcrest.Matchers;\n import org.junit.jupiter.api.Test;\n \n import org.springframework.http.HttpMethod;\n import org.springframework.mock.http.client.MockClientHttpRequest;\n \n+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.assertj.core.api.Assertions.assertThatThrownBy;\n+import static org.hamcrest.Matchers.allOf;\n+import static org.hamcrest.Matchers.any;\n+import static org.hamcrest.Matchers.anything;\n+import static org.hamcrest.Matchers.contains;\n+import static org.hamcrest.Matchers.containsInAnyOrder;\n import static org.hamcrest.Matchers.containsString;\n+import static org.hamcrest.Matchers.endsWith;\n+import static org.hamcrest.Matchers.everyItem;\n+import static org.hamcrest.Matchers.hasItem;\n+import static org.hamcrest.Matchers.hasSize;\n+import static org.hamcrest.Matchers.is;\n+import static org.hamcrest.Matchers.notNullValue;\n+import static org.hamcrest.Matchers.nullValue;\n+import static org.hamcrest.Matchers.startsWith;\n \n /**\n * Unit tests for {@link MockRestRequestMatchers}.\n@@ -146,6 +163,63 @@ void headerContainsWithMissingValue() {\n \t\t\t.hasMessageContaining(\"was \\\"bar\\\"\");\n \t}\n \n+\t@Test\n+\tvoid headerListMissing() {\n+\t\tassertThatThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t\t.isInstanceOf(AssertionError.class)\n+\t\t\t\t.hasMessage(\"No header values for header [foo]\");\n+\t}\n+\n+\t@Test\n+\tvoid headerListMatchers() throws IOException {\n+\t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n+\n+\t\tMockRestRequestMatchers.header(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), Matchers.anything())).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\t//these can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n+\t\tMockRestRequestMatchers.header(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\t//these are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n+\t\t//string-oriented or obviously a vararg of matchers\n+\t\t//list matcher version\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n+\t\t//vararg version\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is((any(String.class)))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", CoreMatchers.either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t}\n+\n+\t@Test\n+\tvoid headerListContainsMismatch() {\n+\t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: iterable containing [a string containing \\\"ba\\\"]\\n\"\n+\t\t\t\t\t\t+ \" but: not matched: \\\"baz\\\"\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: a collection containing a string ending with \\\"ba\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: every item is a string ending with \\\"ar\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: an item was \\\"baz\\\"\");\n+\t}\n+\n \t@Test\n \tvoid headers() throws Exception {\n \t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n@@ -210,4 +284,62 @@ void queryParamContainsWithMissingValue() {\n \t\t\t.hasMessageContaining(\"was \\\"bar\\\"\");\n \t}\n \n+\n+\t@Test\n+\tvoid queryParamListMissing() {\n+\t\tassertThatThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t\t.isInstanceOf(AssertionError.class)\n+\t\t\t\t.hasMessage(\"No queryParam [foo]\");\n+\t}\n+\n+\t@Test\n+\tvoid queryParamListMatchers() throws IOException {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), Matchers.anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\t//these can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\t//these are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n+\t\t//string-oriented or obviously a vararg of matchers\n+\t\t//list matcher version\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n+\t\t//vararg version\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is((any(String.class)))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", CoreMatchers.either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t}\n+\n+\t@Test\n+\tvoid queryParamListContainsMismatch() {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: iterable containing [a string containing \\\"ba\\\"]\\n\"\n+\t\t\t\t\t\t+ \" but: not matched: \\\"baz\\\"\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: a collection containing a string ending with \\\"ba\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: every item is a string ending with \\\"ar\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: an item was \\\"baz\\\"\");\n+\t}\n+\n }\n"}, {"commit_sha": "c662b31ec1e615e91b30a25bdf061c625deef29c", "labeled_review_comments": [], "total_score": 0.26382978723404255, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\nindex ff3f6c27a7df..170116054410 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2020 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -23,6 +23,7 @@\n import javax.xml.xpath.XPathExpressionException;\n \n import org.hamcrest.Matcher;\n+import org.hamcrest.Matchers;\n \n import org.springframework.http.HttpMethod;\n import org.springframework.http.client.ClientHttpRequest;\n@@ -114,6 +115,11 @@ public static RequestMatcher requestTo(URI uri) {\n \n \t/**\n \t * Assert request query parameter values with the given Hamcrest matcher(s).\n+\t *

Note that if the queryParam value list is larger than the number of provided\n+\t * {@code matchers}, extra values are considered acceptable.\n+\t * See {@link #queryParam(String, Matcher)} for a variant that takes a\n+\t * {@code Matcher} over the whole list of values.\n+\t * @see #queryParam(String, Matcher)\n \t */\n \t@SafeVarargs\n \tpublic static RequestMatcher queryParam(String name, Matcher... matchers) {\n@@ -128,6 +134,11 @@ public static RequestMatcher queryParam(String name, Matcher...\n \n \t/**\n \t * Assert request query parameter values.\n+\t *

Note that if the queryParam value list is larger than {@code expectedValues},\n+\t * extra values are considered acceptable.\n+\t * See {@link #queryParam(String, Matcher)} for a variant that takes a\n+\t * {@code Matcher} over the whole list of values.\n+\t * @see #queryParam(String, Matcher)\n \t */\n \tpublic static RequestMatcher queryParam(String name, String... expectedValues) {\n \t\treturn request -> {\n@@ -139,6 +150,29 @@ public static RequestMatcher queryParam(String name, String... expectedValues) {\n \t\t};\n \t}\n \n+\t/**\n+\t * Assert request query parameter, matching on the whole {@code List} of values.\n+\t *

This can be used to check that the list has at least one value matching a\n+\t * criteria ({@link Matchers#hasItem(Matcher)}), or that every value in the list\n+\t * matches a common criteria ({@link Matchers#everyItem(Matcher)}), or that each\n+\t * value in the list matches its corresponding dedicated criteria\n+\t * ({@link Matchers#contains(Matcher[])}, and more.\n+\t * @param name the name of the queryParam to consider\n+\t * @param matcher the matcher to apply to the whole list of values for that header\n+\t * @since 6.0.5\n+\t */\n+\tpublic static RequestMatcher queryParam(String name, Matcher> matcher) {\n+\t\treturn request -> {\n+\t\t\tMultiValueMap params = getQueryParams(request);\n+\t\t\tList paramValues = params.get(name);\n+\t\t\tif (paramValues == null) {\n+\t\t\t\tfail(\"No queryParam [\" + name + \"]\");\n+\t\t\t}\n+\t\t\tassertThat(\"Request queryParam values for [\" + name + \"]\", paramValues, matcher);\n+\t\t};\n+\t}\n+\n+\n \tprivate static MultiValueMap getQueryParams(ClientHttpRequest request) {\n \t\treturn UriComponentsBuilder.fromUri(request.getURI()).build().getQueryParams();\n \t}\n@@ -158,6 +192,11 @@ private static void assertValueCount(\n \n \t/**\n \t * Assert request header values with the given Hamcrest matcher(s).\n+\t *

Note that if the header's value list is larger than the number of provided\n+\t * {@code matchers}, extra values are considered acceptable.\n+\t * See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher}\n+\t * over the whole list of values.\n+\t * @see #header(String, Matcher)\n \t */\n \t@SafeVarargs\n \tpublic static RequestMatcher header(String name, Matcher... matchers) {\n@@ -173,6 +212,11 @@ public static RequestMatcher header(String name, Matcher... matc\n \n \t/**\n \t * Assert request header values.\n+\t *

Note that if the header's value list is larger than {@code expectedValues},\n+\t * extra values are considered acceptable.\n+\t * See {@link #header(String, Matcher)} for a variant that takes a {@code Matcher}\n+\t * over the whole list of values.\n+\t * @see #header(String, Matcher)\n \t */\n \tpublic static RequestMatcher header(String name, String... expectedValues) {\n \t\treturn request -> {\n@@ -185,6 +229,27 @@ public static RequestMatcher header(String name, String... expectedValues) {\n \t\t};\n \t}\n \n+\t/**\n+\t * Assert request header, matching on the whole {@code List} of values.\n+\t *

This can be used to check that the list has at least one value matching a\n+\t * criteria ({@link Matchers#hasItem(Matcher)}), or that every value in the list\n+\t * matches a common criteria ({@link Matchers#everyItem(Matcher)}), or that each\n+\t * value in the list matches its corresponding dedicated criteria\n+\t * ({@link Matchers#contains(Matcher[])}, and more.\n+\t * @param name the name of the header to consider\n+\t * @param matcher the matcher to apply to the whole list of values for that header\n+\t * @since 6.0.5\n+\t */\n+\tpublic static RequestMatcher header(String name, Matcher> matcher) {\n+\t\treturn request -> {\n+\t\t\tList headerValues = request.getHeaders().get(name);\n+\t\t\tif (headerValues == null) {\n+\t\t\t\tfail(\"No header values for header [\" + name + \"]\");\n+\t\t\t}\n+\t\t\tassertThat(\"Request header values for [\" + name + \"]\", headerValues, matcher);\n+\t\t};\n+\t}\n+\n \t/**\n \t * Assert that the given request header does not exist.\n \t * @since 5.2\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\nindex 562324593966..1e7dc6b26278 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java\n@@ -1,5 +1,5 @@\n /*\n- * Copyright 2002-2022 the original author or authors.\n+ * Copyright 2002-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n@@ -16,18 +16,35 @@\n \n package org.springframework.test.web.client.match;\n \n+import java.io.IOException;\n import java.net.URI;\n import java.util.Arrays;\n import java.util.Collections;\n import java.util.List;\n \n+import org.hamcrest.CoreMatchers;\n+import org.hamcrest.Matchers;\n import org.junit.jupiter.api.Test;\n \n import org.springframework.http.HttpMethod;\n import org.springframework.mock.http.client.MockClientHttpRequest;\n \n+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.assertj.core.api.Assertions.assertThatThrownBy;\n+import static org.hamcrest.Matchers.allOf;\n+import static org.hamcrest.Matchers.any;\n+import static org.hamcrest.Matchers.anything;\n+import static org.hamcrest.Matchers.contains;\n+import static org.hamcrest.Matchers.containsInAnyOrder;\n import static org.hamcrest.Matchers.containsString;\n+import static org.hamcrest.Matchers.endsWith;\n+import static org.hamcrest.Matchers.everyItem;\n+import static org.hamcrest.Matchers.hasItem;\n+import static org.hamcrest.Matchers.hasSize;\n+import static org.hamcrest.Matchers.is;\n+import static org.hamcrest.Matchers.notNullValue;\n+import static org.hamcrest.Matchers.nullValue;\n+import static org.hamcrest.Matchers.startsWith;\n \n /**\n * Unit tests for {@link MockRestRequestMatchers}.\n@@ -146,6 +163,63 @@ void headerContainsWithMissingValue() {\n \t\t\t.hasMessageContaining(\"was \\\"bar\\\"\");\n \t}\n \n+\t@Test\n+\tvoid headerListMissing() {\n+\t\tassertThatThrownBy(() -> MockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t\t.isInstanceOf(AssertionError.class)\n+\t\t\t\t.hasMessage(\"No header values for header [foo]\");\n+\t}\n+\n+\t@Test\n+\tvoid headerListMatchers() throws IOException {\n+\t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n+\n+\t\tMockRestRequestMatchers.header(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), Matchers.anything())).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\t//these can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n+\t\tMockRestRequestMatchers.header(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\t//these are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n+\t\t//string-oriented or obviously a vararg of matchers\n+\t\t//list matcher version\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n+\t\t//vararg version\n+\t\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is((any(String.class)))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", CoreMatchers.either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n+\t\tMockRestRequestMatchers.header(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t}\n+\n+\t@Test\n+\tvoid headerListContainsMismatch() {\n+\t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: iterable containing [a string containing \\\"ba\\\"]\\n\"\n+\t\t\t\t\t\t+ \" but: not matched: \\\"baz\\\"\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: a collection containing a string ending with \\\"ba\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.header(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request header values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: every item is a string ending with \\\"ar\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: an item was \\\"baz\\\"\");\n+\t}\n+\n \t@Test\n \tvoid headers() throws Exception {\n \t\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\n@@ -210,4 +284,62 @@ void queryParamContainsWithMissingValue() {\n \t\t\t.hasMessageContaining(\"was \\\"bar\\\"\");\n \t}\n \n+\n+\t@Test\n+\tvoid queryParamListMissing() {\n+\t\tassertThatThrownBy(() -> MockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request))\n+\t\t\t\t.isInstanceOf(AssertionError.class)\n+\t\t\t\t.hasMessage(\"No queryParam [foo]\");\n+\t}\n+\n+\t@Test\n+\tvoid queryParamListMatchers() throws IOException {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", contains(is(\"bar\"), Matchers.anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", hasSize(2)).match(this.request);\n+\n+\t\t//these can be a bit ambiguous when reading the test (the compiler selects the list matcher):\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", notNullValue()).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is(anything())).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\n+\n+\t\t//these are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\n+\t\t//string-oriented or obviously a vararg of matchers\n+\t\t//list matcher version\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\n+\t\t//vararg version\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is((any(String.class)))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", CoreMatchers.either(is(\"bar\")).or(is(nullValue()))).match(this.request);\n+\t\tMockRestRequestMatchers.queryParam(\"foo\", is(notNullValue()), is(notNullValue())).match(this.request);\n+\t}\n+\n+\t@Test\n+\tvoid queryParamListContainsMismatch() {\n+\t\tthis.request.setURI(URI.create(\"http://www.foo.example/a?foo=bar&foo=baz\"));\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", contains(containsString(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: iterable containing [a string containing \\\"ba\\\"]\\n\"\n+\t\t\t\t\t\t+ \" but: not matched: \\\"baz\\\"\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", hasItem(endsWith(\"ba\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: a collection containing a string ending with \\\"ba\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: mismatches were: [was \\\"bar\\\", was \\\"baz\\\"]\");\n+\n+\t\tassertThatExceptionOfType(AssertionError.class).isThrownBy(() -> MockRestRequestMatchers\n+\t\t\t\t\t\t.queryParam(\"foo\", everyItem(endsWith(\"ar\"))).match(this.request))\n+\t\t\t\t.withMessage(\"Request queryParam values for [foo]\\n\"\n+\t\t\t\t\t\t+ \"Expected: every item is a string ending with \\\"ar\\\"\\n\"\n+\t\t\t\t\t\t+ \" but: an item was \\\"baz\\\"\");\n+\t}\n+\n }\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 29766, "url": "https://github.com/spring-projects/spring-framework/pull/29766", "commits": [{"commit_sha": "0b9aef3084ae1491159462a9b53e4e8ee9ca8527", "labeled_review_comments": [], "total_score": 0.3914893617021276, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": true, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/framework-docs/src/docs/asciidoc/testing/spring-mvc-test-framework.adoc b/framework-docs/src/docs/asciidoc/testing/spring-mvc-test-framework.adoc\nindex 196212377fa0..10f21afe6113 100644\n--- a/framework-docs/src/docs/asciidoc/testing/spring-mvc-test-framework.adoc\n+++ b/framework-docs/src/docs/asciidoc/testing/spring-mvc-test-framework.adoc\n@@ -445,6 +445,17 @@ all failures will be tracked and reported.\n \t\tcontent().contentType(\"application/json;charset=UTF-8\"));\n ----\n \n+[source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n+.Kotlin\n+----\n+\timport org.springframework.test.web.servlet.get\n+\n+\tmockMvc.get(\"/accounts/1\").andExpectAll {\n+\t\tstatus { isOk() }\n+\t\tcontent { contentType(APPLICATION_JSON) }\n+\t}\n+----\n+\n `MockMvcResultMatchers.*` provides a number of expectations, some of which are further\n nested with more detailed expectations.\n \n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 29727, "url": "https://github.com/spring-projects/spring-framework/pull/29727", "commits": [{"commit_sha": "4fc268959235c12426202938f479ba079a3a3e9b", "labeled_review_comments": [{"text": "@user1:\nMaybe add a related usage in tests?\n\n@author:\ndone", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diff_hunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {", "line": 153, "start_line": null, "original_line": 152, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": false, "is_resolved": true, "is_outdated": false, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nClever trick, seems to provide a desired behavior, so good catch!", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diff_hunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {", "line": 28, "start_line": null, "original_line": 27, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": false, "is_resolved": true, "is_outdated": false, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user2:\nMaybe add `@user1 6.0.4`?", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diff_hunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll", "line": 151, "start_line": null, "original_line": 150, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": false, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user2:\nMaybe add `@user1 6.0.4`?", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diff_hunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll", "line": 26, "start_line": null, "original_line": 25, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": false, "is_collapsed": true, "marked_as_dismissed": false}}], "total_score": 0.6893617021276596, "rule_results": {"has_resolved_review_comments": true, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\nindex 8971a80f4b5c..0ba22eafa1c4 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {\n+\t\tactions.andExpectAll(*matchers)\n+\t}\n }\ndiff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\nindex 128b9492b8c4..2bc0ffb426d3 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {\n+\t\tval softMatchers = mutableListOf()\n+\t\tval softActions = object : ResultActions {\n+\t\t\toverride fun andExpect(matcher: ResultMatcher): ResultActions {\n+\t\t\t\tsoftMatchers.add(matcher)\n+\t\t\t\treturn this\n+\t\t\t}\n+\n+\t\t\toverride fun andDo(handler: ResultHandler): ResultActions {\n+\t\t\t\tthrow UnsupportedOperationException(\"andDo should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t\toverride fun andReturn(): MvcResult {\n+\t\t\t\tthrow UnsupportedOperationException(\"andReturn should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t}\n+\t\t// the use of softActions as the matchers DSL actions parameter will store ResultMatchers in list\n+\t\tMockMvcResultMatchersDsl(softActions).dsl()\n+\t\tactions.andExpectAll(*softMatchers.toTypedArray())\n+\t\treturn this;\n+\t}\n+\n \t/**\n \t * Provide access to [MockMvcResultHandlersDsl] Kotlin DSL.\n \t * @see MockMvcResultHandlersDsl.handle\ndiff --git a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\nindex d1e731f3bc27..40e1ded9caf1 100644\n--- a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n+++ b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n@@ -17,6 +17,7 @@\n package org.springframework.test.web.servlet\n \n import org.assertj.core.api.Assertions.assertThat\n+import org.assertj.core.api.Assertions.assertThatCode\n import org.assertj.core.api.Assertions.assertThatExceptionOfType\n import org.hamcrest.CoreMatchers\n import org.junit.jupiter.api.Test\n@@ -25,6 +26,7 @@ import org.springframework.http.HttpStatus\n import org.springframework.http.MediaType.APPLICATION_ATOM_XML\n import org.springframework.http.MediaType.APPLICATION_JSON\n import org.springframework.http.MediaType.APPLICATION_XML\n+import org.springframework.http.MediaType.TEXT_PLAIN\n import org.springframework.test.web.Person\n import org.springframework.test.web.servlet.setup.MockMvcBuilders\n import org.springframework.web.bind.annotation.GetMapping\n@@ -183,6 +185,22 @@ class MockMvcExtensionsTests {\n \t\t}\n \t}\n \n+\t@Test\n+\tfun `andExpectAll reports multiple assertion errors`() {\n+\t\tassertThatCode {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\") {\n+\t\t\t\taccept = APPLICATION_JSON\n+\t\t\t}.andExpectAll {\n+\t\t\t\tstatus { is4xxClientError() }\n+\t\t\t\tcontent { contentType(TEXT_PLAIN) }\n+\t\t\t\tjsonPath(\"$.name\") { value(\"Lee\") }\n+\t\t\t}\n+\t\t}\n+\t\t\t\t.hasMessage(\"Multiple Exceptions (2):\\n\" +\n+\t\t\t\t\t\t\"Range for response status value 200 expected: but was:\\n\" +\n+\t\t\t\t\t\t\"Content type expected: but was:\")\n+\t}\n+\n \n \t@RestController\n \tprivate class PersonController {\n"}, {"commit_sha": "16bbf3ed40891259aaa4cde17da700027bb481bc", "labeled_review_comments": [], "total_score": 0.35319148936170214, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": true, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\nindex 8971a80f4b5c..593f666ec2ea 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n@@ -145,4 +145,12 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @since 6.0.4\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {\n+\t\tactions.andExpectAll(*matchers)\n+\t}\n }\ndiff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\nindex 128b9492b8c4..5d413702467d 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n@@ -19,6 +19,35 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @since 6.0.4\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {\n+\t\tval softMatchers = mutableListOf()\n+\t\tval softActions = object : ResultActions {\n+\t\t\toverride fun andExpect(matcher: ResultMatcher): ResultActions {\n+\t\t\t\tsoftMatchers.add(matcher)\n+\t\t\t\treturn this\n+\t\t\t}\n+\n+\t\t\toverride fun andDo(handler: ResultHandler): ResultActions {\n+\t\t\t\tthrow UnsupportedOperationException(\"andDo should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t\toverride fun andReturn(): MvcResult {\n+\t\t\t\tthrow UnsupportedOperationException(\"andReturn should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t}\n+\t\t// the use of softActions as the matchers DSL actions parameter will store ResultMatchers in list\n+\t\tMockMvcResultMatchersDsl(softActions).dsl()\n+\t\tactions.andExpectAll(*softMatchers.toTypedArray())\n+\t\treturn this;\n+\t}\n+\n \t/**\n \t * Provide access to [MockMvcResultHandlersDsl] Kotlin DSL.\n \t * @see MockMvcResultHandlersDsl.handle\ndiff --git a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\nindex d1e731f3bc27..737e235d4e33 100644\n--- a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n+++ b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n@@ -17,6 +17,7 @@\n package org.springframework.test.web.servlet\n \n import org.assertj.core.api.Assertions.assertThat\n+import org.assertj.core.api.Assertions.assertThatCode\n import org.assertj.core.api.Assertions.assertThatExceptionOfType\n import org.hamcrest.CoreMatchers\n import org.junit.jupiter.api.Test\n@@ -25,6 +26,7 @@ import org.springframework.http.HttpStatus\n import org.springframework.http.MediaType.APPLICATION_ATOM_XML\n import org.springframework.http.MediaType.APPLICATION_JSON\n import org.springframework.http.MediaType.APPLICATION_XML\n+import org.springframework.http.MediaType.TEXT_PLAIN\n import org.springframework.test.web.Person\n import org.springframework.test.web.servlet.setup.MockMvcBuilders\n import org.springframework.web.bind.annotation.GetMapping\n@@ -97,6 +99,24 @@ class MockMvcExtensionsTests {\n \t\tassertThat(handlerInvoked).isTrue()\n \t}\n \n+\t@Test\n+\tfun `request with two custom matchers and matchAll`() {\n+\t\tvar matcher1Invoked = false\n+\t\tvar matcher2Invoked = false\n+\t\tval matcher1 = ResultMatcher { matcher1Invoked = true; throw AssertionError(\"expected\") }\n+\t\tval matcher2 = ResultMatcher { matcher2Invoked = true }\n+\t\tassertThatExceptionOfType(AssertionError::class.java).isThrownBy {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\")\n+\t\t\t\t\t.andExpect {\n+\t\t\t\t\t\tmatchAll(matcher1, matcher2)\n+\t\t\t\t\t}\n+\t\t}\n+\t\t\t\t.withMessage(\"expected\")\n+\n+\t\tassertThat(matcher1Invoked).describedAs(\"matcher1\").isTrue()\n+\t\tassertThat(matcher2Invoked).describedAs(\"matcher2\").isTrue()\n+\t}\n+\n \t@Test\n \tfun get() {\n \t\tmockMvc.get(\"/person/{name}\", \"Lee\") {\n@@ -183,6 +203,22 @@ class MockMvcExtensionsTests {\n \t\t}\n \t}\n \n+\t@Test\n+\tfun `andExpectAll reports multiple assertion errors`() {\n+\t\tassertThatCode {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\") {\n+\t\t\t\taccept = APPLICATION_JSON\n+\t\t\t}.andExpectAll {\n+\t\t\t\tstatus { is4xxClientError() }\n+\t\t\t\tcontent { contentType(TEXT_PLAIN) }\n+\t\t\t\tjsonPath(\"$.name\") { value(\"Lee\") }\n+\t\t\t}\n+\t\t}\n+\t\t\t\t.hasMessage(\"Multiple Exceptions (2):\\n\" +\n+\t\t\t\t\t\t\"Range for response status value 200 expected: but was:\\n\" +\n+\t\t\t\t\t\t\"Content type expected: but was:\")\n+\t}\n+\n \n \t@RestController\n \tprivate class PersonController {\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 29557, "url": "https://github.com/spring-projects/spring-framework/pull/29557", "commits": [{"commit_sha": "19d5c7f44a58c414614ecbae38728aaca02e159f", "labeled_review_comments": [], "total_score": 0.3914893617021276, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\nindex 826d91a3db98..0a10c1b5d613 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\n@@ -68,6 +68,8 @@ public final class MockMvcWebConnection implements WebConnection {\n \n \tprivate WebClient webClient;\n \n+\tprivate static int MAX_FORWARDS = 100;\n+\n \n \t/**\n \t * Create a new instance that assumes the context path of the application\n@@ -133,10 +135,12 @@ public WebResponse getResponse(WebRequest webRequest) throws IOException {\n \n \t\tMockHttpServletResponse httpServletResponse = getResponse(requestBuilder);\n \t\tString forwardedUrl = httpServletResponse.getForwardedUrl();\n-\t\twhile (forwardedUrl != null) {\n+\t\tint forwards = 0;\n+\t\twhile (forwardedUrl != null && forwards < MAX_FORWARDS) {\n \t\t\trequestBuilder.setForwardPostProcessor(new ForwardRequestPostProcessor(forwardedUrl));\n \t\t\thttpServletResponse = getResponse(requestBuilder);\n \t\t\tforwardedUrl = httpServletResponse.getForwardedUrl();\n+\t\t\tforwards += 1;\n \t\t}\n \t\tstoreCookies(webRequest, httpServletResponse.getCookies());\n \ndiff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\nindex 0a96d54bac9c..da8c10fddc38 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\n@@ -31,4 +31,9 @@ public String forward() {\n \t\treturn \"forward:/a\";\n \t}\n \n+\t@RequestMapping(\"/infiniteForward\")\n+\tpublic String infiniteForward() {\n+\t\treturn \"forward:/infiniteForward\";\n+\t}\n+\n }\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\nindex 051cabaf0187..d1413ed6aeb5 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\n@@ -80,6 +80,13 @@ public void forward() throws IOException {\n \t\tassertThat(page.getWebResponse().getContentAsString()).isEqualTo(\"hello\");\n \t}\n \n+\t@Test\n+\tpublic void infiniteForward() throws IOException {\n+\t\tthis.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient, \"\"));\n+\t\tPage page = this.webClient.getPage(\"http://localhost/infiniteForward\");\n+\t\tassertThat(page.getWebResponse().getContentAsString()).isEmpty();\n+\t}\n+\n \t@Test\n \t@SuppressWarnings(\"resource\")\n \tpublic void contextPathDoesNotStartWithSlash() throws IOException {\n"}, {"commit_sha": "56b5ec243063a2cc8acb8ba797b8058b422edab5", "labeled_review_comments": [], "total_score": 0.26382978723404255, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\nindex 826d91a3db98..00978ecac0b3 100644\n--- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\n+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java\n@@ -68,6 +68,8 @@ public final class MockMvcWebConnection implements WebConnection {\n \n \tprivate WebClient webClient;\n \n+\tprivate static int MAX_FORWARDS = 100;\n+\n \n \t/**\n \t * Create a new instance that assumes the context path of the application\n@@ -133,10 +135,15 @@ public WebResponse getResponse(WebRequest webRequest) throws IOException {\n \n \t\tMockHttpServletResponse httpServletResponse = getResponse(requestBuilder);\n \t\tString forwardedUrl = httpServletResponse.getForwardedUrl();\n-\t\twhile (forwardedUrl != null) {\n+\t\tint forwards = 0;\n+\t\twhile (forwardedUrl != null && forwards < MAX_FORWARDS) {\n \t\t\trequestBuilder.setForwardPostProcessor(new ForwardRequestPostProcessor(forwardedUrl));\n \t\t\thttpServletResponse = getResponse(requestBuilder);\n \t\t\tforwardedUrl = httpServletResponse.getForwardedUrl();\n+\t\t\tforwards += 1;\n+\t\t}\n+\t\tif (forwards == MAX_FORWARDS) {\n+\t\t\tthrow new IllegalStateException(\"Forwarded more than \" + forwards + \" times in a row, potential infinite forward loop\");\n \t\t}\n \t\tstoreCookies(webRequest, httpServletResponse.getCookies());\n \ndiff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\nindex 0a96d54bac9c..da8c10fddc38 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java\n@@ -31,4 +31,9 @@ public String forward() {\n \t\treturn \"forward:/a\";\n \t}\n \n+\t@RequestMapping(\"/infiniteForward\")\n+\tpublic String infiniteForward() {\n+\t\treturn \"forward:/infiniteForward\";\n+\t}\n+\n }\ndiff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\nindex 051cabaf0187..6d4caaa3c762 100644\n--- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\n+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java\n@@ -29,6 +29,7 @@\n import static org.assertj.core.api.Assertions.assertThat;\n import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;\n+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;\n \n \n /**\n@@ -80,6 +81,13 @@ public void forward() throws IOException {\n \t\tassertThat(page.getWebResponse().getContentAsString()).isEqualTo(\"hello\");\n \t}\n \n+\t@Test\n+\tpublic void infiniteForward() {\n+\t\tthis.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient, \"\"));\n+\t\tassertThatIllegalStateException().isThrownBy(() -> this.webClient.getPage(\"http://localhost/infiniteForward\"))\n+\t\t\t\t\t\t.withMessage(\"Forwarded more than 100 times in a row, potential infinite forward loop\");\n+\t}\n+\n \t@Test\n \t@SuppressWarnings(\"resource\")\n \tpublic void contextPathDoesNotStartWithSlash() throws IOException {\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 29116, "url": "https://github.com/spring-projects/spring-framework/pull/29116", "commits": [{"commit_sha": "76f31e8fe3109f726f934d04612cff83c2af252a", "labeled_review_comments": [], "total_score": 0.4340425531914893, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\nindex 0c5e629022a3..8cfd3a9f8214 100644\n--- a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\n+++ b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\n@@ -346,8 +346,24 @@ public void initConnection() throws JMSException {\n \t\t\tif (this.connection != null) {\n \t\t\t\tcloseConnection(this.connection);\n \t\t\t}\n-\t\t\tthis.connection = doCreateConnection();\n-\t\t\tprepareConnection(this.connection);\n+\t\t\t// Create new (method local) connection, which is later assigned to instance connection\n+\t\t\t// - prevention to hold instance connection without exception listener, in case when\n+\t\t\t// some subsequent methods (after creation of connection) throws JMSException\n+\t\t\tConnection con = doCreateConnection();\n+\t\t\ttry {\n+\t\t\t\tprepareConnection(con);\n+\t\t\t\tthis.connection = con;\n+\t\t\t}\n+\t\t\tcatch (JMSException ex) {\n+\t\t\t\t// Attempt to close new (not used) connection to release possible resources\n+\t\t\t\ttry {\n+\t\t\t\t\tcon.close();\n+\t\t\t\t}\n+\t\t\t\tcatch(Throwable th) {\n+\t\t\t\t\tlogger.warn(\"Could not close new (not used as shared) JMS Connection\", th);\n+\t\t\t\t}\n+\t\t\t\tthrow ex;\n+\t\t\t}\n \t\t\tif (this.startedCount > 0) {\n \t\t\t\tthis.connection.start();\n \t\t\t}\ndiff --git a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\nindex 110ffa2b106e..cc2b6cc1b252 100644\n--- a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\n+++ b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\n@@ -16,6 +16,9 @@\n \n package org.springframework.jms.connection;\n \n+import java.lang.reflect.Field;\n+import java.util.concurrent.atomic.AtomicInteger;\n+\n import jakarta.jms.Connection;\n import jakarta.jms.ConnectionFactory;\n import jakarta.jms.ExceptionListener;\n@@ -29,7 +32,10 @@\n import jakarta.jms.TopicSession;\n import org.junit.jupiter.api.Test;\n \n+import org.springframework.util.ReflectionUtils;\n+\n import static org.assertj.core.api.Assertions.assertThat;\n+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.mockito.BDDMockito.given;\n import static org.mockito.Mockito.mock;\n import static org.mockito.Mockito.times;\n@@ -341,6 +347,76 @@ public void testWithConnectionFactoryAndExceptionListenerAndReconnectOnException\n \t\tassertThat(listener.getCount()).isEqualTo(1);\n \t}\n \n+\t@Test\n+\tpublic void testWithConnectionFactoryAndExceptionListenerAndReconnectOnExceptionWithJMSException() throws Exception {\n+\t\t// Throws JMSException on setExceptionListener() method, but only at the first time\n+\t\tclass FailingTestConnection extends TestConnection {\n+\t\t\tprivate int setExceptionListenerInvocationCounter;\n+\n+\t\t\t@Override\n+\t\t\tpublic void setExceptionListener(ExceptionListener exceptionListener) throws JMSException {\n+\t\t\t\tsetExceptionListenerInvocationCounter++;\n+\t\t\t\t// Throw JMSException on first invocation\n+\t\t\t\tif (setExceptionListenerInvocationCounter == 1) {\n+\t\t\t\t\tthrow new JMSException(\"Test JMSException (setExceptionListener())\");\n+\t\t\t\t}\n+\t\t\t\tsuper.setExceptionListener(exceptionListener);\n+\t\t\t}\n+\t\t}\n+\n+\t\t// Prepare base JMS ConnectionFactory\n+\t\t// - createConnection(1st) -> TestConnection,\n+\t\t// - createConnection(2nd and next) -> FailingTestConnection\n+\t\tTestConnection testCon = new TestConnection();\n+\t\tFailingTestConnection failingCon = new FailingTestConnection();\n+\t\tAtomicInteger createConnectionMethodCounter = new AtomicInteger();\n+\t\tConnectionFactory cf = mock(ConnectionFactory.class);\n+\t\tgiven(cf.createConnection()).willAnswer(invocation -> {\n+\t\t\tint methodInvocationCounter = createConnectionMethodCounter.incrementAndGet();\n+\t\t\treturn methodInvocationCounter == 1 ? testCon : failingCon;\n+\t\t});\n+\n+\t\t// Prepare SingleConnectionFactory (setReconnectOnException())\n+\t\t// - internal connection exception listener should be registered\n+\t\tSingleConnectionFactory scf = new SingleConnectionFactory(cf);\n+\t\tscf.setReconnectOnException(true);\n+\t\tField conField = ReflectionUtils.findField(SingleConnectionFactory.class, \"connection\");\n+\t\tconField.setAccessible(true);\n+\n+\t\t// Get connection (1st)\n+\t\tConnection con1 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(1);\n+\t\tassertThat(con1).isNotNull();\n+\t\tassertThat(con1.getExceptionListener()).isNotNull();\n+\t\tassertThat(con1).isSameAs(testCon);\n+\t\t// Get connection again, the same should be returned (shared connection till some problem)\n+\t\tConnection con2 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(1);\n+\t\tassertThat(con2.getExceptionListener()).isNotNull();\n+\t\tassertThat(con2).isSameAs(con1);\n+\n+\t\t// Invoke reset connection to simulate problem with connection\n+\t\t// - SCF exception listener should be invoked -> connection should be set to null\n+\t\t// - next attempt to invoke getConnection() must create new connection\n+\t\tscf.resetConnection();\n+\t\tassertThat(conField.get(scf)).isNull();\n+\n+\t\t// Attempt to get connection again\n+\t\t// - JMSException should be returned from FailingTestConnection\n+\t\t// - connection should be still null (no new connection without exception listener like before fix)\n+\t\tassertThatExceptionOfType(JMSException.class).isThrownBy(() -> scf.getConnection());\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(2);\n+\t\tassertThat(conField.get(scf)).isNull();\n+\n+\t\t// Attempt to get connection again -> FailingTestConnection should be returned\n+\t\t// - no JMSException is thrown, exception listener should be present\n+\t\tConnection con3 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(3);\n+\t\tassertThat(con3).isNotNull();\n+\t\tassertThat(con3).isSameAs(failingCon);\n+\t\tassertThat(con3.getExceptionListener()).isNotNull();\n+\t}\n+\n \t@Test\n \tpublic void testWithConnectionFactoryAndLocalExceptionListenerWithCleanup() throws JMSException {\n \t\tConnectionFactory cf = mock(ConnectionFactory.class);\n"}, {"commit_sha": "991b51e0abdd140786a1e6fcf71f4e6b8af71dbc", "labeled_review_comments": [], "total_score": 0.26382978723404255, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\nindex 0c5e629022a3..a7fddcc9720e 100644\n--- a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\n+++ b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java\n@@ -346,8 +346,26 @@ public void initConnection() throws JMSException {\n \t\t\tif (this.connection != null) {\n \t\t\t\tcloseConnection(this.connection);\n \t\t\t}\n-\t\t\tthis.connection = doCreateConnection();\n-\t\t\tprepareConnection(this.connection);\n+\t\t\t// Create new (method local) connection, which is later assigned to instance connection\n+\t\t\t// - prevention to hold instance connection without exception listener, in case when\n+\t\t\t// some subsequent methods (after creation of connection) throws JMSException\n+\t\t\tConnection con = doCreateConnection();\n+\t\t\ttry {\n+\t\t\t\tprepareConnection(con);\n+\t\t\t\tthis.connection = con;\n+\t\t\t}\n+\t\t\tcatch (JMSException ex) {\n+\t\t\t\t// Attempt to close new (not used) connection to release possible resources\n+\t\t\t\ttry {\n+\t\t\t\t\tcon.close();\n+\t\t\t\t}\n+\t\t\t\tcatch(Throwable th) {\n+\t\t\t\t\tif (logger.isDebugEnabled()) {\n+\t\t\t\t\t\tlogger.debug(\"Could not close newly obtained JMS Connection that failed to prepare\", th);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\tthrow ex;\n+\t\t\t}\n \t\t\tif (this.startedCount > 0) {\n \t\t\t\tthis.connection.start();\n \t\t\t}\ndiff --git a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\nindex 110ffa2b106e..cc2b6cc1b252 100644\n--- a/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\n+++ b/spring-jms/src/test/java/org/springframework/jms/connection/SingleConnectionFactoryTests.java\n@@ -16,6 +16,9 @@\n \n package org.springframework.jms.connection;\n \n+import java.lang.reflect.Field;\n+import java.util.concurrent.atomic.AtomicInteger;\n+\n import jakarta.jms.Connection;\n import jakarta.jms.ConnectionFactory;\n import jakarta.jms.ExceptionListener;\n@@ -29,7 +32,10 @@\n import jakarta.jms.TopicSession;\n import org.junit.jupiter.api.Test;\n \n+import org.springframework.util.ReflectionUtils;\n+\n import static org.assertj.core.api.Assertions.assertThat;\n+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;\n import static org.mockito.BDDMockito.given;\n import static org.mockito.Mockito.mock;\n import static org.mockito.Mockito.times;\n@@ -341,6 +347,76 @@ public void testWithConnectionFactoryAndExceptionListenerAndReconnectOnException\n \t\tassertThat(listener.getCount()).isEqualTo(1);\n \t}\n \n+\t@Test\n+\tpublic void testWithConnectionFactoryAndExceptionListenerAndReconnectOnExceptionWithJMSException() throws Exception {\n+\t\t// Throws JMSException on setExceptionListener() method, but only at the first time\n+\t\tclass FailingTestConnection extends TestConnection {\n+\t\t\tprivate int setExceptionListenerInvocationCounter;\n+\n+\t\t\t@Override\n+\t\t\tpublic void setExceptionListener(ExceptionListener exceptionListener) throws JMSException {\n+\t\t\t\tsetExceptionListenerInvocationCounter++;\n+\t\t\t\t// Throw JMSException on first invocation\n+\t\t\t\tif (setExceptionListenerInvocationCounter == 1) {\n+\t\t\t\t\tthrow new JMSException(\"Test JMSException (setExceptionListener())\");\n+\t\t\t\t}\n+\t\t\t\tsuper.setExceptionListener(exceptionListener);\n+\t\t\t}\n+\t\t}\n+\n+\t\t// Prepare base JMS ConnectionFactory\n+\t\t// - createConnection(1st) -> TestConnection,\n+\t\t// - createConnection(2nd and next) -> FailingTestConnection\n+\t\tTestConnection testCon = new TestConnection();\n+\t\tFailingTestConnection failingCon = new FailingTestConnection();\n+\t\tAtomicInteger createConnectionMethodCounter = new AtomicInteger();\n+\t\tConnectionFactory cf = mock(ConnectionFactory.class);\n+\t\tgiven(cf.createConnection()).willAnswer(invocation -> {\n+\t\t\tint methodInvocationCounter = createConnectionMethodCounter.incrementAndGet();\n+\t\t\treturn methodInvocationCounter == 1 ? testCon : failingCon;\n+\t\t});\n+\n+\t\t// Prepare SingleConnectionFactory (setReconnectOnException())\n+\t\t// - internal connection exception listener should be registered\n+\t\tSingleConnectionFactory scf = new SingleConnectionFactory(cf);\n+\t\tscf.setReconnectOnException(true);\n+\t\tField conField = ReflectionUtils.findField(SingleConnectionFactory.class, \"connection\");\n+\t\tconField.setAccessible(true);\n+\n+\t\t// Get connection (1st)\n+\t\tConnection con1 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(1);\n+\t\tassertThat(con1).isNotNull();\n+\t\tassertThat(con1.getExceptionListener()).isNotNull();\n+\t\tassertThat(con1).isSameAs(testCon);\n+\t\t// Get connection again, the same should be returned (shared connection till some problem)\n+\t\tConnection con2 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(1);\n+\t\tassertThat(con2.getExceptionListener()).isNotNull();\n+\t\tassertThat(con2).isSameAs(con1);\n+\n+\t\t// Invoke reset connection to simulate problem with connection\n+\t\t// - SCF exception listener should be invoked -> connection should be set to null\n+\t\t// - next attempt to invoke getConnection() must create new connection\n+\t\tscf.resetConnection();\n+\t\tassertThat(conField.get(scf)).isNull();\n+\n+\t\t// Attempt to get connection again\n+\t\t// - JMSException should be returned from FailingTestConnection\n+\t\t// - connection should be still null (no new connection without exception listener like before fix)\n+\t\tassertThatExceptionOfType(JMSException.class).isThrownBy(() -> scf.getConnection());\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(2);\n+\t\tassertThat(conField.get(scf)).isNull();\n+\n+\t\t// Attempt to get connection again -> FailingTestConnection should be returned\n+\t\t// - no JMSException is thrown, exception listener should be present\n+\t\tConnection con3 = scf.getConnection();\n+\t\tassertThat(createConnectionMethodCounter.get()).isEqualTo(3);\n+\t\tassertThat(con3).isNotNull();\n+\t\tassertThat(con3).isSameAs(failingCon);\n+\t\tassertThat(con3.getExceptionListener()).isNotNull();\n+\t}\n+\n \t@Test\n \tpublic void testWithConnectionFactoryAndLocalExceptionListenerWithCleanup() throws JMSException {\n \t\tConnectionFactory cf = mock(ConnectionFactory.class);\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 28322, "url": "https://github.com/spring-projects/spring-framework/pull/28322", "commits": [{"commit_sha": "5367d96e8dddb5365cb8b0443dace852f0489bed", "labeled_review_comments": [], "total_score": 0.4638297872340425, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 1.0, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": true, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.7}, "patch": "diff --git a/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java b/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\nindex ea7e55cb4c03..6871fb3e8c91 100644\n--- a/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\n+++ b/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\n@@ -39,6 +39,11 @@\n import org.springframework.context.ApplicationEventPublisherAware;\n import org.springframework.context.ApplicationListener;\n import org.springframework.context.PayloadApplicationEvent;\n+import org.springframework.context.annotation.AnnotationConfigApplicationContext;\n+import org.springframework.context.event.test.self_inject.MyApplication;\n+import org.springframework.context.event.test.self_inject.MyEventListener;\n+import org.springframework.context.event.test.self_inject.MyEventPublisher;\n+import org.springframework.context.support.AbstractApplicationContext;\n import org.springframework.context.support.GenericApplicationContext;\n import org.springframework.context.support.StaticApplicationContext;\n import org.springframework.context.support.StaticMessageSource;\n@@ -244,6 +249,24 @@ public void proxiedListenersMixedWithTargetListeners() {\n \t\tassertThat(listener1.seenEvents).hasSize(2);\n \t}\n \n+\t/**\n+\t * Regression test for issue 28283,\n+\t * where event listeners proxied due to e.g.\n+\t *

    \n+\t *
  • {@code @Transactional} annotations in their methods or
  • \n+\t *
  • being targeted by aspects
  • \n+\t *
\n+\t * were added to the list of application listener beans twice (both proxy and unwrapped target).\n+\t */\n+\t@Test\n+\tpublic void eventForSelfInjectedProxiedListenerFiredOnlyOnce() {\n+\t\tString basePackage = MyApplication.class.getPackageName();\n+\t\tAbstractApplicationContext context = new AnnotationConfigApplicationContext(basePackage);\n+\t\tcontext.getBean(MyEventPublisher.class).publishMyEvent(\"hello\");\n+\t\tassertThat(MyEventListener.eventCount).isEqualTo(1);\n+\t\tcontext.close();\n+\t}\n+\n \t@Test\n \tpublic void testEventPublicationInterceptor() throws Throwable {\n \t\tMethodInvocation invocation = mock();\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java\nnew file mode 100644\nindex 000000000000..6686c1b121b8\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java\n@@ -0,0 +1,17 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.context.annotation.AnnotationConfigApplicationContext;\n+import org.springframework.context.annotation.Configuration;\n+import org.springframework.context.annotation.EnableAspectJAutoProxy;\n+import org.springframework.context.support.AbstractApplicationContext;\n+\n+@Configuration\n+@EnableAspectJAutoProxy(proxyTargetClass = true)\n+public class MyApplication {\n+\tpublic static void main(String[] args) {\n+\t\ttry (AbstractApplicationContext context = new AnnotationConfigApplicationContext(\"org.springframework.context.event.test.self_inject\")) {\n+\t\t\tcontext.getBean(MyEventPublisher.class).publishMyEvent(\"hello\");\n+\t\t\tassert MyEventListener.eventCount == 1 : \"event listener must fire exactly once\";\n+\t\t}\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java\nnew file mode 100644\nindex 000000000000..9b037195a9e6\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java\n@@ -0,0 +1,15 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.aspectj.lang.JoinPoint;\n+import org.aspectj.lang.annotation.Aspect;\n+import org.aspectj.lang.annotation.Before;\n+import org.springframework.stereotype.Component;\n+\n+@Aspect\n+@Component\n+public class MyAspect {\n+\t@Before(\"within(org.springframework.context.event.test.self_inject.MyEventListener)\")\n+\tpublic void myAdvice(JoinPoint joinPoint) {\n+\t\t//System.out.println(joinPoint);\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java\nnew file mode 100644\nindex 000000000000..2dc0f2bccf72\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java\n@@ -0,0 +1,12 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.context.ApplicationEvent;\n+\n+public class MyEvent extends ApplicationEvent {\n+\tprivate String message;\n+\n+\tpublic MyEvent(Object source, String message) {\n+\t\tsuper(source);\n+\t\tthis.message = message;\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java\nnew file mode 100644\nindex 000000000000..5fddae77c05c\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java\n@@ -0,0 +1,20 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationListener;\n+import org.springframework.stereotype.Component;\n+\n+@Component\n+public class MyEventListener implements ApplicationListener {\n+\tpublic static int eventCount;\n+\n+\t@Autowired // use '-Dspring.main.allow-circular-references=true' in Spring Boot >= 2.6.0\n+\t//@Lazy // with '@Lazy', the problem does not occur\n+\tprivate MyEventListener eventDemoListener;\n+\n+\t@Override\n+\tpublic void onApplicationEvent(MyEvent event) {\n+\t\t//System.out.println(\"Event: \" + event);\n+\t\teventCount++;\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java\nnew file mode 100644\nindex 000000000000..0959134f7c8b\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java\n@@ -0,0 +1,15 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationEventPublisher;\n+import org.springframework.stereotype.Component;\n+\n+@Component\n+public class MyEventPublisher {\n+\t@Autowired\n+\tprivate ApplicationEventPublisher eventPublisher;\n+\n+\tpublic void publishMyEvent(String message) {\n+\t\teventPublisher.publishEvent(new MyEvent(this, message));\n+\t}\n+}\n"}, {"commit_sha": "0dba415171294487b642c84084ef0207cc60988d", "labeled_review_comments": [], "total_score": 0.3361702127659575, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": true, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.7}, "patch": "diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java\nindex e1f60b9302ee..6464fdfff642 100644\n--- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java\n+++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java\n@@ -262,6 +262,24 @@ private Collection> retrieveApplicationListeners(\n \t\t\t\t\tif (supportsEvent(beanFactory, listenerBeanName, eventType)) {\n \t\t\t\t\t\tApplicationListener listener =\n \t\t\t\t\t\t\t\tbeanFactory.getBean(listenerBeanName, ApplicationListener.class);\n+\n+\t\t\t\t\t\t// Despite best efforts to avoid it, unwrapped proxies (singleton targets) can end up in the\n+\t\t\t\t\t\t// list of programmatically registered listeners. In order to avoid duplicates, we need to find\n+\t\t\t\t\t\t// and replace them by their proxy counterparts, because if both a proxy and its target end up\n+\t\t\t\t\t\t// in 'allListeners', listeners will fire twice.\n+\t\t\t\t\t\tApplicationListener unwrappedListener =\n+\t\t\t\t\t\t\t\t(ApplicationListener) AopProxyUtils.getSingletonTarget(listener);\n+\t\t\t\t\t\tif (listener != unwrappedListener) {\n+\t\t\t\t\t\t\tif (filteredListeners != null && filteredListeners.contains(unwrappedListener)) {\n+\t\t\t\t\t\t\t\tfilteredListeners.remove(unwrappedListener);\n+\t\t\t\t\t\t\t\tfilteredListeners.add(listener);\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t\tif (allListeners.contains(unwrappedListener)) {\n+\t\t\t\t\t\t\t\tallListeners.remove(unwrappedListener);\n+\t\t\t\t\t\t\t\tallListeners.add(listener);\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t}\n+\n \t\t\t\t\t\tif (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {\n \t\t\t\t\t\t\tif (retriever != null) {\n \t\t\t\t\t\t\t\tif (beanFactory.isSingleton(listenerBeanName)) {\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java b/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\nindex ea7e55cb4c03..6871fb3e8c91 100644\n--- a/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\n+++ b/spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java\n@@ -39,6 +39,11 @@\n import org.springframework.context.ApplicationEventPublisherAware;\n import org.springframework.context.ApplicationListener;\n import org.springframework.context.PayloadApplicationEvent;\n+import org.springframework.context.annotation.AnnotationConfigApplicationContext;\n+import org.springframework.context.event.test.self_inject.MyApplication;\n+import org.springframework.context.event.test.self_inject.MyEventListener;\n+import org.springframework.context.event.test.self_inject.MyEventPublisher;\n+import org.springframework.context.support.AbstractApplicationContext;\n import org.springframework.context.support.GenericApplicationContext;\n import org.springframework.context.support.StaticApplicationContext;\n import org.springframework.context.support.StaticMessageSource;\n@@ -244,6 +249,24 @@ public void proxiedListenersMixedWithTargetListeners() {\n \t\tassertThat(listener1.seenEvents).hasSize(2);\n \t}\n \n+\t/**\n+\t * Regression test for issue 28283,\n+\t * where event listeners proxied due to e.g.\n+\t *
    \n+\t *
  • {@code @Transactional} annotations in their methods or
  • \n+\t *
  • being targeted by aspects
  • \n+\t *
\n+\t * were added to the list of application listener beans twice (both proxy and unwrapped target).\n+\t */\n+\t@Test\n+\tpublic void eventForSelfInjectedProxiedListenerFiredOnlyOnce() {\n+\t\tString basePackage = MyApplication.class.getPackageName();\n+\t\tAbstractApplicationContext context = new AnnotationConfigApplicationContext(basePackage);\n+\t\tcontext.getBean(MyEventPublisher.class).publishMyEvent(\"hello\");\n+\t\tassertThat(MyEventListener.eventCount).isEqualTo(1);\n+\t\tcontext.close();\n+\t}\n+\n \t@Test\n \tpublic void testEventPublicationInterceptor() throws Throwable {\n \t\tMethodInvocation invocation = mock();\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java\nnew file mode 100644\nindex 000000000000..6686c1b121b8\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java\n@@ -0,0 +1,17 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.context.annotation.AnnotationConfigApplicationContext;\n+import org.springframework.context.annotation.Configuration;\n+import org.springframework.context.annotation.EnableAspectJAutoProxy;\n+import org.springframework.context.support.AbstractApplicationContext;\n+\n+@Configuration\n+@EnableAspectJAutoProxy(proxyTargetClass = true)\n+public class MyApplication {\n+\tpublic static void main(String[] args) {\n+\t\ttry (AbstractApplicationContext context = new AnnotationConfigApplicationContext(\"org.springframework.context.event.test.self_inject\")) {\n+\t\t\tcontext.getBean(MyEventPublisher.class).publishMyEvent(\"hello\");\n+\t\t\tassert MyEventListener.eventCount == 1 : \"event listener must fire exactly once\";\n+\t\t}\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java\nnew file mode 100644\nindex 000000000000..9b037195a9e6\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java\n@@ -0,0 +1,15 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.aspectj.lang.JoinPoint;\n+import org.aspectj.lang.annotation.Aspect;\n+import org.aspectj.lang.annotation.Before;\n+import org.springframework.stereotype.Component;\n+\n+@Aspect\n+@Component\n+public class MyAspect {\n+\t@Before(\"within(org.springframework.context.event.test.self_inject.MyEventListener)\")\n+\tpublic void myAdvice(JoinPoint joinPoint) {\n+\t\t//System.out.println(joinPoint);\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java\nnew file mode 100644\nindex 000000000000..2dc0f2bccf72\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java\n@@ -0,0 +1,12 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.context.ApplicationEvent;\n+\n+public class MyEvent extends ApplicationEvent {\n+\tprivate String message;\n+\n+\tpublic MyEvent(Object source, String message) {\n+\t\tsuper(source);\n+\t\tthis.message = message;\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java\nnew file mode 100644\nindex 000000000000..5fddae77c05c\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java\n@@ -0,0 +1,20 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationListener;\n+import org.springframework.stereotype.Component;\n+\n+@Component\n+public class MyEventListener implements ApplicationListener {\n+\tpublic static int eventCount;\n+\n+\t@Autowired // use '-Dspring.main.allow-circular-references=true' in Spring Boot >= 2.6.0\n+\t//@Lazy // with '@Lazy', the problem does not occur\n+\tprivate MyEventListener eventDemoListener;\n+\n+\t@Override\n+\tpublic void onApplicationEvent(MyEvent event) {\n+\t\t//System.out.println(\"Event: \" + event);\n+\t\teventCount++;\n+\t}\n+}\ndiff --git a/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java\nnew file mode 100644\nindex 000000000000..0959134f7c8b\n--- /dev/null\n+++ b/spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java\n@@ -0,0 +1,15 @@\n+package org.springframework.context.event.test.self_inject;\n+\n+import org.springframework.beans.factory.annotation.Autowired;\n+import org.springframework.context.ApplicationEventPublisher;\n+import org.springframework.stereotype.Component;\n+\n+@Component\n+public class MyEventPublisher {\n+\t@Autowired\n+\tprivate ApplicationEventPublisher eventPublisher;\n+\n+\tpublic void publishMyEvent(String message) {\n+\t\teventPublisher.publishEvent(new MyEvent(this, message));\n+\t}\n+}\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 27735, "url": "https://github.com/spring-projects/spring-framework/pull/27735", "commits": [{"commit_sha": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f", "labeled_review_comments": [{"text": "@user1:\nI think IncorrectResultSizeDataAccessException should contain the size of the results stream.\r\nif `resultList.size()` will be used, actual size of IncorrectResultSizeDataAccessException is `<=2` always unlike actual size of results.\r\n\r\nIf prefer stream way, How about utilze `teeing`?\r\n```java\r\n\t\tresults.collect(teeing(counting(), reducing((first, second) -> first), (count, result) -> {\r\n\t\t\tif (count > 1) {\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, count.intValue());\r\n\t\t\t}\r\n\t\t\treturn result.orElse(null);\r\n\t\t}))\r\n```\n\n@user2:\nJust a suggestion. There are multiple constructors provided by `IncorrectResultSizeDataAccessException` class. \r\n\r\n* One of the constructors doesn't take `actualSize` argument and assigns the value `-1` if the size if unknown. You can consider using it\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-)\r\n* Another constructor explicitly suggests setting the value of `actualSize` to `-1` if size is unknown\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize, int actualSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-int-)\r\n\r\nBoth of them would be suitable for this scenario since size is unknown\n\n@user1:\nIt makes sense.\n\n@user2:\n```suggestion\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour\n\n@author:\nyeah let's use the `public IncorrectResultSizeDataAccessException(int expectedSize)` for the iterator and stream method. \r\nWhat do you mean by \"UT\"?\r\n\r\nEdit: nevermind, figured it out \ud83d\ude04", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "start_line": null, "original_line": 80, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nSame suggestion as above - [Link](https://github.com/spring-projects/spring-framework/pull/27735/files#r757849057). Since `actualSize` of the iterator isn't known beforehand, we can use `public IncorrectResultSizeDataAccessException(int expectedSize)` constructor and set the `actualSize` as `-1`\r\n```suggestion\r\n\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);", "line": null, "start_line": null, "original_line": 102, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}], "total_score": 0.6468085106382978, "rule_results": {"has_resolved_review_comments": true, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..95db075cdc9a 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43", "labeled_review_comments": [{"text": "@user1:\nWould it be better if we delegate this to original `singleResult(Collection)` method?\r\n\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```\n\n@author:\nHi @user1,\r\n\r\nthat is actually pretty smart. Cuts out a lot of redundant code! \ud83d\udc4d \r\n\r\nedit: i commited all 3 enhancements", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();", "line": null, "start_line": null, "original_line": 123, "original_start_line": 117, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nWould it be better if we delegate this to newly added `singleResult(Stream)` method?\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));", "line": null, "start_line": null, "original_line": 144, "original_start_line": 136, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}, {"text": "@user1:\nWould it be better if we delegate this to newly added `singleResult(Iterator)` method?\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);", "line": null, "start_line": null, "original_line": 165, "original_start_line": 158, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": true, "is_outdated": true, "is_collapsed": true, "marked_as_dismissed": false}}], "total_score": 0.6425531914893617, "rule_results": {"has_resolved_review_comments": true, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.3}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..0d4fe8531dad 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,111 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "b98e7ad15d573bfa846d38b41b0661ae39c7f123", "labeled_review_comments": [{"text": "@user1:\nThere is a trade off here and in `#optionalResult` whether we should call `#close` on the stream:\r\n\r\nOn one hand Java convention is the code who creates a \"resource\" is responsible for disposing it, in this case the caller of this method would be responsible to call `#close` on the streams where required.\r\nOn the other hand failing to call `#close` on some streams, like the ones returned by `JdbcOperations#queryForStream`, can lead to resource leaks. Having the caller put streams in a try-with-resources block is both cumbersome and error prone.\n\n@author:\nMakes sense. The passed stream is now closed in both methods. Also e.g. hibernate's Query.stream() documentation suggests the stream should be closed afterwards, so not so far fetched \ud83d\udc4d", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,107 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.limit(2).toList();", "line": null, "start_line": null, "original_line": 77, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": false, "is_outdated": true, "is_collapsed": false, "marked_as_dismissed": false}}], "total_score": 0.5446808510638298, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..c5933609ce06 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,107 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.limit(2).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tList resultList = results.limit(2).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "ff503c7f74eb26d0ee7383ca53856ec03467d10d", "labeled_review_comments": [{"text": "@user1:\nWouldn't it be better to do a\r\n\r\n .limit(2).toList()\r\n\r\nand then avoid opening the second stream and instead do\r\n\r\n resultList.get(0)\n\n@author:\nHi @user1,\r\n\r\nthanks for reviewing, sounds good, i refactored this. Does it make more sense now?\r\n\r\n`throw new IncorrectResultSizeDataAccessException(1, resultList.size());`\r\nas we limited the resultList size with .limit, this would not report the original passed Stream results size though but instead a maximum of 2... is that an issue?\n\n@user1:\nYes, looks better to me.", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();", "line": null, "start_line": null, "original_line": 78, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": false, "is_outdated": true, "is_collapsed": false, "marked_as_dismissed": false}}, {"text": "@user1:\nWhy a stream instead of just\r\n\r\n results.next()", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();", "line": null, "start_line": null, "original_line": 100, "original_start_line": null, "labels": {"referenced_line_changed_in_merged_commit": true, "is_resolved": false, "is_outdated": true, "is_collapsed": false, "marked_as_dismissed": false}}], "total_score": 0.47659574468085103, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": true, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..a5156386b9d3 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,11 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n+import java.util.stream.StreamSupport;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +61,109 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst();\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..09a50f9b7a41 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -16,13 +16,7 @@\n \n package org.springframework.dao.support;\n \n-import java.util.ArrayList;\n-import java.util.Arrays;\n-import java.util.Collection;\n-import java.util.Date;\n-import java.util.HashMap;\n-import java.util.HashSet;\n-import java.util.Map;\n+import java.util.*;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +41,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +90,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +127,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +170,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +186,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +210,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "1e7d103ef28d2d71953b538b1af3d695b0333f6f", "labeled_review_comments": [], "total_score": 0.4510638297872341, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..fd789518af54 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,105 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "6522003c31a7217a57f7072157c005633c09829b", "labeled_review_comments": [], "total_score": 0.4510638297872341, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..85a092ce0102 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,97 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "4ee08be619d964efaac39345699aa97fdeadf5f5", "labeled_review_comments": [], "total_score": 0.4510638297872341, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..17dd72ab6dd3 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,90 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "9206303d453566cd040d1014aad8cbdc78e56387", "labeled_review_comments": [], "total_score": 0.4340425531914893, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..453d74693093 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "7c096e0683570f8fd99da129de25a80be5bf3e59", "labeled_review_comments": [], "total_score": 0.4340425531914893, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..ce359d4be574 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "f86cf085cd38933189a5d126a6bd6db3966da515", "labeled_review_comments": [], "total_score": 0.374468085106383, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": true, "clear_commit_message": 0.8, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": false, "semantic_commit_message": false, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..d5413e30bf5c 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,11 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n+import java.util.stream.StreamSupport;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +61,109 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst();\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\n@@ -180,7 +288,7 @@ else if (Number.class.isAssignableFrom(requiredType) && result instanceof Number\n \t\t\telse {\n \t\t\t\tthrow new TypeMismatchDataAccessException(\n \t\t\t\t\t\t\"Result object is of type [\" + result.getClass().getName() +\n-\t\t\t\t\t\t\"] and could not be converted to required type [\" + requiredType.getName() + \"]\");\n+\t\t\t\t\t\t\t\t\"] and could not be converted to required type [\" + requiredType.getName() + \"]\");\n \t\t\t}\n \t\t}\n \t\treturn (T) result;\n@@ -242,5 +350,4 @@ public static RuntimeException translateIfNecessary(\n \t\tDataAccessException dae = pet.translateExceptionIfPossible(rawException);\n \t\treturn (dae != null ? dae : rawException);\n \t}\n-\n }\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..4f8f129fe4f6 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -16,17 +16,9 @@\n \n package org.springframework.dao.support;\n \n-import java.util.ArrayList;\n-import java.util.Arrays;\n-import java.util.Collection;\n-import java.util.Date;\n-import java.util.HashMap;\n-import java.util.HashSet;\n-import java.util.Map;\n+import java.util.*;\n import java.util.function.Consumer;\n-\n import org.junit.jupiter.api.Test;\n-\n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.IncorrectResultSizeDataAccessException;\n import org.springframework.dao.InvalidDataAccessApiUsageException;\n@@ -47,21 +39,28 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 0));\n+\t\t\t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 0));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.objectResult(col, String.class))\n-\t\t\t.satisfies(sizeRequirements(1, 0));\n+\t\t\t\t\t\tDataAccessUtils.objectResult(col, String.class))\n+\t\t\t\t.satisfies(sizeRequirements(1, 0));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.intResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 0));\n+\t\t\t\t\t\tDataAccessUtils.intResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 0));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.longResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 0));\n+\t\t\t\t\t\tDataAccessUtils.longResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 0));\n \t}\n \n \t@Test\n@@ -71,24 +70,48 @@ public void withTooLargeCollection() {\n \t\tcol.add(\"test2\");\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.uniqueResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t\t\tDataAccessUtils.uniqueResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.objectResult(col, String.class))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.intResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t\t\tDataAccessUtils.longResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.objectResult(col, String.class))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.intResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n-\t\t\t\tDataAccessUtils.longResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +125,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -124,8 +153,8 @@ public void withEquivalentIntegerInstanceTwice() {\n \t\tCollection col = Arrays.asList(Integer.valueOf(555), Integer.valueOf(555));\n \n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)\n-\t\t\t.isThrownBy(() -> DataAccessUtils.uniqueResult(col))\n-\t\t\t.satisfies(sizeRequirements(1, 2));\n+\t\t\t\t.isThrownBy(() -> DataAccessUtils.uniqueResult(col))\n+\t\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -139,6 +168,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,12 +184,20 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col));\n+\n+\n \t}\n \n \t@Test\n@@ -167,6 +210,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, {"commit_sha": "1891fa45b5d43a3741905531f8b84944a7c820e0", "labeled_review_comments": [], "total_score": 0.32765957446808514, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.5, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": true, "issue_reference": false, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 0.0}, "patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..ce359d4be574 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..0efee06ca6ac 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -199,6 +255,13 @@ private Consumer sizeRequi\n \t\t};\n \t}\n \n+\tprivate Consumer sizeRequirements(\n+\t\t\tint expectedSize) {\n+\t\treturn ex -> {\n+\t\t\tassertThat(ex.getExpectedSize()).as(\"expected size\").isEqualTo(expectedSize);\n+\t\t};\n+\t}\n+\n \tpublic static class MapPersistenceExceptionTranslator implements PersistenceExceptionTranslator {\n \n \t\t// in to out\n"}]} +{"repo_owner": "spring-projects", "repo_name": "spring-framework", "pr_number": 27303, "url": "https://github.com/spring-projects/spring-framework/pull/27303", "commits": [{"commit_sha": "51a17316ff5d464400ffc9f7a42b34ba0c0eea69", "labeled_review_comments": [], "total_score": 0.3659574468085107, "rule_results": {"has_resolved_review_comments": false, "has_referenced_line_changed_comments": false, "exclude_merge_commit": true, "exclude_base_merge_commit": false, "clear_commit_message": 0.7, "conventional_commit": false, "reasonable_commit_size": 0.1, "has_associated_review_comments": false, "issue_reference": true, "semantic_commit_message": true, "focused_file_changes": 1.0, "descriptive_commit_content": 1.0}, "patch": "diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java\nindex 575f822f957f..663dbb7566c4 100644\n--- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java\n+++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java\n@@ -147,7 +147,6 @@ public void setRemoveSemicolonContent(boolean removeSemicolonContent) {\n \t * Whether configured to remove \";\" (semicolon) content from the request URI.\n \t */\n \tpublic boolean shouldRemoveSemicolonContent() {\n-\t\tcheckReadOnly();\n \t\treturn this.removeSemicolonContent;\n \t}\n \ndiff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java\nindex 0aea5a0b51d9..1b2921205f51 100644\n--- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java\n+++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java\n@@ -22,6 +22,7 @@\n import org.springframework.web.testfixture.servlet.MockHttpServletRequest;\n \n import static org.assertj.core.api.Assertions.assertThat;\n+import static org.assertj.core.api.Assertions.assertThatCode;\n \n /**\n * Unit tests for {@link UrlPathHelper}.\n@@ -165,6 +166,11 @@ public void getLookupPathWithSemicolonContentAndNullPathInfo() {\n \t\tassertThat(helper.getLookupPathForRequest(request)).isEqualTo(\"/welcome.html;c=d\");\n \t}\n \n+\t@Test // gh-27303\n+\tpublic void shouldRemoveSemicolonContentWithReadOnlyInstance() {\n+\t\tassertThatCode(UrlPathHelper.defaultInstance::shouldRemoveSemicolonContent).doesNotThrowAnyException();\n+\t}\n+\n \n \t//\n \t// suite of tests root requests for default servlets (SRV 11.2) on Websphere vs Tomcat and other containers\n"}]} diff --git a/results/dataset/code_review_task_instances.jsonl b/results/dataset/code_review_task_instances.jsonl new file mode 100644 index 0000000..bcaff08 --- /dev/null +++ b/results/dataset/code_review_task_instances.jsonl @@ -0,0 +1,3 @@ +{"instance_id": "spring-projects__spring-framework-31619@1f9b099", "repo": "spring-projects/spring-framework", "language": "Java", "pull_number": 31619, "title": "Extract recurring asciidoc links to attributes", "body": "This commit extracts Spring-related links and recurring external links into asciidoctor attributes to be used by the Antora toolchain.\r\n\r\nIt notably homogenizes links to:\r\n - IETF RFCs\r\n - Java Community Process JSRs\r\n - Java API Documentation (Java 17 version)\r\n - Kotlin documentation (Kotlinlang.org version)\r\n - the Spring Boot reference guide (`html` version)\r\n\r\nThis commit also reworks most link attributes to follow a Project-Category-Misc syntax. For example, `spring-boot-docs` rather than `docs-spring-boot`.\r\n\r\nCloses gh-26864", "created_at": "2023-11-17T12:29:55Z", "problem_statement": "Use asciidoc attributes in reference documentation\nThere are a number of places where links could use an attribute to rationalize what we use and make sure they are consistent.", "hints_text": "", "resolved_issues": [{"number": 26864, "title": "Use asciidoc attributes in reference documentation", "body": "There are a number of places where links could use an attribute to rationalize what we use and make sure they are consistent."}], "base_commit": "bec385d310865331db34b1ef8f93f0b0c29eac2e", "commit_to_review": {"head_commit": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794", "head_commit_message": "Extract recurring asciidoc links to attributes\n\nThis commit extract spring-related links and recurring\nexternal links into asciidoctor attributes to be used\nby the Antora toolchain.\n\nIt notably homogenizes links to:\n - IETF RFCs\n - Java Community Process JSRs\n - the Java API Documentation (on the Java 17 version)\n - Kotlin documentations (on the Kotlinlang.org version)\n - the Spring Boot reference guide (on the `html` version)\n\nThis commit also reworks most link attributes to follow\na Project-Category-Misc syntax. For example, spring-boot-docs rather than docs-spring-boot.\n\nCloses gh-26864", "patch_to_review": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..121996a15ef5 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 9dd9bcd2d244..6f026c550e71 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -438,4 +438,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\nindex 177a6ae44107..d5eadd684f0b 100644\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ b/framework-docs/modules/ROOT/pages/attributes.adoc\n@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io\n+// :docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n+// :docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n+// :docs-spring-security: {docs-site}/spring-security/reference\n // spring-asciidoctor-backends Settings\n :chomp: default headers packages\n :fold: all\n // Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\n+// :docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n+// :api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n+// :docs-java: {docdir}/../../main/java/org/springframework/docs\n+// :docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n+// :docs-resources: {docdir}/../../main/resources\n+// :spring-framework-main-code: {spring-framework}/tree/main\n+// // Third-party Links\n+// :docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n+// :gh-rsocket: https://github.com/rsocket\n+// :gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n+// :gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..9e64fc1447ff 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {issues-old}/SPR-10237[SPR-10237]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 53a59abf8fcf..16832f42a110 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex 4118859a1585..3f302101a21c 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\n@@ -386,7 +386,7 @@ class SpecificationLikeTests {\n [[kotlin-webtestclient-issue]]\n === `WebTestClient` Type Inference Issue in Kotlin\n \n-Due to a https://youtrack.jetbrains.com/issue/KT-5464[type inference issue], you must\n+Due to a {kotlin-issues}/KT-5464[type inference issue], you must\n use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo(\"toys\")`),\n since it provides a workaround for the Kotlin issue with the Java API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 16a44856931c..0a10a3c17221 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -51,7 +51,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -84,7 +84,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -130,7 +130,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -442,7 +442,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex b7ef832ffa33..e5290659e5dc 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`], support for xref:web-reactive.adoc#webflux-test[testing],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d75c3c842500..6b1c2ee5d992 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,18 +7,18 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. The xref:testing/unit.adoc#mock-objects-web-reactive[next chapter]\n covers Spring WebFlux.\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\n"}, "reference_review_comments": [{"text": "@user1:\nSince this is specific to Framework (as opposed to the Spring portfolio in general) and is only used once, I suggest we remove it and inline it in `spring-framework-github`.", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"", "line": null, "start_line": null, "original_line": 28, "original_start_line": null}, {"text": "@user1:\nA quick search reveals that we're only using that base URL for a single `SPR-` issue.\r\n\r\nSince all `SPR-` issues have been migrated to GitHub, I suggest we remove the `issues-old` attribute.\r\n\r\nIn fact, I'll replace that JIRA link with a GitHub link on `main`.\n\n@author:\n@user1 let's perhaps do the replace in this PR? (this would avoid a merge conflict)\n\n@user1:\nIt turns out the sections related to that SPR issue were obsolete, so I removed them in 617ba845771f8cf6d8f7e30ba8ff66214e97bc54.\r\n\r\nApologies if that causes troubling merge conflicts.", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'", "line": null, "start_line": null, "original_line": 33, "original_start_line": null}, {"text": "@user1:\nThis appears to be overridden in `attributes.adoc`.\r\n\r\nDo we need both?\n\n@author:\nI don't think so, not even sure `attributes.adoc` is used anymore in the antora toolchain \ud83e\udd14\r\nactually, let me double check that the whole `src/docs/asciidoc` folder is even relevant at all now...", "path": "framework-docs/antora.yml", "diff_hunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'", "line": 19, "start_line": null, "original_line": 19, "original_start_line": null}, {"text": "@user1:\nDo we still need this file?\r\n\r\nIn other words, can we move `chomp` and `fold` to `antora.yml` and remove this one?", "path": "framework-docs/modules/ROOT/pages/attributes.adoc", "diff_hunk": "@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io", "line": null, "start_line": null, "original_line": 2, "original_start_line": null}], "merged_commit": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3", "merged_patch": "diff --git a/framework-docs/antora.yml b/framework-docs/antora.yml\nindex 642ecd19f6cd..41f2780cdf82 100644\n--- a/framework-docs/antora.yml\n+++ b/framework-docs/antora.yml\n@@ -17,16 +17,73 @@ asciidoc:\n # FIXME: the copyright is not removed\n # FIXME: The package is not renamed\n chomp: 'all'\n+ fold: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-org}/spring-framework\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ spring-framework-wiki: '{spring-framework-github}/wiki'\n+ # Docs\n docs-site: 'https://docs.spring.io'\n- docs-spring: \"{docs-site}/spring-framework/docs/{spring-version}\"\n- docs-spring-framework: '{docs-site}/spring-framework/docs/{spring-version}'\n- api-spring-framework: '{docs-spring-framework}/javadoc-api/org/springframework'\n- docs-graalvm: 'https://www.graalvm.org/22.3/reference-manual'\n- docs-spring-boot: '{docs-site}/spring-boot/docs/current/reference'\n+ spring-framework-docs-root: '{docs-site}/spring-framework/docs'\n+ spring-framework-api: '{spring-framework-docs-root}/{spring-version}/javadoc-api/org/springframework'\n+ spring-framework-api-kdoc: '{spring-framework-docs-root}/{spring-version}/kdoc-api'\n+ spring-framework-reference: '{spring-framework-docs-root}/{spring-version}/reference'\n+ #\n+ # Other Spring portfolio projects\n+ spring-boot-docs: '{docs-site}/spring-boot/docs/current/reference/html'\n+ spring-boot-issues: '{spring-github-org}/spring-boot/issues'\n+ # TODO add more projects / links or just build up on {docs-site}?\n+ # TODO rename the below using new conventions\n docs-spring-gemfire: '{docs-site}/spring-gemfire/docs/current/reference'\n docs-spring-security: '{docs-site}/spring-security/reference'\n- gh-rsocket: 'https://github.com/rsocket'\n- gh-rsocket-extensions: '{gh-rsocket}/rsocket/blob/master/Extensions'\n- gh-rsocket-java: '{gh-rsocket}/rsocket-java{gh-rsocket}/rsocket-java'\n\\ No newline at end of file\n+ docs-spring-session: '{docs-site}/spring-session/reference'\n+ #\n+ # External projects URLs and related attributes\n+ aspectj-site: 'https://www.eclipse.org/aspectj'\n+ aspectj-docs: \"{aspectj-site}/doc/released\"\n+ aspectj-api: \"{aspectj-docs}/runtime-api\"\n+ aspectj-docs-devguide: \"{aspectj-docs}/devguide\"\n+ aspectj-docs-progguide: \"{aspectj-docs}/progguide\"\n+ assertj-docs: 'https://assertj.github.io/doc'\n+ baeldung-blog: 'https://www.baeldung.com'\n+ bean-validation-site: 'https://beanvalidation.org'\n+ graalvm-docs: 'https://www.graalvm.org/22.3/reference-manual'\n+ hibernate-validator-site: 'https://hibernate.org/validator/'\n+ jackson-docs: 'https://fasterxml.github.io'\n+ jackson-github-org: 'https://github.com/FasterXML'\n+ java-api: 'https://docs.oracle.com/en/java/javase/17/docs/api'\n+ java-tutorial: 'https://docs.oracle.com/javase/tutorial'\n+ JSR: 'https://www.jcp.org/en/jsr/detail?id='\n+ kotlin-site: 'https://kotlinlang.org'\n+ kotlin-docs: '{kotlin-site}/docs'\n+ kotlin-api: '{kotlin-site}/api/latest'\n+ kotlin-coroutines-api: '{kotlin-site}/api/kotlinx.coroutines'\n+ kotlin-github-org: 'https://github.com/Kotlin'\n+ kotlin-issues: 'https://youtrack.jetbrains.com/issue'\n+ reactive-streams-site: 'https://www.reactive-streams.org'\n+ reactive-streams-spec: 'https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification'\n+ reactor-github-org: 'https://github.com/reactor'\n+ reactor-site: 'https://projectreactor.io'\n+ rsocket-github-org: 'https://github.com/rsocket'\n+ rsocket-java: '{rsocket-github-org}/rsocket-java'\n+ rsocket-java-code: '{rsocket-java}/tree/master/'\n+ rsocket-protocol-extensions: '{rsocket-github-org}/rsocket/tree/master/Extensions'\n+ rsocket-site: 'https://rsocket.io'\n+ rfc-site: 'https://datatracker.ietf.org/doc/html'\n+ sockjs-client: 'https://github.com/sockjs/sockjs-client'\n+ sockjs-protocol: 'https://github.com/sockjs/sockjs-protocol'\n+ sockjs-protocol-site: \"https://sockjs.github.io/sockjs-protocol\"\n+ stackoverflow-site: 'https://stackoverflow.com'\n+ stackoverflow-questions: '{stackoverflow-site}/questions'\n+ stackoverflow-spring-tag: \"{stackoverflow-questions}/tagged/spring\"\n+ stackoverflow-spring-kotlin-tags: \"{stackoverflow-spring-tag}+kotlin\"\n+ testcontainers-site: 'https://www.testcontainers.org'\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc\nindex 652f492bdf65..9a9b4e831f50 100644\n--- a/framework-docs/modules/ROOT/nav.adoc\n+++ b/framework-docs/modules/ROOT/nav.adoc\n@@ -439,4 +439,4 @@\n ** xref:languages/groovy.adoc[]\n ** xref:languages/dynamic.adoc[]\n * xref:appendix.adoc[]\n-* https://github.com/spring-projects/spring-framework/wiki[Wiki]\n\\ No newline at end of file\n+* {spring-framework-wiki}[Wiki]\n\\ No newline at end of file\ndiff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc\nindex c6c7d9d89815..4f3229f94ef8 100644\n--- a/framework-docs/modules/ROOT/pages/appendix.adoc\n+++ b/framework-docs/modules/ROOT/pages/appendix.adoc\n@@ -8,7 +8,7 @@ within the core Spring Framework.\n [[appendix-spring-properties]]\n == Spring Properties\n \n-{api-spring-framework}/core/SpringProperties.html[`SpringProperties`] is a static holder\n+{spring-framework-api}/core/SpringProperties.html[`SpringProperties`] is a static holder\n for properties that control certain low-level aspects of the Spring Framework. Users can\n configure these properties via JVM system properties or programmatically via the\n `SpringProperties.setProperty(String key, String value)` method. The latter may be\n@@ -25,7 +25,7 @@ The following table lists all currently supported Spring properties.\n | `spring.beaninfo.ignore`\n | Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the\n JavaBeans `Introspector`. See\n-{api-spring-framework}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n+{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]\n for details.\n \n | `spring.expression.compiler.mode`\n@@ -36,7 +36,7 @@ xref:core/expressions/evaluation.adoc#expressions-compiler-configuration[Spring\n | Instructs Spring to ignore operating system environment variables if a Spring\n `Environment` property -- for example, a placeholder in a configuration String -- isn't\n resolvable otherwise. See\n-{api-spring-framework}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n+{spring-framework-api}++/core/env/AbstractEnvironment.html#IGNORE_GETENV_PROPERTY_NAME++[`AbstractEnvironment`]\n for details.\n \n | `spring.jdbc.getParameterType.ignore`\n@@ -47,12 +47,12 @@ See the note in xref:data-access/jdbc/advanced.adoc#jdbc-batch-list[Batch Operat\n | Instructs Spring to ignore a default JNDI environment, as an optimization for scenarios\n where nothing is ever to be found for such JNDI fallback searches to begin with, avoiding\n the repeated JNDI lookup overhead. See\n-{api-spring-framework}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n+{spring-framework-api}++/jndi/JndiLocatorDelegate.html#IGNORE_JNDI_PROPERTY_NAME++[`JndiLocatorDelegate`]\n for details.\n \n | `spring.objenesis.ignore`\n | Instructs Spring to ignore Objenesis, not even attempting to use it. See\n-{api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n+{spring-framework-api}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`]\n for details.\n \n | `spring.test.aot.processing.failOnError`\ndiff --git a/framework-docs/modules/ROOT/pages/attributes.adoc b/framework-docs/modules/ROOT/pages/attributes.adoc\ndeleted file mode 100644\nindex 177a6ae44107..000000000000\n--- a/framework-docs/modules/ROOT/pages/attributes.adoc\n+++ /dev/null\n@@ -1,20 +0,0 @@\n-// Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n-// spring-asciidoctor-backends Settings\n-:chomp: default headers packages\n-:fold: all\n-// Spring Framework\n-:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}\n-:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework\n-:docs-java: {docdir}/../../main/java/org/springframework/docs\n-:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs\n-:docs-resources: {docdir}/../../main/resources\n-:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main\n-// Third-party Links\n-:docs-graalvm: https://www.graalvm.org/22.3/reference-manual\n-:gh-rsocket: https://github.com/rsocket\n-:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions\n-:gh-rsocket-java: {gh-rsocket}/rsocket-java\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\nindex 8882dfd2da52..6d6f423a6f2e 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/extensibility.adoc\n@@ -12,5 +12,5 @@ support for new custom advice types be added without changing the core framework\n The only constraint on a custom `Advice` type is that it must implement the\n `org.aopalliance.aop.Advice` marker interface.\n \n-See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n+See the {spring-framework-api}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]\n javadoc for further information.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\nindex fdb41e7b4d18..f174ce954015 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop-api/targetsource.adoc\n@@ -119,7 +119,7 @@ The following listing shows an example configuration:\n \n Note that the target object (`businessObjectTarget` in the preceding example) must be a\n prototype. This lets the `PoolingTargetSource` implementation create new instances\n-of the target to grow the pool as necessary. See the {api-spring-framework}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n+of the target to grow the pool as necessary. See the {spring-framework-api}/aop/target/AbstractPoolingTargetSource.html[javadoc of\n `AbstractPoolingTargetSource`] and the concrete subclass you wish to use for information\n about its properties. `maxSize` is the most basic and is always guaranteed to be present.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\nindex 1a243d51c361..28664394da12 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/aspectj-programmatic.adoc\n@@ -52,7 +52,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n+See the {spring-framework-api}/aop/aspectj/annotation/AspectJProxyFactory.html[javadoc] for more information.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\nindex 952aca1f76c3..4380293f2f1b 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj.adoc\n@@ -4,7 +4,7 @@\n \n @AspectJ refers to a style of declaring aspects as regular Java classes annotated with\n annotations. The @AspectJ style was introduced by the\n-https://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring\n+{aspectj-site}[AspectJ project] as part of the AspectJ 5 release. Spring\n interprets the same annotations as AspectJ 5, using a library supplied by AspectJ\n for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and\n there is no dependency on the AspectJ compiler or weaver.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\nindex 30f2bc8dc099..55c3b9146650 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/advice.adoc\n@@ -482,7 +482,7 @@ The `JoinPoint` interface provides a number of useful methods:\n * `getSignature()`: Returns a description of the method that is being advised.\n * `toString()`: Prints a useful description of the method being advised.\n \n-See the https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n+See the {aspectj-api}/org/aspectj/lang/JoinPoint.html[javadoc] for more detail.\n \n [[aop-ataspectj-advice-params-passing]]\n === Passing Parameters to Advice\n@@ -730,7 +730,7 @@ of determining parameter names, an exception will be thrown.\n flag for `javac`. Recommended approach on Java 8+.\n `AspectJAdviceParameterNameDiscoverer` :: Deduces parameter names from the pointcut\n expression, `returning`, and `throwing` clauses. See the\n- {api-spring-framework}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n+ {spring-framework-api}/aop/aspectj/AspectJAdviceParameterNameDiscoverer.html[javadoc]\n for details on the algorithm used.\n \n [[aop-ataspectj-advice-params-names-explicit]]\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\nindex 34386f80393d..3b1ef29d767a 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/ataspectj/pointcuts.adoc\n@@ -36,9 +36,9 @@ Kotlin::\n \n The pointcut expression that forms the value of the `@Pointcut` annotation is a regular\n AspectJ pointcut expression. For a full discussion of AspectJ's pointcut language, see\n-the https://www.eclipse.org/aspectj/doc/released/progguide/index.html[AspectJ\n+the {aspectj-docs-progguide}/index.html[AspectJ\n Programming Guide] (and, for extensions, the\n-https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html[AspectJ 5\n+{aspectj-docs}/adk15notebook/index.html[AspectJ 5\n Developer's Notebook]) or one of the books on AspectJ (such as _Eclipse AspectJ_, by Colyer\n et al., or _AspectJ in Action_, by Ramnivas Laddad).\n \n@@ -392,7 +392,7 @@ method that takes no parameters, whereas `(..)` matches any number (zero or more\n The `({asterisk})` pattern matches a method that takes one parameter of any type.\n `(*,String)` matches a method that takes two parameters. The first can be of any type, while the\n second must be a `String`. Consult the\n-https://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html[Language\n+{aspectj-docs-progguide}/semantics-pointcuts.html[Language\n Semantics] section of the AspectJ Programming Guide for more information.\n \n The following examples show some common pointcut expressions:\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\nindex e95cb1f99559..ab723c056921 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/resources.adoc\n@@ -2,7 +2,7 @@\n = Further Resources\n :page-section-summary-toc: 1\n \n-More information on AspectJ can be found on the https://www.eclipse.org/aspectj[AspectJ website].\n+More information on AspectJ can be found on the {aspectj-site}[AspectJ website].\n \n _Eclipse AspectJ_ by Adrian Colyer et. al. (Addison-Wesley, 2005) provides a\n comprehensive introduction and reference for the AspectJ language.\ndiff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\nindex bdf6d01b7076..8694443677db 100644\n--- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc\n@@ -136,7 +136,7 @@ using Spring in accordance with the properties of the annotation\". In this conte\n \"initialization\" refers to newly instantiated objects (for example, objects instantiated\n with the `new` operator) as well as to `Serializable` objects that are undergoing\n deserialization (for example, through\n-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).\n+{java-api}/java.base/java/io/Serializable.html[readResolve()]).\n \n [NOTE]\n =====\n@@ -168,14 +168,13 @@ Kotlin::\n \n You can find more information about the language semantics of the various pointcut\n types in AspectJ\n-https://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html[in this\n-appendix] of the https://www.eclipse.org/aspectj/doc/next/progguide/index.html[AspectJ\n-Programming Guide].\n+{aspectj-docs-progguide}/semantics-joinPoints.html[in this appendix] of the\n+{aspectj-docs-progguide}/index.html[AspectJ Programming Guide].\n =====\n \n For this to work, the annotated types must be woven with the AspectJ weaver. You can\n either use a build-time Ant or Maven task to do this (see, for example, the\n-https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development\n+{aspectj-docs-devguide}/antTasks.html[AspectJ Development\n Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The\n `AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain\n a reference to the bean factory that is to be used to configure new objects). If you\n@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex\n Spring Framework. This section is not a general introduction to LTW. For full details on\n the specifics of LTW and configuring LTW with only AspectJ (with Spring not being\n involved at all), see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ\n+{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ\n Development Environment Guide].\n \n The value that the Spring Framework brings to AspectJ LTW is in enabling much\n@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch\n Now that the sales pitch is over, let us first walk through a quick example of AspectJ\n LTW that uses Spring, followed by detailed specifics about elements introduced in the\n example. For a complete example, see the\n-https://github.com/spring-projects/spring-petclinic[Petclinic sample application].\n+{spring-github-org}/spring-petclinic[Petclinic sample application].\n \n \n [[aop-aj-ltw-first-example]]\n@@ -621,7 +620,7 @@ java -javaagent:C:/projects/xyz/lib/spring-instrument.jar com.xyz.Main\n ----\n \n The `-javaagent` is a flag for specifying and enabling\n-https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agents\n to instrument programs that run on the JVM]. The Spring Framework ships with such an\n agent, the `InstrumentationSavingAgent`, which is packaged in the\n `spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in\n@@ -721,7 +720,7 @@ The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.\n files that are on the Java classpath (either directly or, more typically, in jar files).\n \n The structure and contents of this file is detailed in the LTW part of the\n-https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference\n+{aspectj-docs-devguide}/ltw-configuration.html[AspectJ reference\n documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/aot.adoc b/framework-docs/modules/ROOT/pages/core/aot.adoc\nindex 7c2a5ddd0920..cba6785e6d58 100644\n--- a/framework-docs/modules/ROOT/pages/core/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/aot.adoc\n@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:\n * The beans defined in your application cannot change at runtime, meaning:\n ** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.\n ** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.\n-* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).\n+* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).\n * Make sure that the bean type is as precise as possible.\n \n TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.\n@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:\n \n * Java source code\n * Bytecode (usually for dynamic proxies)\n-* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n+* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.\n \n NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.\n We intend to support more JVM-based use cases in future generations.\n@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.\n [[aot.basics]]\n == AOT engine overview\n \n-The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:\n+The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:\n \n * Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.\n * Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.\n@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a\n [[aot.bean-factory-initialization-contributions]]\n == Bean Factory Initialization AOT Contributions\n \n-Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n+Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.\n Each implementation can return an AOT contribution, based on the state of the bean factory.\n \n An AOT contribution is a component that contributes generated code that reproduces a particular behavior.\n@@ -261,7 +261,7 @@ If you are registering bean definitions programmatically, consider using `RootBe\n The container is able to choose the most appropriate constructor to use based on several candidates.\n However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.\n \n-In case you are working on a code base that you can't modify, you can set the {api-spring-framework}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n+In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.\n \n [[aot.bestpractices.factory-bean]]\n === FactoryBean\n@@ -379,7 +379,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection\n Similarly, classpath resources are not shipped in a native image unless specified explicitly.\n Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.\n \n-The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n+The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.\n The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:\n \n [tabs]\n@@ -417,7 +417,7 @@ It is also possible to register an implementation statically by adding an entry\n [[aot.hints.reflective]]\n === `@Reflective`\n \n-{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n+{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.\n For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.\n \n By default, only Spring beans are considered and an invocation hint is registered for the annotated element.\n@@ -431,7 +431,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia\n [[aot.hints.register-reflection-for-binding]]\n === `@RegisterReflectionForBinding`\n \n-{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n+{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.\n A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.\n \n `@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.\n@@ -467,7 +467,7 @@ include-code::./SpellCheckServiceTests[tag=hintspredicates]\n With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.\n This approach works well for unit tests but implies that the runtime behavior of a component is well known.\n \n-You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n+You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].\n This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.\n \n For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `\"org.springframework:spring-core-test\"`.\n@@ -499,4 +499,4 @@ io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldReg\n \n There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.\n The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).\n-You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\n+You'll find more details in the {spring-framework-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.\ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\nindex a0ccd3cb33b4..5ca36a86567b 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xml-custom.adoc\n@@ -765,7 +765,7 @@ want to add an additional attribute to the existing bean definition element.\n \n By way of another example, suppose that you define a bean definition for a\n service object that (unknown to it) accesses a clustered\n-https://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the\n+{JSR}107[JCache], and you want to ensure that the\n named JCache instance is eagerly started within the surrounding cluster.\n The following listing shows such a definition:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\nindex 38bccafbe276..0752b210d7ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/appendix/xsd-schemas.adoc\n@@ -66,13 +66,13 @@ developer's intent (\"`inject this constant value`\"), and it reads better:\n [[xsd-schemas-util-frfb]]\n ==== Setting a Bean Property or Constructor Argument from a Field Value\n \n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically\n used for retrieving `public` `static` `final` constants, which may then be used to set a\n property value or constructor argument for another bean.\n \n The following example shows how a `static` field is exposed, by using the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String)[`staticField`]\n property:\n \n [source,xml,indent=0,subs=\"verbatim,quotes\"]\n@@ -109,7 +109,7 @@ to be specified for the bean reference, as the following example shows:\n \n You can also access a non-static (instance) field of another bean, as\n described in the API documentation for the\n-{api-spring-framework}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n+{spring-framework-api}/beans/factory/config/FieldRetrievingFactoryBean.html[`FieldRetrievingFactoryBean`]\n class.\n \n Injecting enumeration values into beans as either property or constructor arguments is\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\nindex c369aaa71514..5646f153fefb 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config.adoc\n@@ -17,7 +17,7 @@ No matter the choice, Spring can accommodate both styles and even mix them toget\n It is worth pointing out that through its xref:core/beans/java.adoc[JavaConfig] option, Spring lets\n annotations be used in a non-invasive way, without touching the target components'\n source code and that, in terms of tooling, all configuration styles are supported by\n-https://spring.io/tools[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n+{spring-site-tools}[Spring Tools] for Eclipse, Visual Studio Code, and Theia.\n ****\n \n An alternative to XML setup is provided by annotation-based configuration, which relies\n@@ -62,11 +62,11 @@ configuration (notice the inclusion of the `context` namespace):\n \n The `` element implicitly registers the following post-processors:\n \n-* {api-spring-framework}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n-* {api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n-* {api-spring-framework}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n+* {spring-framework-api}/context/annotation/ConfigurationClassPostProcessor.html[`ConfigurationClassPostProcessor`]\n+* {spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/annotation/CommonAnnotationBeanPostProcessor.html[`CommonAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html[`PersistenceAnnotationBeanPostProcessor`]\n+* {spring-framework-api}/context/event/EventListenerMethodProcessor.html[`EventListenerMethodProcessor`]\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\nindex 34d63d008483..0ca89cd0ab46 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/custom-autowire-configurer.adoc\n@@ -1,7 +1,7 @@\n [[beans-custom-autowire-configurer]]\n = Using `CustomAutowireConfigurer`\n \n-{api-spring-framework}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n+{spring-framework-api}/beans/factory/annotation/CustomAutowireConfigurer.html[`CustomAutowireConfigurer`]\n is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier\n annotation types, even if they are not annotated with Spring's `@Qualifier` annotation.\n The following example shows how to use `CustomAutowireConfigurer`:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\nindex b3457b78833b..370471e57d0e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/annotation-config/resource.adoc\n@@ -84,7 +84,7 @@ Kotlin::\n NOTE: The name provided with the annotation is resolved as a bean name by the\n `ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.\n The names can be resolved through JNDI if you configure Spring's\n-{api-spring-framework}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n+{spring-framework-api}/jndi/support/SimpleJndiBeanFactory.html[`SimpleJndiBeanFactory`]\n explicitly. However, we recommend that you rely on the default behavior and\n use Spring's JNDI lookup capabilities to preserve the level of indirection.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\nindex 57e51a6f1e9f..9c579a7c926a 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/basics.adoc\n@@ -12,8 +12,8 @@ between those objects.\n Several implementations of the `ApplicationContext` interface are supplied\n with Spring. In stand-alone applications, it is common to create an\n instance of\n-{api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n-or {api-spring-framework}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n+{spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+or {spring-framework-api}/context/support/FileSystemXmlApplicationContext.html[`FileSystemXmlApplicationContext`].\n While XML has been the traditional format for defining configuration metadata, you can\n instruct the container to use Java annotations or code as the metadata format by\n providing a small amount of XML configuration to declaratively enable support for these\n@@ -24,7 +24,7 @@ more instances of a Spring IoC container. For example, in a web application scen\n simple eight (or so) lines of boilerplate web descriptor XML in the `web.xml` file\n of the application typically suffices (see\n xref:core/beans/context-introduction.adoc#context-create[Convenient ApplicationContext Instantiation for Web Applications]).\n-If you use the https://spring.io/tools[Spring Tools for Eclipse] (an Eclipse-powered\n+If you use the {spring-site-tools}[Spring Tools for Eclipse] (an Eclipse-powered\n development environment), you can easily create this boilerplate configuration with a\n few mouse clicks or keystrokes.\n \n@@ -61,10 +61,10 @@ For information about using other forms of metadata with the Spring container, s\n annotation-based configuration metadata.\n * xref:core/beans/java.adoc[Java-based configuration]: define beans external to your application\n classes by using Java rather than XML files. To use these features, see the\n- {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],\n- {api-spring-framework}/context/annotation/Bean.html[`@Bean`],\n- {api-spring-framework}/context/annotation/Import.html[`@Import`],\n- and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n+ {spring-framework-api}/context/annotation/Configuration.html[`@Configuration`],\n+ {spring-framework-api}/context/annotation/Bean.html[`@Bean`],\n+ {spring-framework-api}/context/annotation/Import.html[`@Import`],\n+ and {spring-framework-api}/context/annotation/DependsOn.html[`@DependsOn`] annotations.\n \n Spring configuration consists of at least one and typically more than one bean\n definition that the container must manage. XML-based configuration metadata configures these\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\nindex c872157a60c9..85d354a82c6e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/classpath-scanning.adoc\n@@ -191,7 +191,7 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\n \n \n@@ -315,7 +315,7 @@ entries in the classpath. When you build JARs with Ant, make sure that you do no\n activate the files-only switch of the JAR task. Also, classpath directories may not be\n exposed based on security policies in some environments -- for example, standalone apps on\n JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests -- see\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n However, make sure that your component classes are exported in your `module-info`\n@@ -743,7 +743,7 @@ Kotlin::\n \n If you do not want to rely on the default bean-naming strategy, you can provide a custom\n bean-naming strategy. First, implement the\n-{api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n+{spring-framework-api}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`]\n interface, and be sure to include a default no-arg constructor. Then, provide the fully\n qualified class name when configuring the scanner, as the following example annotation\n and bean definition show.\n@@ -840,7 +840,7 @@ possibly also declaring a custom scoped-proxy mode.\n \n NOTE: To provide a custom strategy for scope resolution rather than relying on the\n annotation-based approach, you can implement the\n-{api-spring-framework}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n+{spring-framework-api}/context/annotation/ScopeMetadataResolver.html[`ScopeMetadataResolver`]\n interface. Be sure to include a default no-arg constructor. Then you can provide the\n fully qualified class name when configuring the scanner, as the following example of both\n an annotation and a bean definition shows:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\nindex 5fbc77c42b98..ac5192b0357f 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-introduction.adoc\n@@ -4,7 +4,7 @@\n As discussed in the xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[chapter introduction], the `org.springframework.beans.factory`\n package provides basic functionality for managing and manipulating beans, including in a\n programmatic way. The `org.springframework.context` package adds the\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n interface, which extends the `BeanFactory` interface, in addition to extending other\n interfaces to provide additional functionality in a more application\n framework-oriented style. Many people use the `ApplicationContext` in a completely\n@@ -269,7 +269,7 @@ file format but is more flexible than the standard JDK based\n `ResourceBundleMessageSource` implementation. In particular, it allows for reading\n files from any Spring resource location (not only from the classpath) and supports hot\n reloading of bundle property files (while efficiently caching them in between).\n-See the {api-spring-framework}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n+See the {spring-framework-api}/context/support/ReloadableResourceBundleMessageSource.html[`ReloadableResourceBundleMessageSource`]\n javadoc for details.\n \n \n@@ -485,8 +485,8 @@ This means that the `publishEvent()` method blocks until all listeners have fini\n One advantage of this synchronous and single-threaded approach is that, when a listener receives an event,\n it operates inside the transaction context of the publisher if a transaction context is available.\n If another strategy for event publication becomes necessary, e.g. asynchronous event processing by default,\n-see the javadoc for Spring's {api-spring-framework}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n-and {api-spring-framework}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n+see the javadoc for Spring's {spring-framework-api}/context/event/ApplicationEventMulticaster.html[`ApplicationEventMulticaster`] interface\n+and {spring-framework-api}/context/event/SimpleApplicationEventMulticaster.html[`SimpleApplicationEventMulticaster`] implementation\n for configuration options which can be applied to a custom \"applicationEventMulticaster\" bean definition.\n In these cases, ThreadLocals and logging context are not propagated for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -529,7 +529,7 @@ notify appropriate parties.\n NOTE: Spring's eventing mechanism is designed for simple communication between Spring beans\n within the same application context. However, for more sophisticated enterprise\n integration needs, the separately maintained\n-https://projects.spring.io/spring-integration/[Spring Integration] project provides\n+{spring-site-projects}/spring-integration/[Spring Integration] project provides\n complete support for building lightweight,\n https://www.enterpriseintegrationpatterns.com[pattern-oriented], event-driven\n architectures that build upon the well-known Spring programming model.\n@@ -742,11 +742,11 @@ Be aware of the following limitations when using asynchronous events:\n \n * If an asynchronous event listener throws an `Exception`, it is not propagated to the\n caller. See\n- {api-spring-framework}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n+ {spring-framework-api}/aop/interceptor/AsyncUncaughtExceptionHandler.html[`AsyncUncaughtExceptionHandler`]\n for more details.\n * Asynchronous event listener methods cannot publish a subsequent event by returning a\n value. If you need to publish another event as the result of the processing, inject an\n- {api-spring-framework}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n+ {spring-framework-api}/context/ApplicationEventPublisher.html[`ApplicationEventPublisher`]\n to publish the event manually.\n * ThreadLocals and logging context are not propagated by default for the event processing.\n See xref:integration/observability.adoc#observability.application-events[the `@EventListener` Observability section]\n@@ -1040,7 +1040,7 @@ and JMX support facilities. Application components can also interact with the ap\n server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.\n \n See the javadoc of the\n-{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n+{spring-framework-api}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]\n class for the configuration details involved in RAR deployment.\n \n For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:\n@@ -1050,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif\n file extension).\n . Add all required library JARs into the root of the RAR archive.\n . Add a\n-`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n+`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])\n and the corresponding Spring XML bean definition file(s) (typically\n `META-INF/applicationContext.xml`).\n . Drop the resulting RAR file into your\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\nindex 73579b414ded..25943592c078 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/context-load-time-weaver.adoc\n@@ -44,7 +44,7 @@ weaver instance. This is particularly useful in combination with\n xref:data-access/orm/jpa.adoc[Spring's JPA support] where load-time weaving may be\n necessary for JPA class transformation.\n Consult the\n-{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n+{spring-framework-api}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]\n javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\nindex 108202c40ac7..21b1f4a1f25e 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-method-injection.adoc\n@@ -99,7 +99,7 @@ container, lets you handle this use case cleanly.\n \n ****\n You can read more about the motivation for Method Injection in\n-https://spring.io/blog/2004/08/06/method-injection/[this blog entry].\n+{spring-site-blog}/2004/08/06/method-injection/[this blog entry].\n ****\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\nindex ae7874fa329f..a31499d5e267 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/dependencies/factory-properties-detailed.adoc\n@@ -51,7 +51,7 @@ XML configuration:\n \n The preceding XML is more succinct. However, typos are discovered at runtime rather than\n design time, unless you use an IDE (such as https://www.jetbrains.com/idea/[IntelliJ\n-IDEA] or the https://spring.io/tools[Spring Tools for Eclipse])\n+IDEA] or the {spring-site-tools}[Spring Tools for Eclipse])\n that supports automatic property completion when you create bean definitions. Such IDE\n assistance is highly recommended.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\nindex 571688d20c51..0e236078d4f1 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/environment.adoc\n@@ -1,7 +1,7 @@\n [[beans-environment]]\n = Environment Abstraction\n \n-The {api-spring-framework}/core/env/Environment.html[`Environment`] interface\n+The {spring-framework-api}/core/env/Environment.html[`Environment`] interface\n is an abstraction integrated in the container that models two key\n aspects of the application environment: xref:core/beans/environment.adoc#beans-definition-profiles[profiles]\n and xref:core/beans/environment.adoc#beans-property-source-abstraction[properties].\n@@ -118,7 +118,7 @@ situation B. We start by updating our configuration to reflect this need.\n [[beans-definition-profiles-java]]\n === Using `@Profile`\n \n-The {api-spring-framework}/context/annotation/Profile.html[`@Profile`]\n+The {spring-framework-api}/context/annotation/Profile.html[`@Profile`]\n annotation lets you indicate that a component is eligible for registration\n when one or more specified profiles are active. Using our preceding example, we\n can rewrite the `dataSource` configuration as follows:\n@@ -599,17 +599,17 @@ Kotlin::\n \n In the preceding snippet, we see a high-level way of asking Spring whether the `my-property` property is\n defined for the current environment. To answer this question, the `Environment` object performs\n-a search over a set of {api-spring-framework}/core/env/PropertySource.html[`PropertySource`]\n+a search over a set of {spring-framework-api}/core/env/PropertySource.html[`PropertySource`]\n objects. A `PropertySource` is a simple abstraction over any source of key-value pairs, and\n-Spring's {api-spring-framework}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n+Spring's {spring-framework-api}/core/env/StandardEnvironment.html[`StandardEnvironment`]\n is configured with two PropertySource objects -- one representing the set of JVM system properties\n (`System.getProperties()`) and one representing the set of system environment variables\n (`System.getenv()`).\n \n NOTE: These default property sources are present for `StandardEnvironment`, for use in standalone\n-applications. {api-spring-framework}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n+applications. {spring-framework-api}/web/context/support/StandardServletEnvironment.html[`StandardServletEnvironment`]\n is populated with additional default property sources including servlet config, servlet\n-context parameters, and a {api-spring-framework}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n+context parameters, and a {spring-framework-api}/jndi/JndiPropertySource.html[`JndiPropertySource`]\n if JNDI is available.\n \n Concretely, when you use the `StandardEnvironment`, the call to `env.containsProperty(\"my-property\")`\n@@ -663,7 +663,7 @@ Kotlin::\n In the preceding code, `MyPropertySource` has been added with highest precedence in the\n search. If it contains a `my-property` property, the property is detected and returned, in favor of\n any `my-property` property in any other `PropertySource`. The\n-{api-spring-framework}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n+{spring-framework-api}/core/env/MutablePropertySources.html[`MutablePropertySources`]\n API exposes a number of methods that allow for precise manipulation of the set of\n property sources.\n \n@@ -672,7 +672,7 @@ property sources.\n [[beans-using-propertysource]]\n == Using `@PropertySource`\n \n-The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]\n+The {spring-framework-api}/context/annotation/PropertySource.html[`@PropertySource`]\n annotation provides a convenient and declarative mechanism for adding a `PropertySource`\n to Spring's `Environment`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\nindex a82606dc0e9b..86d3a9911157 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc\n@@ -22,8 +22,8 @@ in which these `BeanPostProcessor` instances run by setting the `order` property\n You can set this property only if the `BeanPostProcessor` implements the `Ordered`\n interface. If you write your own `BeanPostProcessor`, you should consider implementing\n the `Ordered` interface, too. For further details, see the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n+{spring-framework-api}/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on\n xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].\n \n [NOTE]\n@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop\n However, you can only set this property if the `BeanFactoryPostProcessor` implements the\n `Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should\n consider implementing the `Ordered` interface, too. See the javadoc of the\n-{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n-and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.\n+{spring-framework-api}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]\n+and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces for more details.\n \n [NOTE]\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\nindex 8243d755d1e1..8d8e3d0ceab3 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/factory-scopes.adoc\n@@ -51,7 +51,7 @@ The following table describes the supported scopes:\n \n NOTE: A thread scope is available but is not registered by default. For more information,\n see the documentation for\n-{api-spring-framework}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n+{spring-framework-api}/context/support/SimpleThreadScope.html[`SimpleThreadScope`].\n For instructions on how to register this or any other custom scope, see\n xref:core/beans/factory-scopes.adoc#beans-factory-scopes-custom-using[Using a Custom Scope].\n \n@@ -559,7 +559,7 @@ To integrate your custom scopes into the Spring container, you need to implement\n `org.springframework.beans.factory.config.Scope` interface, which is described in this\n section. For an idea of how to implement your own scopes, see the `Scope`\n implementations that are supplied with the Spring Framework itself and the\n-{api-spring-framework}/beans/factory/config/Scope.html[`Scope`] javadoc,\n+{spring-framework-api}/beans/factory/config/Scope.html[`Scope`] javadoc,\n which explains the methods you need to implement in more detail.\n \n The `Scope` interface has four methods to get objects from the scope, remove them from\n@@ -629,7 +629,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n+See the {spring-framework-api}/beans/factory/config/Scope.html#registerDestructionCallback[javadoc]\n or a Spring scope implementation for more information on destruction callbacks.\n \n The following method obtains the conversation identifier for the underlying scope:\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\nindex 84fce22f428d..755192d355c4 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/introduction.adoc\n@@ -13,10 +13,10 @@ construction of classes or a mechanism such as the Service Locator pattern.\n \n The `org.springframework.beans` and `org.springframework.context` packages are the basis\n for Spring Framework's IoC container. The\n-{api-spring-framework}/beans/factory/BeanFactory.html[`BeanFactory`]\n+{spring-framework-api}/beans/factory/BeanFactory.html[`BeanFactory`]\n interface provides an advanced configuration mechanism capable of managing any type of\n object.\n-{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]\n+{spring-framework-api}/context/ApplicationContext.html[`ApplicationContext`]\n is a sub-interface of `BeanFactory`. It adds:\n \n * Easier integration with Spring's AOP features\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\nindex dd35cefa9d33..4e089707ac84 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/bean-annotation.adoc\n@@ -552,7 +552,7 @@ Sometimes, it is helpful to provide a more detailed textual description of a bea\n be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes.\n \n To add a description to a `@Bean`, you can use the\n-{api-spring-framework}/context/annotation/Description.html[`@Description`]\n+{spring-framework-api}/context/annotation/Description.html[`@Description`]\n annotation, as the following example shows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\nindex 638c8736b34f..11bdc1e25a87 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/composing-configuration-classes.adoc\n@@ -225,7 +225,7 @@ Also, be particularly careful with `BeanPostProcessor` and `BeanFactoryPostProce\n through `@Bean`. Those should usually be declared as `static @Bean` methods, not triggering the\n instantiation of their containing configuration class. Otherwise, `@Autowired` and `@Value` may not\n work on the configuration class itself, since it is possible to create it as a bean instance earlier than\n-{api-spring-framework}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n+{spring-framework-api}/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html[`AutowiredAnnotationBeanPostProcessor`].\n ====\n \n The following example shows how one bean can be autowired to another bean:\n@@ -338,7 +338,7 @@ modularity, but determining exactly where the autowired bean definitions are dec\n still somewhat ambiguous. For example, as a developer looking at `ServiceConfig`, how do\n you know exactly where the `@Autowired AccountRepository` bean is declared? It is not\n explicit in the code, and this may be just fine. Remember that the\n-https://spring.io/tools[Spring Tools for Eclipse] provides tooling that\n+{spring-site-tools}[Spring Tools for Eclipse] provides tooling that\n can render graphs showing how everything is wired, which may be all you need. Also,\n your Java IDE can easily find all declarations and uses of the `AccountRepository` type\n and quickly show you the location of `@Bean` methods that return that type.\n@@ -519,7 +519,7 @@ profile has been enabled in the Spring `Environment` (see xref:core/beans/enviro\n for details).\n \n The `@Profile` annotation is actually implemented by using a much more flexible annotation\n-called {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`].\n+called {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`].\n The `@Conditional` annotation indicates specific\n `org.springframework.context.annotation.Condition` implementations that should be\n consulted before a `@Bean` is registered.\n@@ -570,7 +570,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/annotation/Conditional.html[`@Conditional`]\n+See the {spring-framework-api}/context/annotation/Conditional.html[`@Conditional`]\n javadoc for more detail.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\nindex 3a1d9b9176cc..137bfe28398b 100644\n--- a/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/beans/java/instantiating-container.adoc\n@@ -278,7 +278,7 @@ init-param):\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\nindex a66ade956c27..afa9a50dc96a 100644\n--- a/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/databuffer-codec.adoc\n@@ -56,7 +56,7 @@ alternate between read and write.\n == `PooledDataBuffer`\n \n As explained in the Javadoc for\n-https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html[ByteBuffer],\n+{java-api}/java.base/java/nio/ByteBuffer.html[ByteBuffer],\n byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap\n which eliminates the need for copying for native I/O operations. That makes direct buffers\n particularly useful for receiving and sending data over a socket, but they're also more\ndiff --git a/framework-docs/modules/ROOT/pages/core/expressions.adoc b/framework-docs/modules/ROOT/pages/core/expressions.adoc\nindex 9b02cc49a82b..13aaedd89be8 100644\n--- a/framework-docs/modules/ROOT/pages/core/expressions.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/expressions.adoc\n@@ -11,7 +11,7 @@ EL, to name a few -- the Spring Expression Language was created to provide the S\n community with a single well supported expression language that can be used across all\n the products in the Spring portfolio. Its language features are driven by the\n requirements of the projects in the Spring portfolio, including tooling requirements\n-for code completion support within the https://spring.io/tools[Spring Tools for Eclipse].\n+for code completion support within the {spring-site-tools}[Spring Tools for Eclipse].\n That said, SpEL is based on a technology-agnostic API that lets other expression language\n implementations be integrated, should the need arise.\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/null-safety.adoc b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\nindex e43ad7d0f41b..8e2fe8ed42be 100644\n--- a/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/null-safety.adoc\n@@ -5,14 +5,14 @@ Although Java does not let you express null-safety with its type system, the Spr\n provides the following annotations in the `org.springframework.lang` package to let you\n declare nullability of APIs and fields:\n \n-* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n+* {spring-framework-api}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a\n specific parameter, return value, or field can be `null`.\n-* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n+* {spring-framework-api}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific\n parameter, return value, or field cannot be `null` (not needed on parameters, return values,\n and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).\n-* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n+* {spring-framework-api}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level\n that declares non-null as the default semantics for parameters and return values.\n-* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n+* {spring-framework-api}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package\n level that declares non-null as the default semantics for fields.\n \n The Spring Framework itself leverages these annotations, but they can also be used in any\n@@ -37,7 +37,7 @@ these annotations can be used by an IDE (such as IDEA or Eclipse) to provide use\n warnings related to null-safety in order to avoid `NullPointerException` at runtime.\n \n They are also used to make Spring APIs null-safe in Kotlin projects, since Kotlin natively\n-supports https://kotlinlang.org/docs/null-safety.html[null-safety]. More details\n+supports {kotlin-docs}/null-safety.html[null-safety]. More details\n are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support documentation].\n \n \n@@ -46,7 +46,7 @@ are available in the xref:languages/kotlin/null-safety.adoc[Kotlin support docum\n [[jsr-305-meta-annotations]]\n == JSR-305 meta-annotations\n \n-Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]\n+Spring annotations are meta-annotated with {JSR}305[JSR 305]\n annotations (a dormant but widespread JSR). JSR-305 meta-annotations let tooling vendors\n like IDEA or Kotlin provide null-safety support in a generic way, without having to\n hard-code support for Spring annotations.\ndiff --git a/framework-docs/modules/ROOT/pages/core/resources.adoc b/framework-docs/modules/ROOT/pages/core/resources.adoc\nindex 3bfc74aeb33f..5fd279ab5c66 100644\n--- a/framework-docs/modules/ROOT/pages/core/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/resources.adoc\n@@ -37,7 +37,7 @@ such as a method to check for the existence of the resource being pointed to.\n Spring's `Resource` interface located in the `org.springframework.core.io.` package is\n meant to be a more capable interface for abstracting access to low-level resources. The\n following listing provides an overview of the `Resource` interface. See the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc for further details.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc for further details.\n \n \n [source,java,indent=0,subs=\"verbatim,quotes\"]\n@@ -104,7 +104,7 @@ resource (if the underlying implementation is compatible and supports that\n functionality).\n \n Some implementations of the `Resource` interface also implement the extended\n-{api-spring-framework}/core/io/WritableResource.html[`WritableResource`] interface\n+{spring-framework-api}/core/io/WritableResource.html[`WritableResource`] interface\n for a resource that supports writing to it.\n \n Spring itself uses the `Resource` abstraction extensively, as an argument type in\n@@ -143,7 +143,7 @@ Spring includes several built-in `Resource` implementations:\n \n For a complete list of `Resource` implementations available in Spring, consult the\n \"All Known Implementing Classes\" section of the\n-{api-spring-framework}/core/io/Resource.html[`Resource`] javadoc.\n+{spring-framework-api}/core/io/Resource.html[`Resource`] javadoc.\n \n \n \n@@ -763,7 +763,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n+See the {spring-framework-api}/context/support/ClassPathXmlApplicationContext.html[`ClassPathXmlApplicationContext`]\n javadoc for details on the various constructors.\n \n \n@@ -903,7 +903,7 @@ entries in the classpath. When you build JARs with Ant, do not activate the `fil\n switch of the JAR task. Also, classpath directories may not get exposed based on security\n policies in some environments -- for example, stand-alone applications on JDK 1.7.0_45\n and higher (which requires 'Trusted-Library' to be set up in your manifests. See\n-https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).\n+{stackoverflow-questions}/19394570/java-jre-7u45-breaks-classloader-getresources).\n \n On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.\n Putting resources into a dedicated directory is highly recommendable here as well,\ndiff --git a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\nindex 768af0c34345..67e9d1d31756 100644\n--- a/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/spring-jcl.adoc\n@@ -9,7 +9,7 @@ known as _JUL_ or `java.util.logging`) if neither Log4j 2.x nor SLF4J is availab\n \n Put Log4j 2.x or Logback (or another SLF4J provider) in your classpath, without any extra\n bridges, and let the framework auto-adapt to your choice. For further information see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging[Spring\n+{spring-boot-docs}/features.html#features.logging[Spring\n Boot Logging Reference Documentation].\n \n [NOTE]\ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\nindex bc69769349c3..a68dbf43f8ac 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beans-beans.adoc\n@@ -51,7 +51,7 @@ A JavaBean is a class with a default no-argument constructor and that follows\n a naming convention where (for example) a property named `bingoMadness` would\n have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For\n more information about JavaBeans and the specification, see\n-https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[javabeans].\n+{java-api}/java.desktop/java/beans/package-summary.html[javabeans].\n \n One quite important class in the beans package is the `BeanWrapper` interface and its\n corresponding implementation (`BeanWrapperImpl`). As quoted from the javadoc, the\n@@ -249,7 +249,7 @@ behavior can be achieved by registering custom editors of type\n `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or,\n alternatively, in a specific IoC container (as mentioned in the previous chapter), gives it\n the knowledge of how to convert properties to the desired type. For more about\n-`PropertyEditor`, see https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n+`PropertyEditor`, see {java-api}/java.desktop/java/beans/package-summary.html[the javadoc of the `java.beans` package from Oracle].\n \n A couple of examples where property editing is used in Spring:\n \n@@ -355,7 +355,7 @@ com\n \n Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well\n (described to some extent\n-https://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[here]). The\n+{java-tutorial}/javabeans/advanced/customization.html[here]). The\n following example uses the `BeanInfo` mechanism to explicitly register one or more\n `PropertyEditor` instances with the properties of an associated class:\n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\nindex ef6bbb8630e8..387bf83192a6 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc\n@@ -2,7 +2,7 @@\n = Java Bean Validation\n \n The Spring Framework provides support for the\n-https://beanvalidation.org/[Java Bean Validation] API.\n+{bean-validation-site}[Java Bean Validation] API.\n \n \n \n@@ -72,7 +72,7 @@ Kotlin::\n ======\n \n A Bean Validation validator then validates instances of this class based on the declared\n-constraints. See https://beanvalidation.org/[Bean Validation] for general information about\n+constraints. See {bean-validation-site}[Bean Validation] for general information about\n the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for\n specific constraints. To learn how to set up a bean validation provider as a Spring\n bean, keep reading.\n@@ -317,7 +317,7 @@ XML::\n To be eligible for Spring-driven method validation, target classes need to be annotated\n with Spring's `@Validated` annotation, which can optionally also declare the validation\n groups to use. See\n-{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n+{spring-framework-api}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`]\n for setup details with the Hibernate Validator and Bean Validation providers.\n \n [TIP]\n@@ -472,7 +472,7 @@ Max.degrees=You cannot provide more than {1} {0}\n The default `LocalValidatorFactoryBean` configuration suffices for most\n cases. There are a number of configuration options for various Bean Validation\n constructs, from message interpolation to traversal resolution. See the\n-{api-spring-framework}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n+{spring-framework-api}/validation/beanvalidation/LocalValidatorFactoryBean.html[`LocalValidatorFactoryBean`]\n javadoc for more information on these options.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\nindex 49deddde0c33..37c62169572f 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/conversion.adoc\n@@ -19,8 +19,8 @@ of the field). This is done as a convenience to aid developers when targeting er\n \n More information on the `MessageCodesResolver` and the default strategy can be found\n in the javadoc of\n-{api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n-{api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n+{spring-framework-api}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and\n+{spring-framework-api}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`],\n respectively.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/format.adoc b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\nindex 920e2a44d970..4ac313d3f298 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/format.adoc\n@@ -139,7 +139,7 @@ Kotlin::\n ======\n \n The Spring team welcomes community-driven `Formatter` contributions. See\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues] to contribute.\n+{spring-framework-issues}[GitHub Issues] to contribute.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\nindex 8e3b060b54f1..17fa6402d3ba 100644\n--- a/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n+++ b/framework-docs/modules/ROOT/pages/core/validation/validator.adoc\n@@ -96,7 +96,7 @@ Kotlin::\n \n The `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to\n reject the `name` property if it is `null` or the empty string. Have a look at the\n-{api-spring-framework}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n+{spring-framework-api}/validation/ValidationUtils.html[`ValidationUtils`] javadoc\n to see what functionality it provides besides the example shown previously.\n \n While it is certainly possible to implement a single `Validator` class to validate each\n@@ -193,7 +193,7 @@ Kotlin::\n Validation errors are reported to the `Errors` object passed to the validator. In the case\n of Spring Web MVC, you can use the `` tag to inspect the error messages, but\n you can also inspect the `Errors` object yourself. More information about the\n-methods it offers can be found in the {api-spring-framework}/validation/Errors.html[javadoc].\n+methods it offers can be found in the {spring-framework-api}/validation/Errors.html[javadoc].\n \n Validators may also get locally invoked for the immediate validation of a given object,\n not involving a binding process. As of 6.1, this has been simplified through a new\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\nindex 7ebb4a44a68f..54d0c1243f61 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/connections.adoc\n@@ -199,7 +199,7 @@ participating in Spring managed transactions. It is generally preferable to writ\n own new code by using the higher level abstractions for resource management, such as\n `JdbcTemplate` or `DataSourceUtils`.\n \n-See the {api-spring-framework}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n+See the {spring-framework-api}/jdbc/datasource/TransactionAwareDataSourceProxy.html[`TransactionAwareDataSourceProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\nindex 60b6eea8fb96..a427ecc5fe93 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/core.adoc\n@@ -51,7 +51,7 @@ corresponding to the fully qualified class name of the template instance (typica\n \n The following sections provide some examples of `JdbcTemplate` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`.\n-See the attendant {api-spring-framework}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n+See the attendant {spring-framework-api}/jdbc/core/JdbcTemplate.html[javadoc] for that.\n \n [[jdbc-JdbcTemplate-examples-query]]\n === Querying (`SELECT`)\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\nindex eaa86da5f268..f9855a33c84d 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/jdbc/embedded-database-support.adoc\n@@ -83,7 +83,7 @@ Kotlin::\n ----\n ======\n \n-See the {api-spring-framework}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n+See the {spring-framework-api}/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.html[javadoc for `EmbeddedDatabaseBuilder`]\n for further details on all supported options.\n \n You can also use the `EmbeddedDatabaseBuilder` to create an embedded database by using Java\n@@ -288,7 +288,7 @@ You can extend Spring JDBC embedded database support in two ways:\n connection pool to manage embedded database connections.\n \n We encourage you to contribute extensions to the Spring community at\n-https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+{spring-framework-issues}[GitHub Issues].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\nindex bfb3e3c532ac..d44aca0c20d7 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/introduction.adoc\n@@ -58,8 +58,8 @@ The benefits of using the Spring Framework to create your ORM DAOs include:\n \n TIP: For more comprehensive ORM support, including support for alternative database\n technologies such as MongoDB, you might want to check out the\n-https://projects.spring.io/spring-data/[Spring Data] suite of projects. If you are\n-a JPA user, the https://spring.io/guides/gs/accessing-data-jpa/[Getting Started Accessing\n+{spring-site-projects}/spring-data/[Spring Data] suite of projects. If you are\n+a JPA user, the {spring-site-guides}/gs/accessing-data-jpa/[Getting Started Accessing\n Data with JPA] guide from https://spring.io provides a great introduction.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\nindex b9fc4279fc3f..9c7a0a4da7fb 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc\n@@ -157,7 +157,7 @@ The `LoadTimeWeaver` interface is a Spring-provided class that lets JPA\n `ClassTransformer` instances be plugged in a specific manner, depending on whether the\n environment is a web container or application server. Hooking `ClassTransformers`\n through an\n-https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agent]\n+{java-api}/java.instrument/java/lang/instrument/package-summary.html[agent]\n is typically not efficient. The agents work against the entire virtual machine and\n inspect every class that is loaded, which is usually undesirable in a production\n server environment.\n@@ -541,8 +541,8 @@ way of auto-configuring an `EntityManagerFactory` setup for Hibernate or Eclipse\n respectively. Note that those provider adapters are primarily designed for use with\n Spring-driven transaction management (that is, for use with `JpaTransactionManager`).\n \n-See the {api-spring-framework}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n-{api-spring-framework}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n+See the {spring-framework-api}/orm/jpa/JpaDialect.html[`JpaDialect`] and\n+{spring-framework-api}/orm/jpa/JpaVendorAdapter.html[`JpaVendorAdapter`] javadoc for\n more details of its operations and how they are used within Spring's JPA support.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\nindex 3cbe3a502e70..5bc8fcdfda96 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/oxm.adoc\n@@ -36,8 +36,8 @@ simpler.\n [[oxm-consistent-interfaces]]\n === Consistent Interfaces\n \n-Spring's O-X mapping operates through two global interfaces: {api-spring-framework}/oxm/Marshaller.html[`Marshaller`] and\n-{api-spring-framework}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n+Spring's O-X mapping operates through two global interfaces: {spring-framework-api}/oxm/Marshaller.html[`Marshaller`] and\n+{spring-framework-api}/oxm/Unmarshaller.html[`Unmarshaller`]. These abstractions let you switch O-X mapping frameworks\n with relative ease, with little or no change required on the classes that do the\n marshalling. This approach has the additional benefit of making it possible to do XML\n marshalling with a mix-and-match approach (for example, some marshalling performed using JAXB\n@@ -557,7 +557,7 @@ set the `supportedClasses` property on the `XStreamMarshaller`, as the following\n Doing so ensures that only the registered classes are eligible for unmarshalling.\n \n Additionally, you can register\n-{api-spring-framework}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n+{spring-framework-api}/oxm/xstream/XStreamMarshaller.html#setConverters(com.thoughtworks.xstream.converters.ConverterMatcher...)[custom\n converters] to make sure that only your supported classes can be unmarshalled. You might\n want to add a `CatchAllConverter` as the last converter in the list, in addition to\n converters that explicitly support the domain classes that should be supported. As a\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\nindex a4f7814a61f3..e75c0aac80f6 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/r2dbc.adoc\n@@ -95,7 +95,7 @@ parameter to database bind marker translation.\n run.\n * `\u2026.namedParameters(false)`: Disable named parameter expansion. Enabled by default.\n \n-TIP: Dialects are resolved by {api-spring-framework}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n+TIP: Dialects are resolved by {spring-framework-api}/r2dbc/core/binding/BindMarkersFactoryResolver.html[`BindMarkersFactoryResolver`]\n from a `ConnectionFactory`, typically by inspecting `ConnectionFactoryMetadata`.\n +\n You can let Spring auto-discover your `BindMarkersFactory` by registering a\n@@ -120,7 +120,7 @@ the reactive sequence to aid debugging.\n \n The following sections provide some examples of `DatabaseClient` usage. These examples\n are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`.\n-See the attendant {api-spring-framework}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n+See the attendant {spring-framework-api}/r2dbc/core/DatabaseClient.html[javadoc] for that.\n \n [[r2dbc-DatabaseClient-examples-statement]]\n ==== Executing Statements\n@@ -752,7 +752,7 @@ the same time, have this client participating in Spring managed transactions. It\n preferable to integrate a R2DBC client with proper access to `ConnectionFactoryUtils`\n for resource management.\n \n-See the {api-spring-framework}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n+See the {spring-framework-api}/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html[`TransactionAwareConnectionFactoryProxy`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\nindex eb94d9516959..4e865292cdd4 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc\n@@ -7,7 +7,7 @@ the JTA `UserTransaction` and `TransactionManager` objects) autodetects the loca\n the latter object, which varies by application server. Having access to the JTA\n `TransactionManager` allows for enhanced transaction semantics -- in particular,\n supporting transaction suspension. See the\n-{api-spring-framework}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n+{spring-framework-api}/transaction/jta/JtaTransactionManager.html[`JtaTransactionManager`]\n javadoc for details.\n \n Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\nindex 2ce54174913c..c8a83923b5cf 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc\n@@ -85,7 +85,7 @@ subclass-level annotation.\n When a POJO class such as the one above is defined as a bean in a Spring context,\n you can make the bean instance transactional through an `@EnableTransactionManagement`\n annotation in a `@Configuration` class. See the\n-{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n+{spring-framework-api}/transaction/annotation/EnableTransactionManagement.html[javadoc]\n for full details.\n \n In XML configuration, the `` tag provides similar convenience:\n@@ -262,7 +262,7 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.\n | XML Attribute| Annotation Attribute| Default| Description\n \n | `transaction-manager`\n-| N/A (see {api-spring-framework}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n+| N/A (see {spring-framework-api}/transaction/annotation/TransactionManagementConfigurer.html[`TransactionManagementConfigurer`] javadoc)\n | `transactionManager`\n | Name of the transaction manager to use. Required only if the name of the transaction\n manager is not `transactionManager`, as in the preceding example.\ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\nindex 58a65cafff62..af4de5b40077 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/aspectj.adoc\n@@ -57,8 +57,7 @@ transaction semantics given by the class annotation (if present). You can annota\n regardless of visibility.\n \n To weave your applications with the `AnnotationTransactionAspect`, you must either build\n-your application with AspectJ (see the\n-https://www.eclipse.org/aspectj/doc/released/devguide/index.html[AspectJ Development\n+your application with AspectJ (see the {aspectj-docs-devguide}/index.html[AspectJ Development\n Guide]) or use load-time weaving. See xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time weaving with AspectJ in the Spring Framework]\n for a discussion of load-time weaving with AspectJ.\n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\nindex cf4bceac371b..b41fd48f0d51 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc\n@@ -75,6 +75,6 @@ that it can roll back to. Such partial rollbacks let an inner transaction scope\n trigger a rollback for its scope, with the outer transaction being able to continue\n the physical transaction despite some operations having been rolled back. This setting\n is typically mapped onto JDBC savepoints, so it works only with JDBC resource\n-transactions. See Spring's {api-spring-framework}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n+transactions. See Spring's {spring-framework-api}/jdbc/datasource/DataSourceTransactionManager.html[`DataSourceTransactionManager`].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\nindex 8d34460168fe..62749a4d5842 100644\n--- a/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n+++ b/framework-docs/modules/ROOT/pages/data-access/transaction/event.adoc\n@@ -63,7 +63,7 @@ For the former, listeners are guaranteed to see the current thread-bound transac\n Since the latter uses the Reactor context instead of thread-local variables, the transaction\n context needs to be included in the published event instance as the event source.\n See the\n-{api-spring-framework}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n+{spring-framework-api}/transaction/reactive/TransactionalEventPublisher.html[`TransactionalEventPublisher`]\n javadoc for details.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/index.adoc b/framework-docs/modules/ROOT/pages/index.adoc\nindex a99335c230ea..8982e5b36060 100644\n--- a/framework-docs/modules/ROOT/pages/index.adoc\n+++ b/framework-docs/modules/ROOT/pages/index.adoc\n@@ -19,7 +19,7 @@ xref:integration.adoc[Integration] :: REST Clients, JMS, JCA, JMX,\n Email, Tasks, Scheduling, Caching, Observability, JVM Checkpoint Restore.\n xref:languages.adoc[Languages] :: Kotlin, Groovy, Dynamic Languages.\n xref:testing/appendix.adoc[Appendix] :: Spring properties.\n-https://github.com/spring-projects/spring-framework/wiki[Wiki] :: What's New,\n+{spring-framework-wiki}[Wiki] :: What's New,\n Upgrade Notes, Supported Versions, additional cross-version information.\n \n Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg,\ndiff --git a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\nindex aa1d408df829..a455ac6ef278 100644\n--- a/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc\n@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]\n+unexpected key collisions (see {spring-framework-issues}/14870[spring-framework#14870]\n for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.\n \n If you want to keep using the previous key strategy, you can configure the deprecated\n@@ -566,7 +566,7 @@ switching to `aspectj` mode in combination with compile-time or load-time weavin\n \n NOTE: For more detail about advanced customizations (using Java configuration) that are\n required to implement `CachingConfigurer`, see the\n-{api-spring-framework}/cache/annotation/CachingConfigurer.html[javadoc].\n+{spring-framework-api}/cache/annotation/CachingConfigurer.html[javadoc].\n \n [[cache-annotation-driven-settings]]\n .Cache annotation settings\n@@ -575,7 +575,7 @@ required to implement `CachingConfigurer`, see the\n | XML Attribute | Annotation Attribute | Default | Description\n \n | `cache-manager`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `cacheManager`\n | The name of the cache manager to use. A default `CacheResolver` is initialized behind\n the scenes with this cache manager (or `cacheManager` if not set). For more\n@@ -583,19 +583,19 @@ required to implement `CachingConfigurer`, see the\n attribute.\n \n | `cache-resolver`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | A `SimpleCacheResolver` using the configured `cacheManager`.\n | The bean name of the CacheResolver that is to be used to resolve the backing caches.\n This attribute is not required and needs to be specified only as an alternative to\n the 'cache-manager' attribute.\n \n | `key-generator`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleKeyGenerator`\n | Name of the custom key generator to use.\n \n | `error-handler`\n-| N/A (see the {api-spring-framework}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n+| N/A (see the {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`] javadoc)\n | `SimpleCacheErrorHandler`\n | The name of the custom cache error handler to use. By default, any exception thrown during\n a cache related operation is thrown back at the client.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/email.adoc b/framework-docs/modules/ROOT/pages/integration/email.adoc\nindex 610fda7c8797..1fa72f65161b 100644\n--- a/framework-docs/modules/ROOT/pages/integration/email.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/email.adoc\n@@ -26,7 +26,7 @@ interface. A simple value object that encapsulates the properties of a simple ma\n as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package\n also contains a hierarchy of checked exceptions that provide a higher level of\n abstraction over the lower level mail system exceptions, with the root exception being\n-`MailException`. See the {api-spring-framework}/mail/MailException.html[javadoc]\n+`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc]\n for more information on the rich mail exception hierarchy.\n \n The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\nindex edda9de3d387..a0ffb80fb0a3 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/annotated.adoc\n@@ -64,7 +64,7 @@ You can customize the listener container factory to use for each annotation or y\n configure an explicit default by implementing the `JmsListenerConfigurer` interface.\n The default is required only if at least one endpoint is registered without a specific\n container factory. See the javadoc of classes that implement\n-{api-spring-framework}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n+{spring-framework-api}/jms/annotation/JmsListenerConfigurer.html[`JmsListenerConfigurer`]\n for details and examples.\n \n If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the ``\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\nindex 23ce156526d3..70942ae58dd7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc\n@@ -64,9 +64,9 @@ In some environments, you can instead obtain the entire `ResourceAdapter` object\n (by using ``). The Spring-based message listeners can then interact with\n the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`.\n \n-See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n-{api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n-and {api-spring-framework}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n+See the javadoc for {spring-framework-api}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`],\n+{spring-framework-api}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`],\n+and {spring-framework-api}/jca/support/ResourceAdapterFactoryBean.html[`ResourceAdapterFactoryBean`]\n for more details.\n \n Spring also provides a generic JCA message endpoint manager that is not tied to JMS:\n@@ -74,7 +74,7 @@ Spring also provides a generic JCA message endpoint manager that is not tied to\n for using any message listener type (such as a JMS `MessageListener`) and any\n provider-specific `ActivationSpec` object. See your JCA provider's documentation to\n find out about the actual capabilities of your connector, and see the\n-{api-spring-framework}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n+{spring-framework-api}/jca/endpoint/GenericMessageEndpointManager.html[`GenericMessageEndpointManager`]\n javadoc for the Spring-specific configuration details.\n \n NOTE: JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\nindex be6cb7b45cbd..8ecda386a372 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/namespace.adoc\n@@ -113,7 +113,7 @@ as the following example shows:\n ----\n \n The following table describes all available attributes. See the class-level javadoc\n-of the {api-spring-framework}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n+of the {spring-framework-api}/jms/listener/AbstractMessageListenerContainer.html[`AbstractMessageListenerContainer`]\n and its concrete subclasses for more details on the individual properties. The javadoc\n also provides a discussion of transaction choices and message redelivery scenarios.\n \n@@ -254,7 +254,7 @@ The following table describes the available configuration options for the JCA va\n \n | `activation-spec-factory`\n | A reference to the `JmsActivationSpecFactory`. The default is to autodetect the JMS\n- provider and its `ActivationSpec` class (see {api-spring-framework}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n+ provider and its `ActivationSpec` class (see {spring-framework-api}/jms/listener/endpoint/DefaultJmsActivationSpecFactory.html[`DefaultJmsActivationSpecFactory`]).\n \n | `destination-resolver`\n | A reference to the `DestinationResolver` strategy for resolving JMS `Destinations`.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\nindex ff47edf51210..81388f3ae0f5 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/receiving.adoc\n@@ -76,7 +76,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine\n ----\n \n See the Spring javadoc of the various message listener containers (all of which implement\n-{api-spring-framework}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n+{spring-framework-api}/jms/listener/MessageListenerContainer.html[MessageListenerContainer])\n for a full description of the features supported by each implementation.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\nindex db342992e03e..027098cbc205 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jms/using.adoc\n@@ -234,7 +234,7 @@ use a proper cache level in such a case.\n This container also has recoverable capabilities when the broker goes down. By default,\n a simple `BackOff` implementation retries every five seconds. You can specify\n a custom `BackOff` implementation for more fine-grained recovery options. See\n-{api-spring-framework}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n+{spring-framework-api}/util/backoff/ExponentialBackOff.html[`ExponentialBackOff`] for an example.\n \n NOTE: Like its sibling (xref:integration/jms/using.adoc#jms-mdp-simple[`SimpleMessageListenerContainer`]),\n `DefaultMessageListenerContainer` supports native JMS transactions and allows for\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\nindex 78e197acbbb4..4811434a9c70 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/notifications.adoc\n@@ -246,7 +246,7 @@ instance. The `NotificationPublisherAware` interface supplies an instance of a\n which the bean can then use to publish `Notifications`.\n \n As stated in the javadoc of the\n-{api-spring-framework}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n+{spring-framework-api}/jmx/export/notification/NotificationPublisher.html[`NotificationPublisher`]\n interface, managed beans that publish events through the `NotificationPublisher`\n mechanism are not responsible for the state management of notification listeners.\n Spring's JMX support takes care of handling all the JMX infrastructure issues.\ndiff --git a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\nindex 369ccbf2c19c..7e6164bc86e6 100644\n--- a/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/jmx/resources.adoc\n@@ -6,10 +6,8 @@ This section contains links to further resources about JMX:\n \n * The https://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html[JMX\n homepage] at Oracle.\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html[JMX\n- specification] (JSR-000003).\n-* The https://jcp.org/aboutJava/communityprocess/final/jsr160/index.html[JMX Remote API\n- specification] (JSR-000160).\n+* The {JSR}003[JMX specification] (JSR-000003).\n+* The {JSR}160[JMX Remote API specification] (JSR-000160).\n * The http://mx4j.sourceforge.net/[MX4J homepage]. (MX4J is an open-source implementation of\n various JMX specs.)\n \ndiff --git a/framework-docs/modules/ROOT/pages/integration/observability.adoc b/framework-docs/modules/ROOT/pages/integration/observability.adoc\nindex 834cde1e30b8..13ca74ab1182 100644\n--- a/framework-docs/modules/ROOT/pages/integration/observability.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/observability.adoc\n@@ -7,7 +7,7 @@ Metrics can help you to track error rates, usage patterns, performance, and more\n Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.\n \n Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.\n-You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n+You can learn more about {spring-boot-docs}/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].\n \n \n [[observability.list]]\ndiff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\nindex 0ce1a984b00d..9350587756f7 100644\n--- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc\n@@ -344,7 +344,7 @@ The `spring-web` module contains the `HttpMessageConverter` interface for readin\n Concrete implementations for the main media (MIME) types are provided in the framework and are, by default, registered with the `RestClient` and `RestTemplate` on the client side and with `RequestMappingHandlerAdapter` on the server side (see xref:web/webmvc/mvc-config/message-converters.adoc[Configuring Message Converters]).\n \n Several implementations of `HttpMessageConverter` are described below.\n-Refer to the {api-spring-framework}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n+Refer to the {spring-framework-api}/http/converter/HttpMessageConverter.html[`HttpMessageConverter` Javadoc] for the complete list.\n For all converters, a default media type is used, but you can override it by setting the `supportedMediaTypes` property.\n \n [[rest-message-converters-tbl]]\n@@ -384,7 +384,7 @@ When you need further control (for cases where custom JSON serializers/deseriali\n By default, this converter supports `application/json`.\n \n | `MappingJackson2XmlHttpMessageConverter`\n-| An `HttpMessageConverter` implementation that can read and write XML by using https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n+| An `HttpMessageConverter` implementation that can read and write XML by using {jackson-github-org}/jackson-dataformat-xml[Jackson XML] extension's `XmlMapper`.\n You can customize XML mapping as needed through the use of JAXB or Jackson's provided annotations.\n When you need further control (for cases where custom XML serializers/deserializers need to be provided for specific types), you can inject a custom `XmlMapper` through the `ObjectMapper` property.\n By default, this converter supports `application/xml`.\n@@ -401,7 +401,7 @@ You can also set the message converters to use explicitly, by using `messageConv\n \n ==== Jackson JSON Views\n \n-To serialize only a subset of the object properties, you can specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n+To serialize only a subset of the object properties, you can specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON View], as the following example shows:\n \n [source,java,indent=0,subs=\"verbatim\"]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\nindex 344e365d34ae..cc8e0e2cd577 100644\n--- a/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n+++ b/framework-docs/modules/ROOT/pages/integration/scheduling.adoc\n@@ -282,8 +282,8 @@ You can pick and choose the relevant annotations for your application. For examp\n if you need only support for `@Scheduled`, you can omit `@EnableAsync`. For more\n fine-grained control, you can additionally implement the `SchedulingConfigurer`\n interface, the `AsyncConfigurer` interface, or both. See the\n-{api-spring-framework}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n-and {api-spring-framework}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n+{spring-framework-api}/scheduling/annotation/SchedulingConfigurer.html[`SchedulingConfigurer`]\n+and {spring-framework-api}/scheduling/annotation/AsyncConfigurer.html[`AsyncConfigurer`]\n javadoc for full details.\n \n If you prefer XML configuration, you can use the `` element,\n@@ -722,7 +722,7 @@ In the preceding configuration, a `queue-capacity` value has also been provided.\n The configuration of the thread pool should also be considered in light of the\n executor's queue capacity. For the full description of the relationship between pool\n size and queue capacity, see the documentation for\n-https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n+{java-api}/java.base/java/util/concurrent/ThreadPoolExecutor.html[`ThreadPoolExecutor`].\n The main idea is that, when a task is submitted, the executor first tries to use a\n free thread if the number of active threads is currently less than the core size.\n If the core size has been reached, the task is added to the queue, as long as its\n@@ -1093,7 +1093,7 @@ we need to set up the `SchedulerFactoryBean`, as the following example shows:\n \n More properties are available for the `SchedulerFactoryBean`, such as the calendars used by the\n job details, properties to customize Quartz with, and a Spring-provided JDBC DataSource. See\n-the {api-spring-framework}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n+the {spring-framework-api}/scheduling/quartz/SchedulerFactoryBean.html[`SchedulerFactoryBean`]\n javadoc for more information.\n \n NOTE: `SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\nindex c6beb7f4a6ca..4184525d7fb8 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin.adoc\n@@ -2,9 +2,9 @@\n = Kotlin\n :page-section-summary-toc: 1\n \n-https://kotlinlang.org[Kotlin] is a statically typed language that targets the JVM\n+{kotlin-site}[Kotlin] is a statically typed language that targets the JVM\n (and other platforms) which allows writing concise and elegant code while providing\n-very good https://kotlinlang.org/docs/reference/java-interop.html[interoperability]\n+very good {kotlin-docs}/java-interop.html[interoperability]\n with existing libraries written in Java.\n \n The Spring Framework provides first-class support for Kotlin and lets developers write\n@@ -13,13 +13,13 @@ Most of the code samples of the reference documentation are\n provided in Kotlin in addition to Java.\n \n The easiest way to build a Spring application with Kotlin is to leverage Spring Boot and\n-its https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-kotlin.html[dedicated Kotlin support].\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n+its{spring-boot-docs}/boot-features-kotlin.html[dedicated Kotlin support].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[This comprehensive tutorial]\n will teach you how to build Spring Boot applications with Kotlin using https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack]\n or ask a question with `spring` and `kotlin` as tags on\n-https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.\n+{stackoverflow-spring-kotlin-tags}[Stackoverflow] if you need support.\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\nindex 4a724caf0115..813d2c106b3b 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/annotations.adoc\n@@ -1,7 +1,7 @@\n [[kotlin-annotations]]\n = Annotations\n \n-The Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]\n+The Spring Framework also takes advantage of {kotlin-docs}/null-safety.html[Kotlin null-safety]\n to determine if an HTTP parameter is required without having to explicitly\n define the `required` attribute. That means `@RequestParam name: String?` is treated\n as not required and, conversely, `@RequestParam name: String` is treated as being required.\n@@ -20,9 +20,9 @@ type `Car` may or may not exist. The same behavior applies to autowired construc\n \n NOTE: If you use bean validation on classes with properties or a primary constructor\n parameters, you may need to use\n-https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets[annotation use-site targets],\n+{kotlin-docs}/annotations.html#annotation-use-site-targets[annotation use-site targets],\n such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in\n-https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].\n+{stackoverflow-site}/a/35853200/1092077[this Stack Overflow response].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\nindex 68949a9bf0bc..53ee46dd29c6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/bean-definition-dsl.adoc\n@@ -51,7 +51,7 @@ the constructor parameters will be autowired by type:\n ----\n \n In order to allow a more declarative approach and cleaner syntax, Spring Framework provides\n-a {docs-spring-framework}/kdoc-api/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n+a {spring-framework-api-kdoc}/spring-context/org.springframework.context.support/-bean-definition-dsl/index.html[Kotlin bean definition DSL]\n It declares an `ApplicationContextInitializer` through a clean declarative API,\n which lets you deal with profiles and `Environment` for customizing\n how beans are registered.\n@@ -104,10 +104,10 @@ as the following example shows:\n ----\n \n NOTE: Spring Boot is based on JavaConfig and\n-https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],\n+{spring-boot-issues}/8115[does not yet provide specific support for functional bean definition],\n but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.\n-See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n-for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].\n+See {stackoverflow-questions}/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]\n+for more details and up-to-date information. See also the experimental Kofu DSL developed in {spring-github-org}/spring-fu[Spring Fu incubator].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\nindex 5dd4520dd9f5..604563704a50 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/classes-interfaces.adoc\n@@ -12,7 +12,7 @@ compiler flag to be enabled during compilation. (For completeness, we neverthele\n running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)\n \n You can declare configuration classes as\n-https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],\n+{kotlin-docs}/nested-classes.html[top level or nested but not inner],\n since the later requires a reference to the outer class.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\nindex 17becb7aa151..ff64c052e542 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/coroutines.adoc\n@@ -1,21 +1,21 @@\n [[coroutines]]\n = Coroutines\n \n-Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin\n+Kotlin {kotlin-docs}/coroutines-overview.html[Coroutines] are Kotlin\n lightweight threads allowing to write non-blocking code in an imperative way. On language side,\n suspending functions provides an abstraction for asynchronous operations while on library side\n-https://github.com/Kotlin/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n-and types like https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n+{kotlin-github-org}/kotlinx.coroutines[kotlinx.coroutines] provides functions like\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/async.html[`async { }`]\n+and types like {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`].\n \n Spring Framework provides support for Coroutines on the following scope:\n \n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html[Deferred] and {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[Flow] return values support in Spring MVC and WebFlux annotated `@Controller`\n * Suspending function support in Spring MVC and WebFlux annotated `@Controller`\n-* Extensions for WebFlux {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n-* WebFlux.fn {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n+* Extensions for WebFlux {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.client/index.html[client] and {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/index.html[server] functional API.\n+* WebFlux.fn {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL\n * Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods\n-* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n+* Extensions for {spring-framework-api-kdoc}/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]\n \n \n \n@@ -53,17 +53,17 @@ For input parameters:\n * If laziness is not needed, `fun handler(mono: Mono)` becomes `fun handler(value: T)` since a suspending functions can be invoked to get the value parameter.\n * If laziness is needed, `fun handler(mono: Mono)` becomes `fun handler(supplier: suspend () -> T)` or `fun handler(supplier: suspend () -> T?)`\n \n-https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n+{kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html[`Flow`] is `Flux` equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:\n \n * `Flow` is push-based while `Flux` is push-pull hybrid\n * Backpressure is implemented via suspending functions\n-* `Flow` has only a https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as https://kotlinlang.org/docs/reference/extensions.html[extensions]\n-* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n+* `Flow` has only a {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html[single suspending `collect` method] and operators are implemented as {kotlin-docs}/extensions.html[extensions]\n+* {kotlin-github-org}/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators[Operators are easy to implement] thanks to Coroutines\n * Extensions allow to add custom operators to `Flow`\n * Collect operations are suspending functions\n-* https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n+* {kotlin-coroutines-api}/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html[`map` operator] supports asynchronous operation (no need for `flatMap`) since it takes a suspending function parameter\n \n-Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n+Read this blog post about {spring-site-blog}/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]\n for more details, including how to run code concurrently with Coroutines.\n \n \n@@ -170,7 +170,7 @@ class CoroutinesViewController(banner: Banner) {\n [[webflux-fn]]\n == WebFlux.fn\n \n-Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n+Here is an example of Coroutines router defined via the {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.\n \n [source,kotlin,indent=0]\n ----\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\nindex d7da3aee5328..6af9b086ae9f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/extensions.adoc\n@@ -1,11 +1,11 @@\n [[kotlin-extensions]]\n = Extensions\n \n-Kotlin https://kotlinlang.org/docs/reference/extensions.html[extensions] provide the ability\n+Kotlin {kotlin-docs}/extensions.html[extensions] provide the ability\n to extend existing classes with additional functionality. The Spring Framework Kotlin APIs\n use these extensions to add new Kotlin-specific conveniences to existing Spring APIs.\n \n-The {docs-spring-framework}/kdoc-api/[Spring Framework KDoc API] lists\n+The {spring-framework-api-kdoc}/[Spring Framework KDoc API] lists\n and documents all available Kotlin extensions and DSLs.\n \n NOTE: Keep in mind that Kotlin extensions need to be imported to be used. This means,\n@@ -13,8 +13,8 @@ for example, that the `GenericApplicationContext.registerBean` Kotlin extension\n is available only if `org.springframework.context.support.registerBean` is imported.\n That said, similar to static imports, an IDE should automatically suggest the import in most cases.\n \n-For example, https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n-provide a workaround for JVM https://docs.oracle.com/javase/tutorial/java/generics/erasure.html[generics type erasure],\n+For example, {kotlin-docs}/inline-functions.html#reified-type-parameters[Kotlin reified type parameters]\n+provide a workaround for JVM {java-tutorial}/java/generics/erasure.html[generics type erasure],\n and the Spring Framework provides some extensions to take advantage of this feature.\n This allows for a better Kotlin API `RestTemplate`, for the new `WebClient` from Spring\n WebFlux, and for various other APIs.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\nindex c53a37351ded..26cf9aa412b6 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/getting-started.adoc\n@@ -2,7 +2,7 @@\n = Getting Started\n \n The easiest way to learn how to build a Spring application with Kotlin is to follow\n-https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n+{spring-site-guides}/tutorials/spring-boot-kotlin/[the dedicated tutorial].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\nindex dc1a3f0257b8..96070d163f42 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/null-safety.adoc\n@@ -1,20 +1,20 @@\n [[kotlin-null-safety]]\n = Null-safety\n \n-One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety],\n+One of Kotlin's key features is {kotlin-docs}/null-safety.html[null-safety],\n which cleanly deals with `null` values at compile time rather than bumping into the famous\n `NullPointerException` at runtime. This makes applications safer through nullability\n declarations and expressing \"`value or no value`\" semantics without paying the cost of wrappers, such as `Optional`.\n (Kotlin allows using functional constructs with nullable values. See this\n-https://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n+{baeldung-blog}/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)\n \n Although Java does not let you express null-safety in its type-system, the Spring Framework\n provides xref:languages/kotlin/null-safety.adoc[null-safety of the whole Spring Framework API]\n via tooling-friendly annotations declared in the `org.springframework.lang` package.\n By default, types from Java APIs used in Kotlin are recognized as\n-https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types],\n+{kotlin-docs}/java-interop.html#null-safety-and-platform-types[platform types],\n for which null-checks are relaxed.\n-https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n+{kotlin-docs}/java-interop.html#jsr-305-support[Kotlin support for JSR-305 annotations]\n and Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,\n with the advantage of dealing with `null`-related issues at compile time.\n \n@@ -30,7 +30,7 @@ API nullability declaration could evolve even between minor releases and that mo\n be added in the future.\n \n NOTE: Generic type arguments, varargs, and array elements nullability are not supported yet,\n-but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]\n+but should be in an upcoming release. See {kotlin-github-org}/KEEP/issues/79[this discussion]\n for up-to-date information.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\nindex 80a2b48fc15a..19c0ae9e38bb 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/requirements.adoc\n@@ -9,9 +9,9 @@ and https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect[`kotli\n to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on\n https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].\n \n-WARNING: Kotlin https://kotlinlang.org/docs/inline-classes.html[inline classes] are not yet supported.\n+WARNING: Kotlin {kotlin-docs}/inline-classes.html[inline classes] are not yet supported.\n \n-NOTE: The https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] is required\n+NOTE: The {jackson-github-org}/jackson-module-kotlin[Jackson Kotlin module] is required\n for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the\n `com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.\n It is automatically registered when found in the classpath.\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\nindex a99666581818..567719b78dca 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/resources.adoc\n@@ -4,9 +4,9 @@\n We recommend the following resources for people learning how to build applications with\n Kotlin and the Spring Framework:\n \n-* https://kotlinlang.org/docs/reference/[Kotlin language reference]\n+* {kotlin-docs}[Kotlin language reference]\n * https://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel)\n-* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow, with `spring` and `kotlin` tags]\n+* {stackoverflow-spring-kotlin-tags}[Stackoverflow, with `spring` and `kotlin` tags]\n * https://play.kotlinlang.org/[Try Kotlin in your browser]\n * https://blog.jetbrains.com/kotlin/[Kotlin blog]\n * https://kotlin.link/[Awesome Kotlin]\n@@ -34,12 +34,12 @@ The following Github projects offer examples that you can learn from and possibl\n The following list categorizes the pending issues related to Spring and Kotlin support:\n \n * Spring Framework\n-** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]\n-** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]\n+** {spring-framework-issues}/20606[Unable to use WebTestClient with mock server in Kotlin]\n+** {spring-framework-issues}/20496[Support null-safety at generics, varargs and array elements level]\n * Kotlin\n-** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]\n-** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]\n-** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]\n-** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]\n-** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]\n-** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]\n+** {kotlin-issues}/KT-6380[Parent issue for Spring Framework support]\n+** {kotlin-issues}/KT-5464[Kotlin requires type inference where Java doesn't]\n+** {kotlin-issues}/KT-20283[Smart cast regression with open classes]\n+** {kotlin-issues}/KT-14984[Impossible to pass not all SAM argument as function]\n+** {kotlin-issues}/KT-15125[Support JSR 223 bindings directly via script variables]\n+** {kotlin-issues}/KT-6653[Kotlin properties do not override Java-style getters and setters]\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\nindex c8fc3c84597f..b3d4329ef227 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/spring-projects-in.adoc\n@@ -21,10 +21,10 @@ member function of Spring beans that are proxied by CGLIB, which can\n quickly become painful and is against the Kotlin principle of keeping code concise and predictable.\n \n NOTE: It is also possible to avoid CGLIB proxies for configuration classes by using `@Configuration(proxyBeanMethods = false)`.\n-See {api-spring-framework}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n+See {spring-framework-api}/context/annotation/Configuration.html#proxyBeanMethods--[`proxyBeanMethods` Javadoc] for more details.\n \n Fortunately, Kotlin provides a\n-https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n+{kotlin-docs}/compiler-plugins.html#kotlin-spring-compiler-plugin[`kotlin-spring`]\n plugin (a preconfigured version of the `kotlin-allopen` plugin) that automatically opens classes\n and their member functions for types that are annotated or meta-annotated with one of the following\n annotations:\n@@ -59,7 +59,7 @@ within the primary constructor, as in the following example:\n \tclass Person(val name: String, val age: Int)\n ----\n \n-You can optionally add https://kotlinlang.org/docs/reference/data-classes.html[the `data` keyword]\n+You can optionally add {kotlin-docs}/data-classes.html[the `data` keyword]\n to make the compiler automatically derive the following members from all properties declared\n in the primary constructor:\n \n@@ -80,12 +80,12 @@ As the following example shows, this allows for easy changes to individual prope\n \n Common persistence technologies (such as JPA) require a default constructor, preventing this\n kind of design. Fortunately, there is a workaround for this\n-https://stackoverflow.com/questions/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n-since Kotlin provides a https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n+{stackoverflow-questions}/32038177/kotlin-with-jpa-default-constructor-hell[\"`default constructor hell`\"],\n+since Kotlin provides a {kotlin-docs}/compiler-plugins.html#kotlin-jpa-compiler-plugin[`kotlin-jpa`]\n plugin that generates synthetic no-arg constructor for classes annotated with JPA annotations.\n \n If you need to leverage this kind of mechanism for other persistence technologies, you can configure\n-the https://kotlinlang.org/docs/reference/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n+the {kotlin-docs}/compiler-plugins.html#how-to-use-no-arg-plugin[`kotlin-noarg`]\n plugin.\n \n NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class instances and\n@@ -98,7 +98,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object\n == Injecting Dependencies\n \n Our recommendation is to try to favor constructor injection with `val` read-only (and\n-non-nullable when possible) https://kotlinlang.org/docs/reference/properties.html[properties],\n+non-nullable when possible) {kotlin-docs}/properties.html[properties],\n as the following example shows:\n \n [source,kotlin,indent=0]\n@@ -137,13 +137,13 @@ as the following example shows:\n \n In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value(\"${property}\")`)].\n However, in Kotlin, `$` is a reserved character that is used for\n-https://kotlinlang.org/docs/reference/idioms.html#string-interpolation[string interpolation].\n+{kotlin-docs}/idioms.html#string-interpolation[string interpolation].\n \n Therefore, if you wish to use the `@Value` annotation in Kotlin, you need to escape the `$`\n character by writing pass:q[`@Value(\"\\${property}\")`].\n \n NOTE: If you use Spring Boot, you should probably use\n-https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n+{spring-boot-docs}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[`@ConfigurationProperties`]\n instead of `@Value` annotations.\n \n As an alternative, you can customize the property placeholder prefix by declaring the\n@@ -177,14 +177,14 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl\n [[checked-exceptions]]\n == Checked Exceptions\n \n-Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]\n+Java and {kotlin-docs}/exceptions.html[Kotlin exception handling]\n are pretty close, with the main difference being that Kotlin treats all exceptions as\n unchecked exceptions. However, when using proxied objects (for example classes or methods\n annotated with `@Transactional`), checked exceptions thrown will be wrapped by default in\n an `UndeclaredThrowableException`.\n \n To get the original exception thrown like in Java, methods should be annotated with\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n+{kotlin-api}/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]\n to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).\n \n \n@@ -194,7 +194,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce\n \n Kotlin annotations are mostly similar to Java annotations, but array attributes (which are\n extensively used in Spring) behave differently. As explained in the\n-https://kotlinlang.org/docs/reference/annotations.html[Kotlin documentation] you can omit\n+{kotlin-docs}/annotations.html[Kotlin documentation] you can omit\n the `value` attribute name, unlike other attributes, and specify it as a `vararg` parameter.\n \n To understand what that means, consider `@RequestMapping` (which is one of the most widely\n@@ -240,13 +240,13 @@ be matched, not only the `GET` method.\n == Declaration-site variance\n \n Dealing with generic types in Spring applications written in Kotlin may require, for some use cases, to understand\n-Kotlin https://kotlinlang.org/docs/generics.html#declaration-site-variance[declaration-site variance]\n+Kotlin {kotlin-docs}/generics.html#declaration-site-variance[declaration-site variance]\n which allows to define the variance when declaring a type, which is not possible in Java which supports only use-site\n variance.\n \n For example, declaring `List` in Kotlin is conceptually equivalent to `java.util.List` because\n `kotlin.collections.List` is declared as\n-https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n+{kotlin-api}/jvm/stdlib/kotlin.collections/-list/[`interface List : kotlin.collections.Collection`].\n \n This needs to be taken into account by using the `out` Kotlin keyword on generic types when using Java classes,\n for example when writing a `org.springframework.core.convert.converter.Converter` from a Kotlin type to a Java type.\n@@ -267,7 +267,7 @@ class ListOfAnyConverter : Converter, CustomJavaList<*>> {\n ----\n \n NOTE: Spring Framework does not leverage yet declaration-site variance type information for injecting beans,\n-subscribe to https://github.com/spring-projects/spring-framework/issues/22313[spring-framework#22313] to track related\n+subscribe to {spring-framework-issues}/22313[spring-framework#22313] to track related\n progresses.\n \n \n@@ -280,7 +280,7 @@ The recommended testing framework is https://junit.org/junit5/[JUnit 5] along wi\n https://mockk.io/[Mockk] for mocking.\n \n NOTE: If you are using Spring Boot, see\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].\n+{spring-boot-docs}/features.html#features.kotlin.testing[this related documentation].\n \n \n [[constructor-injection]]\n@@ -289,7 +289,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-featu\n As described in the xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[dedicated section],\n JUnit Jupiter (JUnit 5) allows constructor injection of beans which is pretty useful with Kotlin\n in order to use `val` instead of `lateinit var`. You can use\n-{api-spring-framework}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n+{spring-framework-api}/test/context/TestConstructor.html[`@TestConstructor(autowireMode = AutowireMode.ALL)`]\n to enable autowiring for all parameters.\n \n NOTE: You can also change the default behavior to `ALL` in a `junit-platform.properties`\ndiff --git a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\nindex 0b44ce3c7432..459b49103a5f 100644\n--- a/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n+++ b/framework-docs/modules/ROOT/pages/languages/kotlin/web.adoc\n@@ -8,9 +8,9 @@\n \n Spring Framework comes with a Kotlin router DSL available in 3 flavors:\n \n-* WebMvc.fn DSL with {docs-spring-framework}/kdoc-api/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n-* WebFlux.fn <> DSL with {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n+* WebMvc.fn DSL with {spring-framework-api-kdoc}/spring-webmvc/org.springframework.web.servlet.function/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/router.html[router { }]\n+* WebFlux.fn <> DSL with {spring-framework-api-kdoc}/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }]\n \n These DSL let you write clean and idiomatic Kotlin code to build a `RouterFunction` instance as the following example shows:\n \n@@ -79,12 +79,12 @@ mockMvc.get(\"/person/{name}\", \"Lee\") {\n == Kotlin Script Templates\n \n Spring Framework provides a\n-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n-which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.\n+{spring-framework-api}/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]\n+which supports {JSR}223[JSR-223] to render templates by using script engines.\n \n By leveraging `scripting-jsr223` dependencies, it\n is possible to use such feature to render Kotlin-based templates with\n-https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n+{kotlin-github-org}/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.\n \n `build.gradle.kts`\n [source,kotlin,indent=0]\n@@ -126,10 +126,10 @@ project for more details.\n [[kotlin-multiplatform-serialization]]\n == Kotlin multiplatform serialization\n \n-As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is\n+As of Spring Framework 5.3, {kotlin-github-org}/kotlinx.serialization[Kotlin multiplatform serialization] is\n supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently targets CBOR, JSON, and ProtoBuf formats.\n \n-To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n+To enable it, follow {kotlin-github-org}/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.\n With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since\n Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.\n With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,\ndiff --git a/framework-docs/modules/ROOT/pages/overview.adoc b/framework-docs/modules/ROOT/pages/overview.adoc\nindex b0ed76a7d869..cb03d79d9c0d 100644\n--- a/framework-docs/modules/ROOT/pages/overview.adoc\n+++ b/framework-docs/modules/ROOT/pages/overview.adoc\n@@ -57,18 +57,18 @@ competition with Spring, they are in fact complementary. The Spring programming\n model does not embrace the Jakarta EE platform specification; rather, it integrates\n with carefully selected individual specifications from the traditional EE umbrella:\n \n-* Servlet API (https://jcp.org/en/jsr/detail?id=340[JSR 340])\n-* WebSocket API (https://www.jcp.org/en/jsr/detail?id=356[JSR 356])\n-* Concurrency Utilities (https://www.jcp.org/en/jsr/detail?id=236[JSR 236])\n-* JSON Binding API (https://jcp.org/en/jsr/detail?id=367[JSR 367])\n-* Bean Validation (https://jcp.org/en/jsr/detail?id=303[JSR 303])\n-* JPA (https://jcp.org/en/jsr/detail?id=338[JSR 338])\n-* JMS (https://jcp.org/en/jsr/detail?id=914[JSR 914])\n+* Servlet API ({JSR}340[JSR 340])\n+* WebSocket API ({JSR}356[JSR 356])\n+* Concurrency Utilities ({JSR}236[JSR 236])\n+* JSON Binding API ({JSR}367[JSR 367])\n+* Bean Validation ({JSR}303[JSR 303])\n+* JPA ({JSR}338[JSR 338])\n+* JMS ({JSR}914[JSR 914])\n * as well as JTA/JCA setups for transaction coordination, if necessary.\n \n The Spring Framework also supports the Dependency Injection\n-(https://www.jcp.org/en/jsr/detail?id=330[JSR 330]) and Common Annotations\n-(https://jcp.org/en/jsr/detail?id=250[JSR 250]) specifications, which application\n+({JSR}330[JSR 330]) and Common Annotations\n+({JSR}250[JSR 250]) specifications, which application\n developers may choose to use instead of the Spring-specific mechanisms provided\n by the Spring Framework. Originally, those were based on common `javax` packages.\n \n@@ -89,7 +89,7 @@ and can run on servers (such as Netty) that are not Servlet containers.\n Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other\n projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch,\n among others. It\u2019s important to remember that each project has its own source code repository,\n-issue tracker, and release cadence. See https://spring.io/projects[spring.io/projects] for\n+issue tracker, and release cadence. See {spring-site-projects}[spring.io/projects] for\n the complete list of Spring projects.\n \n \n@@ -125,17 +125,17 @@ clean code structure with no circular dependencies between packages.\n == Feedback and Contributions\n \n For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click\n-https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n+{stackoverflow-spring-tag}+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest[here]\n for a list of the suggested tags to use on Stack Overflow. If you're fairly certain that\n there is a problem in the Spring Framework or would like to suggest a feature, please use\n-the https://github.com/spring-projects/spring-framework/issues[GitHub Issues].\n+the {spring-framework-issues}[GitHub Issues].\n \n If you have a solution in mind or a suggested fix, you can submit a pull request on\n-https://github.com/spring-projects/spring-framework[Github]. However, please keep in mind\n+{spring-framework-github}[Github]. However, please keep in mind\n that, for all but the most trivial issues, we expect a ticket to be filed in the issue\n tracker, where discussions take place and leave a record for future reference.\n \n-For more details see the guidelines at the {spring-framework-main-code}/CONTRIBUTING.md[CONTRIBUTING],\n+For more details see the guidelines at the {spring-framework-code}/CONTRIBUTING.md[CONTRIBUTING],\n top-level project page.\n \n \n@@ -145,15 +145,15 @@ top-level project page.\n == Getting Started\n \n If you are just getting started with Spring, you may want to begin using the Spring\n-Framework by creating a https://projects.spring.io/spring-boot/[Spring Boot]-based\n+Framework by creating a {spring-site-projects}/spring-boot/[Spring Boot]-based\n application. Spring Boot provides a quick (and opinionated) way to create a\n production-ready Spring-based application. It is based on the Spring Framework, favors\n convention over configuration, and is designed to get you up and running as quickly\n as possible.\n \n You can use https://start.spring.io/[start.spring.io] to generate a basic project or follow\n-one of the https://spring.io/guides[\"Getting Started\" guides], such as\n-https://spring.io/guides/gs/rest-service/[Getting Started Building a RESTful Web Service].\n+one of the {spring-site-guides}[\"Getting Started\" guides], such as\n+{spring-site-guides}/gs/rest-service/[Getting Started Building a RESTful Web Service].\n As well as being easier to digest, these guides are very task focused, and most of them\n are based on Spring Boot. They also cover other projects from the Spring portfolio that\n you might want to consider when solving a particular problem.\ndiff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc\nindex 86846ae5cfdd..402c213898df 100644\n--- a/framework-docs/modules/ROOT/pages/rsocket.adoc\n+++ b/framework-docs/modules/ROOT/pages/rsocket.adoc\n@@ -23,7 +23,7 @@ while the above interactions are called \"request streams\" or simply \"requests\".\n \n These are the key features and benefits of the RSocket protocol:\n \n-* https://www.reactive-streams.org/[Reactive Streams] semantics across network boundary --\n+* {reactive-streams-site}/[Reactive Streams] semantics across network boundary --\n for streaming requests such as `Request-Stream` and `Channel`, back pressure signals\n travel between requester and responder, allowing a requester to slow down a responder at\n the source, hence reducing reliance on network layer congestion control, and the need\n@@ -38,9 +38,9 @@ the amount of state required.\n * Fragmentation and re-assembly of large messages.\n * Keepalive (heartbeats).\n \n-RSocket has {gh-rsocket}[implementations] in multiple languages. The\n-{gh-rsocket-java}[Java library] is built on https://projectreactor.io/[Project Reactor],\n-and https://github.com/reactor/reactor-netty[Reactor Netty] for the transport. That means\n+RSocket has {rsocket-github-org}[implementations] in multiple languages. The\n+{rsocket-java}[Java library] is built on {reactor-site}/[Project Reactor],\n+and {reactor-github-org}/reactor-netty[Reactor Netty] for the transport. That means\n signals from Reactive Streams Publishers in your application propagate transparently\n through RSocket across the network.\n \n@@ -50,8 +50,8 @@ through RSocket across the network.\n === The Protocol\n \n One of the benefits of RSocket is that it has well defined behavior on the wire and an\n-easy to read https://rsocket.io/about/protocol[specification] along with some protocol\n-{gh-rsocket}/rsocket/tree/master/Extensions[extensions]. Therefore it is\n+easy to read {rsocket-site}/about/protocol[specification] along with some protocol\n+{rsocket-protocol-extensions}[extensions]. Therefore it is\n a good idea to read the spec, independent of language implementations and higher level\n framework APIs. This section provides a succinct overview to establish some context.\n \n@@ -96,18 +96,18 @@ and therefore only included in the first message on a request, i.e. with one of\n \n Protocol extensions define common metadata formats for use in applications:\n \n-* {gh-rsocket-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n+* {rsocket-protocol-extensions}/CompositeMetadata.md[Composite Metadata]-- multiple,\n independently formatted metadata entries.\n-* {gh-rsocket-extensions}/Routing.md[Routing] -- the route for a request.\n+* {rsocket-protocol-extensions}/Routing.md[Routing] -- the route for a request.\n \n \n \n [[rsocket-java]]\n === Java Implementation\n \n-The {gh-rsocket-java}[Java implementation] for RSocket is built on\n-https://projectreactor.io/[Project Reactor]. The transports for TCP and WebSocket are\n-built on https://github.com/reactor/reactor-netty[Reactor Netty]. As a Reactive Streams\n+The {rsocket-java}[Java implementation] for RSocket is built on\n+{reactor-site}/[Project Reactor]. The transports for TCP and WebSocket are\n+built on {reactor-github-org}/reactor-netty[Reactor Netty]. As a Reactive Streams\n library, Reactor simplifies the job of implementing the protocol. For applications it is\n a natural fit to use `Flux` and `Mono` with declarative operators and transparent back\n pressure support.\n@@ -117,7 +117,7 @@ features and leaves the application programming model (e.g. RPC codegen vs other\n higher level, independent concern.\n \n The main contract\n-{gh-rsocket-java}/blob/master/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n+{rsocket-java-code}/rsocket-core/src/main/java/io/rsocket/RSocket.java[io.rsocket.RSocket]\n models the four request interaction types with `Mono` representing a promise for a\n single message, `Flux` a stream of messages, and `io.rsocket.Payload` the actual\n message with access to data and metadata as byte buffers. The `RSocket` contract is used\n@@ -127,7 +127,7 @@ requests with. For responding, the application implements `RSocket` to handle re\n This is not meant to be a thorough introduction. For the most part, Spring applications\n will not have to use its API directly. However it may be important to see or experiment\n with RSocket independent of Spring. The RSocket Java repository contains a number of\n-{gh-rsocket-java}/tree/master/rsocket-examples[sample apps] that\n+{rsocket-java-code}/rsocket-examples[sample apps] that\n demonstrate its API and protocol features.\n \n \n@@ -152,7 +152,7 @@ Spring Boot 2.2 supports standing up an RSocket server over TCP or WebSocket, in\n the option to expose RSocket over WebSocket in a WebFlux server. There is also client\n support and auto-configuration for an `RSocketRequester.Builder` and `RSocketStrategies`.\n See the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-rsocket[RSocket section]\n+{spring-boot-docs}/messaging.html#messaging.rsocket[RSocket section]\n in the Spring Boot reference for more details.\n \n Spring Security 5.2 provides RSocket support.\n@@ -222,7 +222,7 @@ established transparently and used.\n \n For data, the default mime type is derived from the first configured `Decoder`. For\n metadata, the default mime type is\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] which allows multiple\n metadata value and mime type pairs per request. Typically both don't need to be changed.\n \n Data and metadata in the `SETUP` frame is optional. On the server side,\n@@ -534,7 +534,7 @@ Kotlin::\n ======\n \n Extra metadata values can be added if using\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite metadata] (the default) and if the\n values are supported by a registered `Encoder`. For example:\n \n [tabs]\n@@ -663,8 +663,8 @@ Kotlin::\n ======\n \n `RSocketMessageHandler` supports\n-{gh-rsocket-extensions}/CompositeMetadata.md[composite] and\n-{gh-rsocket-extensions}/Routing.md[routing] metadata by default. You can set its\n+{rsocket-protocol-extensions}/CompositeMetadata.md[composite] and\n+{rsocket-protocol-extensions}/Routing.md[routing] metadata by default. You can set its\n xref:rsocket.adoc#rsocket-metadata-extractor[MetadataExtractor] if you need to switch to a\n different mime type or register additional metadata mime types.\n \n@@ -954,7 +954,7 @@ xref:rsocket.adoc#rsocket-requester-server[Server Requester] for details.\n == MetadataExtractor\n \n Responders must interpret metadata.\n-{gh-rsocket-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n+{rsocket-protocol-extensions}/CompositeMetadata.md[Composite metadata] allows independently\n formatted metadata values (e.g. for routing, security, tracing) each with its own mime\n type. Applications need a way to configure metadata mime types to support, and a way\n to access extracted values.\n@@ -965,7 +965,7 @@ in annotated handler methods.\n \n `DefaultMetadataExtractor` can be given `Decoder` instances to decode metadata. Out of\n the box it has built-in support for\n-{gh-rsocket-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n+{rsocket-protocol-extensions}/Routing.md[\"message/x.rsocket.routing.v0\"] which it decodes to\n `String` and saves under the \"route\" key. For any other mime type you'll need to provide\n a `Decoder` and register the mime type as follows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\nindex 3bc6e18d1a2c..4944779c3b44 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit-jupiter.adoc\n@@ -82,7 +82,7 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n+{spring-framework-api}/test/context/junit/jupiter/SpringJUnitConfig.html[`@SpringJUnitConfig`]\n and `@ContextConfiguration` for further details.\n \n [[integration-testing-annotations-junit-jupiter-springjunitwebconfig]]\n@@ -157,9 +157,9 @@ Kotlin::\n \n \n See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] as well as the javadoc for\n-{api-spring-framework}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n-{api-spring-framework}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/junit/jupiter/web/SpringJUnitWebConfig.html[`@SpringJUnitWebConfig`],\n+{spring-framework-api}/test/context/ContextConfiguration.html[`@ContextConfiguration`], and\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n for further details.\n \n [[integration-testing-annotations-testconstructor]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\nindex 20bb7976d6a0..78164ab07744 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-meta.adoc\n@@ -305,5 +305,5 @@ Kotlin::\n ======\n \n For further details, see the\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n+{spring-framework-wiki}/Spring-Annotation-Programming-Model[Spring Annotation Programming Model]\n wiki page.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\nindex 6b3d521b492b..31299b96bd07 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-activeprofiles.adoc\n@@ -74,6 +74,6 @@ and registering it by using the `resolver` attribute of `@ActiveProfiles`.\n \n See xref:testing/testcontext-framework/ctx-management/env-profiles.adoc[Context Configuration with Environment Profiles],\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration], and the\n-{api-spring-framework}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n+{spring-framework-api}/test/context/ActiveProfiles.html[`@ActiveProfiles`] javadoc for\n examples and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\nindex 497ef55afe12..0dc49e7bec52 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc\n@@ -40,6 +40,6 @@ Kotlin::\n By default, `@ContextCustomizerFactories` provides support for inheriting factories from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\nindex f136a4da5c99..66aedbcb9fd0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-contexthierarchy.adoc\n@@ -70,6 +70,6 @@ If you need to merge or override the configuration for a given level of the cont\n hierarchy within a test class hierarchy, you must explicitly name that level by supplying\n the same value to the `name` attribute in `@ContextConfiguration` at each corresponding\n level in the class hierarchy. See xref:testing/testcontext-framework/ctx-management/hierarchies.adoc[Context Hierarchies] and the\n-{api-spring-framework}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n+{spring-framework-api}/test/context/ContextHierarchy.html[`@ContextHierarchy`] javadoc\n for further examples.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\nindex 39c27a8f1600..12d361deca8a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dirtiescontext.adoc\n@@ -257,6 +257,6 @@ Kotlin::\n \n \n For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the\n-{api-spring-framework}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n+{spring-framework-api}/test/annotation/DirtiesContext.HierarchyMode.html[`DirtiesContext.HierarchyMode`]\n javadoc.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\nindex 003175517ccf..4c6e37863c36 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-dynamicpropertysource.adoc\n@@ -6,7 +6,7 @@ _dynamic_ properties to be added to the set of `PropertySources` in the `Environ\n an `ApplicationContext` loaded for an integration test. Dynamic properties are useful\n when you do not know the value of the properties upfront \u2013 for example, if the properties\n are managed by an external resource such as for a container managed by the\n-https://www.testcontainers.org/[Testcontainers] project.\n+{testcontainers-site}[Testcontainers] project.\n \n The following example demonstrates how to register a dynamic property:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\nindex fbd7f0cf03f2..73365f75e1bd 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-recordapplicationevents.adoc\n@@ -9,6 +9,6 @@ _Spring TestContext Framework_ to record all application events that are publish\n The recorded events can be accessed via the `ApplicationEvents` API within tests.\n \n See xref:testing/testcontext-framework/application-events.adoc[Application Events] and the \n-{api-spring-framework}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n+{spring-framework-api}/test/context/event/RecordApplicationEvents.html[`@RecordApplicationEvents`\n javadoc] for an example and further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\nindex 3e9505d15235..370d1e7d5865 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testexecutionlisteners.adoc\n@@ -39,7 +39,7 @@ Kotlin::\n By default, `@TestExecutionListeners` provides support for inheriting listeners from\n superclasses or enclosing classes. See\n xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-nested-test-configuration[`@Nested` test class configuration] and the\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`\n javadoc] for an example and further details. If you discover that you need to switch\n back to using the default `TestExecutionListener` implementations, see the note\n in xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-registering-tels[Registering `TestExecutionListener` Implementations].\ndiff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\nindex a367a0ee9451..2c3d1ac328dc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-webappconfiguration.adoc\n@@ -80,6 +80,6 @@ Kotlin::\n Note that `@WebAppConfiguration` must be used in conjunction with\n `@ContextConfiguration`, either within a single test class or within a test class\n hierarchy. See the\n-{api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n+{spring-framework-api}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`]\n javadoc for further details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/resources.adoc b/framework-docs/modules/ROOT/pages/testing/resources.adoc\nindex c7b3c247dc10..9b6b5d61b99f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/resources.adoc\n@@ -8,7 +8,7 @@ See the following resources for more information about testing:\n * https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support\n for test groups, data-driven testing, distributed testing, and other features. Supported\n in the xref:testing/testcontext-framework.adoc[Spring TestContext Framework]\n-* https://assertj.github.io/doc/[AssertJ]: \"Fluent assertions for Java\",\n+* {assertj-docs}[AssertJ]: \"Fluent assertions for Java\",\n including support for Java 8 lambdas, streams, and numerous other features.\n * https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.\n * http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a\n@@ -24,7 +24,7 @@ See the following resources for more information about testing:\n * https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that\n is targeted at database-driven projects and, among other things, puts your database into\n a known state between test runs.\n-* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit\n+* {testcontainers-site}[Testcontainers]: Java library that supports JUnit\n tests, providing lightweight, throwaway instances of common databases, Selenium web\n browsers, or anything else that can run in a Docker container.\n * https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\nindex a223a9f4ca35..e8c56ed11fc0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-client.adoc\n@@ -211,5 +211,5 @@ configuration. Check for the support for code completion on static members.\n == Further Examples of Client-side REST Tests\n \n Spring MVC Test's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example\n tests] of client-side REST tests.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\nindex e581e32b1905..27dbf6ed50f5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-defining-expectations.adoc\n@@ -184,7 +184,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -192,7 +192,7 @@ Note that common expectations are always applied and cannot be overridden withou\n creating a separate `MockMvc` instance.\n \n When a JSON response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using JsonPath expressions, as the following example shows:\n \n [tabs]\n@@ -220,7 +220,7 @@ Kotlin::\n ======\n \n When XML response content contains hypermedia links created with\n-https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], you can verify the\n+{spring-github-org}/spring-hateoas[Spring HATEOAS], you can verify the\n resulting links by using XPath expressions:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\nindex 7b379b88cde5..b292ec168a3e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-filters.adoc\n@@ -18,7 +18,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\nindex 145fbb6b809d..7ef8a8dbcfbf 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/mah.adoc\n@@ -113,7 +113,7 @@ Kotlin::\n ======\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] library:\n+assertions use the {assertj-docs}[AssertJ] library:\n \n [tabs]\n ======\n@@ -268,7 +268,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\nindex 392ae27a8cbd..2c9bff2f937d 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc\n@@ -362,7 +362,7 @@ annotation to look up our submit button with a `css` selector (*input[type=submi\n --\n \n Finally, we can verify that a new message was created successfully. The following\n-assertions use the https://assertj.github.io/doc/[AssertJ] assertion library:\n+assertions use the {assertj-docs}[AssertJ] assertion library:\n \n --\n [tabs]\n@@ -562,7 +562,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\nindex ba8ac3772dc3..0d6bcab7ca33 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-performing-requests.adoc\n@@ -159,7 +159,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\nindex 7444c1038fb1..cb9c8e97e8d6 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-resources.adoc\n@@ -3,9 +3,9 @@\n :page-section-summary-toc: 1\n \n The framework's own tests include\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples[\n many sample tests] intended to show how to use MockMvc on its own or through the\n-{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client[\n WebTestClient]. Browse these examples for further ideas.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\nindex 2ec41f725a57..e179a8364a27 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/server-setup-steps.adoc\n@@ -25,7 +25,7 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n@@ -53,11 +53,11 @@ Kotlin::\n +\n [source,kotlin,indent=0,subs=\"verbatim,quotes\",role=\"secondary\"]\n ----\n-\t// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed\n+\t// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed\n ----\n ======\n \n See the javadoc for\n-{api-spring-framework}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n+{spring-framework-api}/test/web/servlet/setup/ConfigurableMockMvcBuilder.html[`ConfigurableMockMvcBuilder`]\n for a list of all MockMvc builder features or use the IDE to explore the available options.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\nindex 9b26c80f2370..a2027b67ce62 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc\n@@ -21,7 +21,7 @@ for rendering JSON, XML, and other formats through `@ResponseBody` methods.\n \n Alternatively, you may consider the full end-to-end integration testing support from\n Spring Boot with `@SpringBootTest`. See the\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing[Spring Boot Reference Guide].\n \n There are pros and cons for each approach. The options provided in Spring MVC Test are\n different stops on the scale from classic unit testing to full integration testing. To be\ndiff --git a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\nindex c5c3e7dc5a2c..d7524499dadc 100644\n--- a/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/spring-mvc-test-framework/vs-streaming-response.adoc\n@@ -33,6 +33,6 @@ Java::\n \n `WebTestClient` can also connect to a live server and perform full end-to-end integration\n tests. This is also supported in Spring Boot where you can\n-{docs-spring-boot}/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n+{spring-boot-docs}/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server[test a running server].\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\nindex 0ce800ca2278..337eb71c655f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc\n@@ -52,13 +52,13 @@ To provide test-specific runtime hints for use within a GraalVM native image, yo\n the following options.\n \n * Implement a custom\n- {api-spring-framework}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n+ {spring-framework-api}/test/context/aot/TestRuntimeHintsRegistrar.html[`TestRuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories`.\n-* Implement a custom {api-spring-framework}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n+* Implement a custom {spring-framework-api}/aot/hint/RuntimeHintsRegistrar.html[`RuntimeHintsRegistrar`]\n and register it globally via `META-INF/spring/aot.factories` or locally on a test class\n- via {api-spring-framework}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n-* Annotate a test class with {api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n- {api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n+ via {spring-framework-api}/context/annotation/ImportRuntimeHints.html[`@ImportRuntimeHints`].\n+* Annotate a test class with {spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] or\n+ {spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`].\n * See xref:core/aot.adoc#aot.hints[Runtime Hints] for details on Spring's core runtime hints\n and annotation support.\n \n@@ -71,12 +71,12 @@ that are not specific to particular test classes, favor implementing\n ====\n \n If you implement a custom `ContextLoader`, it must implement\n-{api-spring-framework}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n+{spring-framework-api}/test/context/aot/AotContextLoader.html[`AotContextLoader`] in\n order to provide AOT build-time processing and AOT runtime execution support. Note,\n however, that all context loader implementations provided by the Spring Framework and\n Spring Boot already implement `AotContextLoader`.\n \n If you implement a custom `TestExecutionListener`, it must implement\n-{api-spring-framework}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n+{spring-framework-api}/test/context/aot/AotTestExecutionListener.html[`AotTestExecutionListener`]\n in order to participate in AOT processing. See the `SqlScriptsTestExecutionListener` in\n the `spring-test` module for an example.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\nindex 14cf022a8891..b27d2d98c5b5 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/application-events.adoc\n@@ -24,7 +24,7 @@ To use `ApplicationEvents` in your tests, do the following.\n to an `@Autowired` field in the test class.\n \n The following test class uses the `SpringExtension` for JUnit Jupiter and\n-https://assertj.github.io/doc/[AssertJ] to assert the types of application events\n+{assertj-docs}[AssertJ] to assert the types of application events\n published while invoking a method in a Spring-managed component:\n \n // Don't use \"quotes\" in the \"subs\" section because of the asterisks in /* ... */\n@@ -88,6 +88,6 @@ Kotlin::\n ======\n \n See the\n-{api-spring-framework}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n+{spring-framework-api}/test/context/event/ApplicationEvents.html[`ApplicationEvents`\n javadoc] for further details regarding the `ApplicationEvents` API.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\nindex 1979482042cf..9a5e920b4eed 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/context-customizers.adoc\n@@ -29,7 +29,7 @@ You can register `ContextCustomizerFactory` implementations explicitly for a tes\n subclasses, and its nested classes by using the `@ContextCustomizerFactories` annotation. See\n xref:testing/annotations/integration-spring/annotation-contextcustomizerfactories.adoc[annotation support]\n and the javadoc for\n-{api-spring-framework}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n+{spring-framework-api}/test/context/ContextCustomizerFactories.html[`@ContextCustomizerFactories`]\n for details and examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\nindex ad418ef4cdfc..4705d57cbe64 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/dynamic-property-sources.adoc\n@@ -11,7 +11,7 @@ integration test.\n ====\n The `@DynamicPropertySource` annotation and its supporting infrastructure were\n originally designed to allow properties from\n-https://www.testcontainers.org/[Testcontainers] based tests to be exposed easily to\n+{testcontainers-site}[Testcontainers] based tests to be exposed easily to\n Spring integration tests. However, this feature may also be used with any form of\n external resource whose lifecycle is maintained outside the test's `ApplicationContext`.\n ====\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\nindex bb868bf5fae4..f1d52d53c03a 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/env-profiles.adoc\n@@ -478,7 +478,7 @@ programmatically instead of declaratively -- for example, based on:\n To resolve active bean definition profiles programmatically, you can implement\n a custom `ActiveProfilesResolver` and register it by using the `resolver`\n attribute of `@ActiveProfiles`. For further information, see the corresponding\n-{api-spring-framework}/test/context/ActiveProfilesResolver.html[javadoc].\n+{spring-framework-api}/test/context/ActiveProfilesResolver.html[javadoc].\n The following example demonstrates how to implement and register a custom\n `OperatingSystemActiveProfilesResolver`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\nindex c92ebb9064b2..22953ed289cb 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/hierarchies.adoc\n@@ -235,6 +235,6 @@ NOTE: If you use `@DirtiesContext` in a test whose context is configured as part\n context hierarchy, you can use the `hierarchyMode` flag to control how the context cache\n is cleared. For further details, see the discussion of `@DirtiesContext` in\n xref:testing/annotations/integration-spring/annotation-dirtiescontext.adoc[Spring Testing Annotations] and the\n-{api-spring-framework}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n+{spring-framework-api}/test/annotation/DirtiesContext.html[`@DirtiesContext`] javadoc.\n --\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\nindex cfd0cedfe235..af460ea84f06 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/ctx-management/javaconfig.adoc\n@@ -51,8 +51,8 @@ The term \"`component class`\" can refer to any of the following:\n of a single constructor without the use of Spring annotations.\n \n See the javadoc of\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and\n-{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] and\n+{spring-framework-api}/context/annotation/Bean.html[`@Bean`] for further information\n regarding the configuration and semantics of component classes, paying special attention\n to the discussion of `@Bean` Lite Mode.\n ====\n@@ -62,7 +62,7 @@ TestContext framework tries to detect the presence of default configuration clas\n Specifically, `AnnotationConfigContextLoader` and `AnnotationConfigWebContextLoader`\n detect all `static` nested classes of the test class that meet the requirements for\n configuration class implementations, as specified in the\n-{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n+{spring-framework-api}/context/annotation/Configuration.html[`@Configuration`] javadoc.\n Note that the name of the configuration class is arbitrary. In addition, a test class can\n contain more than one `static` nested configuration class if desired. In the following\n example, the `OrderServiceTest` class declares a `static` nested configuration class\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\nindex b7ff759e6101..b3bd66ff7c7f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/executing-sql.adoc\n@@ -29,7 +29,7 @@ integration test methods.\n scripts and is mainly intended for internal use within the framework. However, if you\n require full control over how SQL scripts are parsed and run, `ScriptUtils` may suit\n your needs better than some of the other alternatives described later. See the\n-{api-spring-framework}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n+{spring-framework-api}/jdbc/datasource/init/ScriptUtils.html[javadoc] for individual\n methods in `ScriptUtils` for further details.\n \n `ResourceDatabasePopulator` provides an object-based API for programmatically populating,\n@@ -38,7 +38,7 @@ resources. `ResourceDatabasePopulator` provides options for configuring the char\n encoding, statement separator, comment delimiters, and error handling flags used when\n parsing and running the scripts. Each of the configuration options has a reasonable\n default value. See the\n-{api-spring-framework}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n+{spring-framework-api}/jdbc/datasource/init/ResourceDatabasePopulator.html[javadoc] for\n details on default values. To run the scripts configured in a\n `ResourceDatabasePopulator`, you can invoke either the `populate(Connection)` method to\n run the populator against a `java.sql.Connection` or the `execute(DataSource)` method\n@@ -392,8 +392,8 @@ local `@SqlConfig` attributes do not supply an explicit value other than `\"\"`, `\n The configuration options provided by `@Sql` and `@SqlConfig` are equivalent to those\n supported by `ScriptUtils` and `ResourceDatabasePopulator` but are a superset of those\n provided by the `` XML namespace element. See the javadoc of\n-individual attributes in {api-spring-framework}/test/context/jdbc/Sql.html[`@Sql`] and\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n+individual attributes in {spring-framework-api}/test/context/jdbc/Sql.html[`@Sql`] and\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] for details.\n \n [[testcontext-executing-sql-declaratively-tx]]\n ==== Transaction management for `@Sql`\n@@ -415,8 +415,8 @@ behavior by setting the `transactionMode` attribute of `@SqlConfig` (for example\n scripts should be run in an isolated transaction). Although a thorough discussion of all\n supported options for transaction management with `@Sql` is beyond the scope of this\n reference manual, the javadoc for\n-{api-spring-framework}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n-{api-spring-framework}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n+{spring-framework-api}/test/context/jdbc/SqlConfig.html[`@SqlConfig`] and\n+{spring-framework-api}/test/context/jdbc/SqlScriptsTestExecutionListener.html[`SqlScriptsTestExecutionListener`]\n provide detailed information, and the following example shows a typical testing scenario\n that uses JUnit Jupiter and transactional tests with `@Sql`:\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\nindex 04e5e9ce4aa8..6910ce06fb9e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/key-abstractions.adoc\n@@ -10,7 +10,7 @@ in turn, manages a `TestContext` that holds the context of the current test. The\n and delegates to `TestExecutionListener` implementations, which instrument the actual\n test execution by providing dependency injection, managing transactions, and so on. A\n `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test\n-class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the\n+class. See the {spring-framework-api}/test/context/package-summary.html[javadoc] and the\n Spring test suite for further information and examples of various implementations.\n \n [[testcontext]]\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\nindex 1a3c642f6261..6cb00cbcc75f 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/parallel-test-execution.adoc\n@@ -40,7 +40,7 @@ for details.\n \n WARNING: Parallel test execution in the Spring TestContext Framework is only possible if\n the underlying `TestContext` implementation provides a copy constructor, as explained in\n-the javadoc for {api-spring-framework}/test/context/TestContext.html[`TestContext`]. The\n+the javadoc for {spring-framework-api}/test/context/TestContext.html[`TestContext`]. The\n `DefaultTestContext` used in Spring provides such a constructor. However, if you use a\n third-party library that provides a custom `TestContext` implementation, you need to\n verify that it is suitable for parallel test execution.\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\nindex 2c2c749b88cb..754d490563b0 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tel-config.adoc\n@@ -29,7 +29,7 @@ by default, exactly in the following order:\n You can register `TestExecutionListener` implementations explicitly for a test class, its\n subclasses, and its nested classes by using the `@TestExecutionListeners` annotation. See\n xref:testing/annotations.adoc[annotation support] and the javadoc for\n-{api-spring-framework}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n+{spring-framework-api}/test/context/TestExecutionListeners.html[`@TestExecutionListeners`]\n for details and examples.\n \n .Switching to default `TestExecutionListener` implementations\ndiff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\nindex d144ddc2f771..f34ad15f9457 100644\n--- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/tx.adoc\n@@ -216,7 +216,7 @@ Support for `TestTransaction` is automatically available whenever the\n `TransactionalTestExecutionListener` is enabled.\n \n The following example demonstrates some of the features of `TestTransaction`. See the\n-javadoc for {api-spring-framework}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n+javadoc for {spring-framework-api}/test/context/transaction/TestTransaction.html[`TestTransaction`]\n for further details.\n \n [tabs]\n@@ -355,7 +355,7 @@ of `PlatformTransactionManager` within the test's `ApplicationContext`, you can\n qualifier by using `@Transactional(\"myTxMgr\")` or `@Transactional(transactionManager =\n \"myTxMgr\")`, or `TransactionManagementConfigurer` can be implemented by an\n `@Configuration` class. Consult the\n-{api-spring-framework}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n+{spring-framework-api}/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-[javadoc\n for `TestContextTransactionUtils.retrieveTransactionManager()`] for details on the\n algorithm used to look up a transaction manager in the test's `ApplicationContext`.\n \n@@ -668,7 +668,7 @@ Kotlin::\n ======\n \n See\n-https://github.com/spring-projects/spring-framework/blob/main/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n+{spring-framework-code}/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/orm/JpaEntityListenerTests.java[JpaEntityListenerTests]\n in the Spring Framework test suite for working examples using all JPA lifecycle callbacks.\n =====\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc\nindex f137331a5138..d2ce8648b0e9 100644\n--- a/framework-docs/modules/ROOT/pages/testing/unit.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc\n@@ -112,16 +112,16 @@ categories:\n The `org.springframework.test.util` package contains several general purpose utilities\n for use in unit and integration testing.\n \n-{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n+{spring-framework-api}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of\n AOP-related utility methods. You can use these methods to obtain a reference to the\n underlying target object hidden behind one or more Spring proxies. For example, if you\n have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,\n and the mock is wrapped in a Spring proxy, you may need direct access to the underlying\n mock to configure expectations on it and perform verifications. For Spring's core AOP\n-utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and\n-{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n+utilities, see {spring-framework-api}/aop/support/AopUtils.html[`AopUtils`] and\n+{spring-framework-api}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].\n \n-{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n+{spring-framework-api}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a\n collection of reflection-based utility methods. You can use these methods in testing\n scenarios where you need to change the value of a constant, set a non-`public` field,\n invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle\n@@ -135,7 +135,7 @@ callback method when testing application code for use cases such as the followin\n * Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback\n methods.\n \n-{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n+{spring-framework-api}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple\n utility for finding available TCP ports on `localhost` for use in integration testing\n scenarios.\n \n@@ -155,7 +155,7 @@ server for the port it is currently using.\n === Spring MVC Testing Utilities\n \n The `org.springframework.test.web` package contains\n-{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n+{spring-framework-api}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you\n can use in combination with JUnit, TestNG, or any other testing framework for unit tests\n that deal with Spring MVC `ModelAndView` objects.\n \ndiff --git a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\nindex 7d6d1e4461b6..cd625209b35e 100644\n--- a/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/testing/webtestclient.adoc\n@@ -48,7 +48,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following which delegates to the\n-{api-spring-framework}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n+{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]\n to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],\n registers the given controller(s), and creates an instance of\n xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:\n@@ -81,7 +81,7 @@ infrastructure and controller declarations and use it to handle requests via moc\n and response objects, without a running server.\n \n For WebFlux, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html#applicationContext-org.springframework.context.ApplicationContext-[WebHttpHandlerBuilder]\n to create the xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[WebHandler chain] to handle\n requests:\n \n@@ -127,7 +127,7 @@ Kotlin::\n ======\n \n For Spring MVC, use the following where the Spring `ApplicationContext` is passed to\n-{api-spring-framework}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n+{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]\n to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle\n requests:\n \n@@ -439,7 +439,7 @@ Kotlin::\n \n TIP: When you need to decode to a target type with generics, look for the overloaded methods\n that accept\n-{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n+{spring-framework-api}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]\n instead of `Class`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web-reactive.adoc b/framework-docs/modules/ROOT/pages/web-reactive.adoc\nindex 28ecf885b3e3..378d65ef5911 100644\n--- a/framework-docs/modules/ROOT/pages/web-reactive.adoc\n+++ b/framework-docs/modules/ROOT/pages/web-reactive.adoc\n@@ -2,7 +2,7 @@\n = Web on Reactive Stack\n \n This part of the documentation covers support for reactive-stack web applications built\n-on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking\n+on a {reactive-streams-site}/[Reactive Streams] API to run on non-blocking\n servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover\n the xref:web/webflux.adoc#webflux[Spring WebFlux] framework,\n the reactive xref:web/webflux-webclient.adoc[`WebClient`],\ndiff --git a/framework-docs/modules/ROOT/pages/web/integration.adoc b/framework-docs/modules/ROOT/pages/web/integration.adoc\nindex 6d362d916ae7..55276ff2bcb2 100644\n--- a/framework-docs/modules/ROOT/pages/web/integration.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/integration.adoc\n@@ -35,7 +35,7 @@ context\"). This section details how you can configure a Spring container (a\n `WebApplicationContext`) that contains all of the 'business beans' in your application.\n \n Moving on to specifics, all you need to do is declare a\n-{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n+{spring-framework-api}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]\n in the standard Jakarta EE servlet `web.xml` file of your web application and add a\n `contextConfigLocation` `` section (in the same file) that defines which\n set of Spring XML configuration files to load.\n@@ -62,7 +62,7 @@ Further consider the following `` configuration:\n If you do not specify the `contextConfigLocation` context parameter, the\n `ContextLoaderListener` looks for a file called `/WEB-INF/applicationContext.xml` to\n load. Once the context files are loaded, Spring creates a\n-{api-spring-framework}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n+{spring-framework-api}/web/context/WebApplicationContext.html[`WebApplicationContext`]\n object based on the bean definitions and stores it in the `ServletContext` of the web\n application.\n \n@@ -78,7 +78,7 @@ The following example shows how to get the `WebApplicationContext`:\n ----\n \n The\n-{api-spring-framework}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n+{spring-framework-api}/web/context/support/WebApplicationContextUtils.html[`WebApplicationContextUtils`]\n class is for convenience, so you need not remember the name of the `ServletContext`\n attribute. Its `getWebApplicationContext()` method returns `null` if an object\n does not exist under the `WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`\n@@ -142,7 +142,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF\n \n A custom `ELResolver` works well when mapping your properties to beans in\n `faces-config.xml`, but, at times, you may need to explicitly grab a bean.\n-The {api-spring-framework}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n+The {spring-framework-api}/web/jsf/FacesContextUtils.html[`FacesContextUtils`]\n class makes this easy. It is similar to `WebApplicationContextUtils`, except that\n it takes a `FacesContext` parameter rather than a `ServletContext` parameter.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\nindex 845976b8e02c..4de277efa7ea 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-cors.adoc\n@@ -47,7 +47,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/reactive/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the WebFlux Java configuration to declare such mappings, which results in a single,\n global map passed to all `HandlerMapping` implementations.\n@@ -60,7 +60,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, such as `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ a finite set of values instead to provide a higher level of security.\n == `@CrossOrigin`\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-controller[See equivalent in the Servlet stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods, as the\n following example shows:\n \n@@ -363,7 +363,7 @@ Kotlin::\n [.small]#xref:web/webmvc-cors.adoc#mvc-cors-filter[See equivalent in the Servlet stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n+{spring-framework-api}/web/cors/reactive/CorsWebFilter.html[`CorsWebFilter`], which is a\n good fit with <>.\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\nindex 3e3cb23c9f86..35a5b50588cd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc\n@@ -122,7 +122,7 @@ Most applications can run through the WebFlux Java configuration, see xref:web/w\n \n `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly\n access to the HTTP request and response.\n-Both request and response provide https://www.reactive-streams.org[Reactive Streams] back pressure\n+Both request and response provide {reactive-streams-site}[Reactive Streams] back pressure\n against the body streams.\n The request body is represented with a Reactor `Flux` or `Mono`.\n The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`.\n@@ -350,7 +350,7 @@ ServerResponse.created(location).build()\n ======\n \n Depending on the codec used, it is possible to pass hint parameters to customize how the\n-body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:\n+body is serialized or deserialized. For example, to specify a {baeldung-blog}/jackson-json-view-annotation[Jackson JSON view]:\n \n [tabs]\n ======\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\nindex 45ac4fcd581d..b4b8cc533b3a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-reactive-libraries.adoc\n@@ -11,7 +11,7 @@ encoding or decoding HTTP messages).\n \n For annotated controllers, WebFlux transparently adapts to the reactive library chosen by\n the application. This is done with the help of the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`], which\n provides pluggable support for reactive library and other asynchronous types. The registry\n has built-in support for RxJava 3, Kotlin coroutines and SmallRye Mutiny, but you can\n register others, too.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\nindex 491a064f3ffd..288fc1a38c52 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc\n@@ -209,7 +209,7 @@ sections of the Spring MVC documentation.\n \n The Spring Framework has a built-in integration for using Spring WebFlux with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine.\n+{JSR}223[JSR-223] Java scripting engine.\n The following table shows the templating libraries that we have tested on different script engines:\n \n [%header]\n@@ -221,7 +221,7 @@ The following table shows the templating libraries that we have tested on differ\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -312,7 +312,7 @@ The `render` function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -404,8 +404,8 @@ The following example shows how compile a template:\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n-{spring-framework-main-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and\n+{spring-framework-code}/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\nindex effa703ab605..448ff3db92d8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient.adoc\n@@ -12,8 +12,8 @@ decode request and response content on the server side.\n `WebClient` needs an HTTP client library to perform requests with. There is built-in\n support for the following:\n \n-* https://github.com/reactor/reactor-netty[Reactor Netty]\n-* https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n+* {reactor-github-org}/reactor-netty[Reactor Netty]\n+* {java-api}/java.net.http/java/net/http/HttpClient.html[JDK HttpClient]\n * https://github.com/jetty-project/jetty-reactive-httpclient[Jetty Reactive HttpClient]\n * https://hc.apache.org/index.html[Apache HttpComponents]\n * Others can be plugged via `ClientHttpConnector`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\nindex 8b1393cc52b6..febbb5498272 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux-webclient/client-testing.adoc\n@@ -5,7 +5,7 @@\n To test code that uses the `WebClient`, you can use a mock web server, such as the\n https://github.com/square/okhttp#mockwebserver[OkHttp MockWebServer]. To see an example\n of its use, check out\n-{spring-framework-main-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n+{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java[`WebClientIntegrationTests`]\n in the Spring Framework test suite or the\n https://github.com/square/okhttp/tree/master/samples/static-server[`static-server`]\n sample in the OkHttp repository.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux.adoc b/framework-docs/modules/ROOT/pages/web/webflux.adoc\nindex a9487c93739b..cbf487481cb8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux.adoc\n@@ -7,12 +7,12 @@\n The original web framework included in the Spring Framework, Spring Web MVC, was\n purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,\n Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports\n-https://www.reactive-streams.org/[Reactive Streams] back pressure, and runs on such servers as\n+{reactive-streams-site}/[Reactive Streams] back pressure, and runs on such servers as\n Netty, Undertow, and Servlet containers.\n \n Both web frameworks mirror the names of their source modules\n-({spring-framework-main-code}/spring-webmvc[spring-webmvc] and\n-{spring-framework-main-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n+({spring-framework-code}/spring-webmvc[spring-webmvc] and\n+{spring-framework-code}/spring-webflux[spring-webflux]) and co-exist side by side in the\n Spring Framework. Each module is optional. Applications can use one or the other module or,\n in some cases, both -- for example, Spring MVC controllers with the reactive `WebClient`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\nindex d8fb4a7291c2..f775e28e2ade 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807.html[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\nindex 5da8d201aedf..a01e743b5edf 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/caching.adoc\n@@ -19,14 +19,14 @@ This section describes the HTTP caching related options available in Spring WebF\n == `CacheControl`\n [.small]#xref:web/webmvc/mvc-caching.adoc#mvc-caching-cachecontrol[See equivalent in the Servlet stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n * xref:web/webflux/caching.adoc#webflux-caching-etag-lastmodified[Controllers]\n * xref:web/webflux/caching.adoc#webflux-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios, as the following example shows:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\nindex 69e2f8195784..f2c9796bf49f 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc\n@@ -348,18 +348,18 @@ Kotlin::\n more readers and writers, customize the default ones, or replace the default ones completely.\n \n For Jackson JSON and XML, consider using\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`],\n which customizes Jackson's default properties with the following ones:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[`jackson-datatype-joda`]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[`jackson-datatype-jsr310`]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[`jackson-datatype-jdk8`]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n \n \n@@ -549,7 +549,7 @@ See xref:web/webflux-view.adoc[View Technologies] for more on the view technolog\n [.small]#xref:web/webmvc/mvc-config/static-resources.adoc[See equivalent in the Servlet stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/static` on the classpath. Resources\n@@ -598,8 +598,8 @@ Kotlin::\n See also xref:web/webflux/caching.adoc#webflux-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/reactive/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which can be used to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\n@@ -685,7 +685,7 @@ for fine-grained control, e.g. last-modified behavior and optimized resource res\n [.small]#xref:web/webmvc/mvc-config/path-matching.adoc[See equivalent in the Servlet stack]#\n \n You can customize options related to path matching. For details on the individual options, see the\n-{api-spring-framework}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/reactive/config/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n The following example shows how to use `PathMatchConfigurer`:\n \n [tabs]\n@@ -746,7 +746,7 @@ The WebFlux Java config allows you to customize blocking execution in WebFlux.\n \n You can have blocking controller methods called on a separate thread by providing\n an `AsyncTaskExecutor` such as the\n-{api-spring-framework}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n+{spring-framework-api}/core/task/VirtualThreadTaskExecutor.html[`VirtualThreadTaskExecutor`]\n as follows:\n \n [tabs]\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\nindex 362425369283..cf77c0ca8409 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-advice.adoc\n@@ -64,6 +64,6 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\nindex 87cb4522b2aa..4c0215ad403b 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/arguments.adoc\n@@ -114,7 +114,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the above, it is, by default, resolved as\n a `@RequestParam` if it is a simple type, as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n or as a `@ModelAttribute`, otherwise.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\nindex fe3db7c7d560..1def0f1794fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webmvc/mvc-controller/ann-methods/jackson.adoc[See equivalent in the Servlet stack]#\n \n Spring WebFlux provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allows rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\nindex b5a5bd9753c5..02d4555997dd 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc[See equivalent in the Servlet stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring WebFlux, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\nindex 8cccf3b7d0d4..35abbbd828ee 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/modelattrib-method-args.adoc\n@@ -197,7 +197,7 @@ controller method xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation]\n \n TIP: Using `@ModelAttribute` is optional. By default, any argument that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\nindex 2752035758fd..372c4bfaa6be 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/requestparam.adoc\n@@ -74,7 +74,7 @@ When a `@RequestParam` annotation is declared on a `Map` or\n \n Note that use of `@RequestParam` is optional -- for example, to set its attributes. By\n default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\nindex 7752ee485377..750cdf443660 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-methods/return-types.adoc\n@@ -75,7 +75,7 @@ generally supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\nindex bf8d7afa04e9..fab54b23073a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-modelattrib-methods.adoc\n@@ -75,7 +75,7 @@ Kotlin::\n ======\n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the type,\n-as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the name attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\nindex 8b0c069db657..584b0f870294 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\nindex b0919fd8fdab..a621320538ae 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/dispatcher-handler.adoc\n@@ -12,7 +12,7 @@ This model is flexible and supports diverse workflows.\n It is also designed to be a Spring bean itself and implements `ApplicationContextAware`\n for access to the context in which it runs. If `DispatcherHandler` is declared with a bean\n name of `webHandler`, it is, in turn, discovered by\n-{api-spring-framework}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n+{spring-framework-api}/web/server/adapter/WebHttpHandlerBuilder.html[`WebHttpHandlerBuilder`],\n which puts together a request-processing chain, as described in xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api[`WebHandler` API].\n \n Spring configuration in a WebFlux application typically contains:\n@@ -144,9 +144,9 @@ as a `HandlerResult`, along with some additional context, and passed to the firs\n | 100\n \n | `ViewResolutionResultHandler`\n-| `CharSequence`, {api-spring-framework}/web/reactive/result/view/View.html[`View`],\n- {api-spring-framework}/ui/Model.html[Model], `Map`,\n- {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering],\n+| `CharSequence`, {spring-framework-api}/web/reactive/result/view/View.html[`View`],\n+ {spring-framework-api}/ui/Model.html[Model], `Map`,\n+ {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering],\n or any other `Object` is treated as a model attribute.\n \n See also xref:web/webflux/dispatcher-handler.adoc#webflux-viewresolution[View Resolution].\n@@ -202,13 +202,13 @@ the list of configured `ViewResolver` implementations.\n trailing slash, and resolve it to a `View`. The same also happens when a view name\n was not provided (for example, model attribute was returned) or an async return value\n (for example, `Mono` completed empty).\n-* {api-spring-framework}/web/reactive/result/view/Rendering.html[Rendering]: API for\n+* {spring-framework-api}/web/reactive/result/view/Rendering.html[Rendering]: API for\n view resolution scenarios. Explore the options in your IDE with code completion.\n * `Model`, `Map`: Extra model attributes to be added to the model for the request.\n * Any other: Any other return value (except for simple types, as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n is treated as a model attribute to be added to the model. The attribute name is derived\n-from the class name by using {api-spring-framework}/core/Conventions.html[conventions],\n+from the class name by using {spring-framework-api}/core/Conventions.html[conventions],\n unless a handler method `@ModelAttribute` annotation is present.\n \n The model can contain asynchronous, reactive types (for example, from Reactor or RxJava). Prior\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\nindex 39f080c10178..1b5a9e643a7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/http2.adoc\n@@ -6,4 +6,4 @@\n \n HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are\n considerations related to server configuration. For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\nindex e9b72f23173e..b03cefb04bbe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/new-framework.adoc\n@@ -38,13 +38,13 @@ code, it becomes important to control the rate of events so that a fast producer\n overwhelm its destination.\n \n Reactive Streams is a\n-https://github.com/reactive-streams/reactive-streams-jvm/blob/master/README.md#specification[small spec]\n-(also https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html[adopted] in Java 9)\n+{reactive-streams-spec}[small spec]\n+(also {java-api}/java.base/java/util/concurrent/Flow.html[adopted] in Java 9)\n that defines the interaction between asynchronous components with back pressure.\n For example a data repository (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Publisher.html[Publisher])\n can produce data that an HTTP server (acting as\n-https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n+{reactive-streams-site}/reactive-streams-1.0.1-javadoc/org/reactivestreams/Subscriber.html[Subscriber])\n can then write to the response. The main purpose of Reactive Streams is to let the\n subscriber control how quickly or how slowly the publisher produces data.\n \n@@ -63,10 +63,10 @@ low-level. Applications need a higher-level and richer, functional API to\n compose async logic -- similar to the Java 8 `Stream` API but not only for collections.\n This is the role that reactive libraries play.\n \n-https://github.com/reactor/reactor[Reactor] is the reactive library of choice for\n+{reactor-github-org}/reactor[Reactor] is the reactive library of choice for\n Spring WebFlux. It provides the\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n-https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Mono.html[`Mono`] and\n+{reactor-site}/docs/core/release/api/reactor/core/publisher/Flux.html[`Flux`] API types\n to work on data sequences of 0..1 (`Mono`) and 0..N (`Flux`) through a rich set of operators aligned with the\n ReactiveX https://reactivex.io/documentation/operators.html[vocabulary of operators].\n Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back pressure.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\nindex 4be5c9b4311c..13d527592cc8 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/reactive-spring.adoc\n@@ -13,7 +13,7 @@ request handling, on top of which concrete programming models such as annotated\n controllers and functional endpoints are built.\n * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP\n requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for\n-https://github.com/reactor/reactor-netty[Reactor Netty], reactive\n+{reactor-github-org}/reactor-netty[Reactor Netty], reactive\n https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HttpClient]\n and https://hc.apache.org/[Apache HttpComponents].\n The higher level xref:web/webflux-webclient.adoc[WebClient] used in applications\n@@ -26,7 +26,7 @@ deserialization of HTTP request and response content.\n [[webflux-httphandler]]\n == `HttpHandler`\n \n-{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]\n+{spring-framework-api}/http/server/reactive/HttpHandler.html[HttpHandler]\n is a simple contract with a single method to handle a request and a response. It is\n intentionally minimal, and its main and only purpose is to be a minimal abstraction\n over different HTTP server APIs.\n@@ -39,7 +39,7 @@ The following table describes the supported server APIs:\n \n | Netty\n | Netty API\n-| https://github.com/reactor/reactor-netty[Reactor Netty]\n+| {reactor-github-org}/reactor-netty[Reactor Netty]\n \n | Undertow\n | Undertow API\n@@ -59,7 +59,7 @@ The following table describes the supported server APIs:\n |===\n \n The following table describes server dependencies (also see\n-https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):\n+{spring-framework-wiki}/What%27s-New-in-the-Spring-Framework[supported versions]):\n \n |===\n |Server name|Group id|Artifact name\n@@ -213,7 +213,7 @@ Kotlin::\n *Servlet Container*\n \n To deploy as a WAR to any Servlet container, you can extend and include\n-{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n+{spring-framework-api}/web/server/adapter/AbstractReactiveWebInitializer.html[`AbstractReactiveWebInitializer`]\n in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers\n that as a `Servlet`.\n \n@@ -224,9 +224,9 @@ that as a `Servlet`.\n \n The `org.springframework.web.server` package builds on the xref:web/webflux/reactive-spring.adoc#webflux-httphandler[`HttpHandler`] contract\n to provide a general-purpose web API for processing requests through a chain of multiple\n-{api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n-{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single\n-{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n+{spring-framework-api}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple\n+{spring-framework-api}/web/server/WebFilter.html[`WebFilter`], and a single\n+{spring-framework-api}/web/server/WebHandler.html[`WebHandler`] component. The chain can\n be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring\n `ApplicationContext` where components are\n xref:web/webflux/reactive-spring.adoc#webflux-web-handler-api-special-beans[auto-detected], and/or by registering components\n@@ -438,7 +438,7 @@ The following table describes the available `WebExceptionHandler` implementation\n \n | `ResponseStatusExceptionHandler`\n | Provides handling for exceptions of type\n- {api-spring-framework}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n+ {spring-framework-api}/web/server/ResponseStatusException.html[`ResponseStatusException`]\n by setting the response to the HTTP status code of the exception.\n \n | `WebFluxResponseStatusExceptionHandler`\n@@ -459,15 +459,15 @@ The `spring-web` and `spring-core` modules provide support for serializing and\n deserializing byte content to and from higher level objects through non-blocking I/O with\n Reactive Streams back pressure. The following describes this support:\n \n-* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and\n-{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n+* {spring-framework-api}/core/codec/Encoder.html[`Encoder`] and\n+{spring-framework-api}/core/codec/Decoder.html[`Decoder`] are low level contracts to\n encode and decode content independent of HTTP.\n-* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n-{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n+* {spring-framework-api}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and\n+{spring-framework-api}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts\n to encode and decode HTTP message content.\n * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web\n application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.\n-* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n+* {spring-framework-api}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different\n byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is\n what all codecs work on. See xref:core/databuffer-codec.adoc[Data Buffers and Codecs] in the\n \"Spring Core\" section for more on this topic.\n@@ -485,7 +485,7 @@ xref:web/webflux/config.adoc#webflux-config-message-codecs[HTTP message codecs].\n [[webflux-codecs-jackson]]\n === Jackson JSON\n \n-JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are\n+JSON and binary JSON ({jackson-github-org}/smile-format-specification[Smile]) are\n both supported when the Jackson library is present.\n \n The `Jackson2Decoder` works as follows:\n@@ -549,7 +549,7 @@ for the actual parsing to a `Flux` and then simply collects the parts into\n By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the\n `ServerCodecConfigurer`.\n For more information about the `DefaultPartHttpMessageReader`, refer to the\n-{api-spring-framework}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n+{spring-framework-api}/http/codec/multipart/DefaultPartHttpMessageReader.html[javadoc of `DefaultPartHttpMessageReader`].\n \n On the server side where multipart form content may need to be accessed from multiple\n places, `ServerWebExchange` provides a dedicated `getMultipartData()` method that parses\n@@ -643,11 +643,11 @@ is not useful for correlating log messages that belong to a specific request. Th\n WebFlux log messages are prefixed with a request-specific ID by default.\n \n On the server side, the log ID is stored in the `ServerWebExchange` attribute\n-({api-spring-framework}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n+({spring-framework-api}/web/server/ServerWebExchange.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`]),\n while a fully formatted prefix based on that ID is available from\n `ServerWebExchange#getLogPrefix()`. On the `WebClient` side, the log ID is stored in the\n `ClientRequest` attribute\n-({api-spring-framework}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n+({spring-framework-api}/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE[`LOG_ID_ATTRIBUTE`])\n ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\nindex 4c448e3cba7b..fcb982d254cb 100644\n--- a/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webflux/security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webmvc/mvc-security.adoc[See equivalent in the Servlet stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\nindex 3a8596d8250a..a8e7bb148b64 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-cors.adoc\n@@ -76,7 +76,7 @@ rejected. No CORS headers are added to the responses of simple and actual CORS r\n and, consequently, browsers reject them.\n \n Each `HandlerMapping` can be\n-{api-spring-framework}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n+{spring-framework-api}/web/servlet/handler/AbstractHandlerMapping.html#setCorsConfigurations-java.util.Map-[configured]\n individually with URL pattern-based `CorsConfiguration` mappings. In most cases, applications\n use the MVC Java configuration or the XML namespace to declare such mappings, which results\n in a single global map being passed to all `HandlerMapping` instances.\n@@ -89,7 +89,7 @@ class- or method-level `@CrossOrigin` annotations (other handlers can implement\n The rules for combining global and local configuration are generally additive -- for example,\n all global and all local origins. For those attributes where only a single value can be\n accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global value. See\n-{api-spring-framework}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n+{spring-framework-api}/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-[`CorsConfiguration#combine(CorsConfiguration)`]\n for more details.\n \n [TIP]\n@@ -108,7 +108,7 @@ To learn more from the source or make advanced customizations, check the code be\n == `@CrossOrigin`\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-controller[See equivalent in the Reactive stack]#\n \n-The {api-spring-framework}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n+The {spring-framework-api}/web/bind/annotation/CrossOrigin.html[`@CrossOrigin`]\n annotation enables cross-origin requests on annotated controller methods,\n as the following example shows:\n \n@@ -385,7 +385,7 @@ as the following example shows:\n [.small]#xref:web/webflux-cors.adoc#webflux-cors-webfilter[See equivalent in the Reactive stack]#\n \n You can apply CORS support through the built-in\n-{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].\n+{spring-framework-api}/web/filter/CorsFilter.html[`CorsFilter`].\n \n NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring\n Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\nindex 68714b3dfe5c..d12bf374fa40 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-feeds.adoc\n@@ -102,7 +102,7 @@ cookies or other HTTP headers. The feed is automatically written to the response\n object after the method returns.\n \n For an example of creating an Atom view, see Alef Arendsen's Spring Team Blog\n-https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n+{spring-site-blog}/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support[entry].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\nindex fd8f53404349..3b38ac877447 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jackson.adoc\n@@ -31,7 +31,7 @@ serializers and deserializers for specific types.\n [.small]#xref:web/webflux-view.adoc#webflux-view-httpmessagewriter[See equivalent in the Reactive stack]#\n \n `MappingJackson2XmlView` uses the\n-https://github.com/FasterXML/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n+{jackson-github-org}/jackson-dataformat-xml[Jackson XML extension's] `XmlMapper`\n to render the response content as XML. If the model contains multiple entries, you should\n explicitly set the object to be serialized by using the `modelKey` bean property. If the\n model contains a single entry, it is serialized automatically.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\nindex 1e37619d3932..d926842b3581 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-jsp.adoc\n@@ -44,7 +44,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact\n \n The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \n@@ -745,7 +745,7 @@ The HTML would be as follows:\n \n The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`.\n For a comprehensive reference on individual tags, browse the\n-{api-spring-framework}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n+{spring-framework-api}/web/servlet/tags/form/package-summary.html#package.description[API reference]\n or see the tag library description.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\nindex 27fac970a199..adc87d900352 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc\n@@ -5,7 +5,7 @@\n \n The Spring Framework has a built-in integration for using Spring MVC with any\n templating library that can run on top of the\n-https://www.jcp.org/en/jsr/detail?id=223[JSR-223] Java scripting engine. We have tested the following\n+{JSR}223[JSR-223] Java scripting engine. We have tested the following\n templating libraries on different script engines:\n \n [%header]\n@@ -17,7 +17,7 @@ templating libraries on different script engines:\n |https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]\n |https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby]\n |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]\n-|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |https://kotlinlang.org/[Kotlin]\n+|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]\n |===\n \n TIP: The basic rule for integrating any other script engine is that it must implement the\n@@ -174,7 +174,7 @@ The render function is called with the following parameters:\n * `String template`: The template content\n * `Map model`: The view model\n * `RenderingContext renderingContext`: The\n- {api-spring-framework}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n+ {spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]\n that gives access to the application context, the locale, the template loader, and the\n URL (since 5.0)\n \n@@ -265,8 +265,8 @@ template engine configuration, for example). The following example shows how to\n ----\n \n Check out the Spring Framework unit tests,\n-{spring-framework-main-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n-{spring-framework-main-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n+{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and\n+{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],\n for more configuration examples.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc.adoc b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\nindex d38563319ab3..8eaac910662d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc.adoc\n@@ -7,16 +7,16 @@\n Spring Web MVC is the original web framework built on the Servlet API and has been included\n in the Spring Framework from the very beginning. The formal name, \"Spring Web MVC,\"\n comes from the name of its source module\n-({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),\n+({spring-framework-code}/spring-webmvc[`spring-webmvc`]),\n but it is more commonly known as \"Spring MVC\".\n \n Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework\n whose name, \"Spring WebFlux,\" is also based on its source module\n-({spring-framework-main-code}/spring-webflux[`spring-webflux`]).\n+({spring-framework-code}/spring-webflux[`spring-webflux`]).\n This chapter covers Spring Web MVC. For reactive-stack web applications, see \n xref:web-reactive.adoc[Web on Reactive Stack].\n \n For baseline information and compatibility with Servlet container and Jakarta EE version\n ranges, see the Spring Framework\n-https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions[Wiki].\n+{spring-framework-wiki}/Spring-Framework-Versions[Wiki].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\nindex 27629d92a77b..77c222a5c65c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/filters.adoc\n@@ -84,7 +84,7 @@ See xref:web/webmvc/mvc-caching.adoc[HTTP Caching].\n \n This filter has a `writeWeakETag` parameter that configures the filter to write weak ETags\n similar to the following: `W/\"02a2d595e6ed9a0b24f027f2b63b134d6\"` (as defined in\n-https://tools.ietf.org/html/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n+{rfc-site}/rfc7232#section-2.3[RFC 7232 Section 2.3]).\n \n In order to support xref:web/webmvc/mvc-ann-async.adoc[asynchronous requests] this filter must be mapped\n with `DispatcherType.ASYNC` so that the filter can delay and successfully generate an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\nindex 8f4c06f25b56..11816910ad7e 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc\n@@ -137,7 +137,7 @@ Here is a very concise overview of Servlet asynchronous request processing:\n asynchronously produced return value from the `Callable`.\n \n For further background and context, you can also read\n-https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n+{spring-site-blog}/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support[the\n blog posts] that introduced asynchronous request processing support in Spring MVC 3.2.\n \n \n@@ -165,11 +165,11 @@ processing (instead of `postHandle` and `afterCompletion`).\n `HandlerInterceptor` implementations can also register a `CallableProcessingInterceptor`\n or a `DeferredResultProcessingInterceptor`, to integrate more deeply with the\n lifecycle of an asynchronous request (for example, to handle a timeout event). See\n-{api-spring-framework}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n+{spring-framework-api}/web/servlet/AsyncHandlerInterceptor.html[`AsyncHandlerInterceptor`]\n for more details.\n \n `DeferredResult` provides `onTimeout(Runnable)` and `onCompletion(Runnable)` callbacks.\n-See the {api-spring-framework}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n+See the {spring-framework-api}/web/context/request/async/DeferredResult.html[javadoc of `DeferredResult`]\n for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional\n methods for timeout and completion callbacks.\n \n@@ -399,7 +399,7 @@ Applications can also return `Flux` or `Observable>`.\n \n TIP: Spring MVC supports Reactor and RxJava through the\n-{api-spring-framework}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n+{spring-framework-api}/core/ReactiveAdapterRegistry.html[`ReactiveAdapterRegistry`] from\n `spring-core`, which lets it adapt from multiple reactive libraries.\n \n For streaming to the response, reactive back pressure is supported, but writes to the\n@@ -420,7 +420,7 @@ across multiple threads. The Micrometer\n https://github.com/micrometer-metrics/context-propagation#context-propagation-library[Context Propagation]\n library simplifies context propagation across threads, and across context mechanisms such\n as `ThreadLocal` values,\n-Reactor https://projectreactor.io/docs/core/release/reference/#context[context],\n+Reactor {reactor-site}/docs/core/release/reference/#context[context],\n GraphQL Java https://www.graphql-java.com/documentation/concerns/#context-objects[context],\n and others.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\nindex 245e370d5200..66bfbc0e7650 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc\n@@ -5,7 +5,7 @@\n \n A common requirement for REST services is to include details in the body of error\n responses. The Spring Framework supports the \"Problem Details for HTTP APIs\"\n-specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].\n+specification, {rfc-site}/rfc7807[RFC 7807].\n \n The following are the main abstractions for this support:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\nindex f011bad15660..2ae6c92f6c96 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-caching.adoc\n@@ -19,16 +19,16 @@ This section describes the HTTP caching-related options that are available in Sp\n == `CacheControl`\n [.small]#xref:web/webflux/caching.adoc#webflux-caching-cachecontrol[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for\n+{spring-framework-api}/http/CacheControl.html[`CacheControl`] provides support for\n configuring settings related to the `Cache-Control` header and is accepted as an argument\n in a number of places:\n \n-* {api-spring-framework}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n-* {api-spring-framework}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n+* {spring-framework-api}/web/servlet/mvc/WebContentInterceptor.html[`WebContentInterceptor`]\n+* {spring-framework-api}/web/servlet/support/WebContentGenerator.html[`WebContentGenerator`]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-etag-lastmodified[Controllers]\n * xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[Static Resources]\n \n-While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible\n+While {rfc-site}/rfc7234#section-5.2.2[RFC 7234] describes all possible\n directives for the `Cache-Control` response header, the `CacheControl` type takes a\n use case-oriented approach that focuses on the common scenarios:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\nindex 1ead038524e0..fb1abadc4aca 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc\n@@ -5,14 +5,13 @@\n \n You can set the `HttpMessageConverter` instances to use in Java configuration,\n replacing the ones used by default, by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`].\n You can also customize the list of configured message converters at the end by overriding\n-{api-spring-framework}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n+{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`].\n \n TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any\n `HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a\n-Boot application, prefer to use the\n-https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html[HttpMessageConverters]\n+Boot application, prefer to use the {spring-boot-docs}/web.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters]\n mechanism. Or alternatively, use `extendMessageConverters` to modify message converters\n at the end.\n \n@@ -60,24 +59,24 @@ Kotlin::\n ======\n \n In the preceding example,\n-{api-spring-framework}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n+{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`]\n is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and\n `MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format,\n and the registration of\n-https://github.com/FasterXML/jackson-module-parameter-names[`jackson-module-parameter-names`],\n+{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`],\n Which adds support for accessing parameter names (a feature added in Java 8).\n \n This builder customizes Jackson's default properties as follows:\n \n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n-* https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled.\n+* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled.\n \n It also automatically registers the following well-known modules if they are detected on the classpath:\n \n-* https://github.com/FasterXML/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n-* https://github.com/FasterXML/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n-* https://github.com/FasterXML/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n-* https://github.com/FasterXML/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n+* {jackson-github-org}/jackson-datatype-joda[jackson-datatype-joda]: Support for Joda-Time types.\n+* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types.\n+* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`.\n+* {jackson-github-org}/jackson-module-kotlin[`jackson-module-kotlin`]: Support for Kotlin classes and data classes.\n \n NOTE: Enabling indentation with Jackson XML support requires\n https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`]\n@@ -86,7 +85,7 @@ dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jac\n Other interesting Jackson modules are available:\n \n * https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module).\n-* https://github.com/FasterXML/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n+* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects).\n \n The following example shows how to achieve the same configuration in XML:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\nindex eff9db98d660..989ad29c0c5a 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/path-matching.adoc\n@@ -5,7 +5,7 @@\n \n You can customize options related to path matching and treatment of the URL.\n For details on the individual options, see the\n-{api-spring-framework}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n+{spring-framework-api}/web/servlet/config/annotation/PathMatchConfigurer.html[`PathMatchConfigurer`] javadoc.\n \n The following example shows how to customize path matching in Java configuration:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\nindex adb887831e97..e56686152863 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc\n@@ -4,7 +4,7 @@\n [.small]#xref:web/webflux/config.adoc#webflux-config-static-resources[See equivalent in the Reactive stack]#\n \n This option provides a convenient way to serve static resources from a list of\n-{api-spring-framework}/core/io/Resource.html[`Resource`]-based locations.\n+{spring-framework-api}/core/io/Resource.html[`Resource`]-based locations.\n \n In the next example, given a request that starts with `/resources`, the relative path is\n used to find and serve static resources relative to `/public` under the web application\n@@ -64,8 +64,8 @@ See also\n xref:web/webmvc/mvc-caching.adoc#mvc-caching-static-resources[HTTP caching support for static resources].\n \n The resource handler also supports a chain of\n-{api-spring-framework}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n-{api-spring-framework}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n+{spring-framework-api}/web/servlet/resource/ResourceResolver.html[`ResourceResolver`] implementations and\n+{spring-framework-api}/web/servlet/resource/ResourceTransformer.html[`ResourceTransformer`] implementations,\n which you can use to create a toolchain for working with optimized resources.\n \n You can use the `VersionResourceResolver` for versioned resource URLs based on an MD5 hash\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\nindex 112361f7dba1..e893eaa75832 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller.adoc\n@@ -47,7 +47,7 @@ Kotlin::\n In the preceding example, the method accepts a `Model` and returns a view name as a `String`,\n but many other options exist and are explained later in this chapter.\n \n-TIP: Guides and tutorials on https://spring.io/guides[spring.io] use the annotation-based\n+TIP: Guides and tutorials on {spring-site-guides}[spring.io] use the annotation-based\n programming model described in this section.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\nindex 46726f71ad24..90f206a7c44d 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-advice.adoc\n@@ -62,7 +62,7 @@ Kotlin::\n \n The selectors in the preceding example are evaluated at runtime and may negatively impact\n performance if used extensively. See the\n-{api-spring-framework}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n+{spring-framework-api}/web/bind/annotation/ControllerAdvice.html[`@ControllerAdvice`]\n javadoc for more details.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\nindex 73af9fa6ce46..1e0fa2173b79 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-exceptionhandler.adoc\n@@ -271,7 +271,7 @@ see xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses]\n \n | Any other return value\n | If a return value is not matched to any of the above and is not a simple type (as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n by default, it is treated as a model attribute to be added to the model. If it is a simple type,\n it remains unresolved.\n |===\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\nindex d1509896fea8..4e3b30ea3c09 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/arguments.adoc\n@@ -135,7 +135,7 @@ and others) and is equivalent to `required=false`.\n | Any other argument\n | If a method argument is not matched to any of the earlier values in this table and it is\n a simple type (as determined by\n-\t{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n+\t{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]),\n it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\nindex 3ea43c3e9713..b0522fdb773c 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/jackson.adoc\n@@ -8,7 +8,7 @@ Spring offers support for the Jackson JSON library.\n [.small]#xref:web/webflux/controller/ann-methods/jackson.adoc#webflux-ann-jsonview[See equivalent in the Reactive stack]#\n \n Spring MVC provides built-in support for\n-https://www.baeldung.com/jackson-json-view-annotation[Jackson's Serialization Views],\n+{baeldung-blog}/jackson-json-view-annotation[Jackson's Serialization Views],\n which allow rendering only a subset of all fields in an `Object`. To use it with\n `@ResponseBody` or `ResponseEntity` controller methods, you can use Jackson's\n `@JsonView` annotation to activate a serialization view class, as the following example shows:\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\nindex 83171fc4f036..c96b15a35297 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/matrix-variables.adoc\n@@ -3,7 +3,7 @@\n \n [.small]#xref:web/webflux/controller/ann-methods/matrix-variables.adoc[See equivalent in the Reactive stack]#\n \n-https://tools.ietf.org/html/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n+{rfc-site}/rfc3986#section-3.3[RFC 3986] discusses name-value pairs in\n path segments. In Spring MVC, we refer to those as \"`matrix variables`\" based on an\n https://www.w3.org/DesignIssues/MatrixURIs.html[\"`old post`\"] by Tim Berners-Lee, but they\n can be also be referred to as URI path parameters.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\nindex 02e314974ab1..0e15b5448cc3 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc\n@@ -242,5 +242,5 @@ xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation].\n \n TIP: Using `@ModelAttribute` is optional. By default, any parameter that is not a simple\n value type as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty]\n _AND_ that is not resolved by any other argument resolver is treated as an `@ModelAttribute`.\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\nindex ae5e3a0ed4c7..3486beeb3b07 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc\n@@ -75,7 +75,7 @@ then the map is populated with the request parameter values for each given param\n \n Note that use of `@RequestParam` is optional (for example, to set its attributes).\n By default, any argument that is a simple value type (as determined by\n-{api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n+{spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty])\n and is not resolved by any other argument resolver, is treated as if it were annotated\n with `@RequestParam`.\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\nindex 266d6ee1aaae..79f4588dbedc 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/return-types.adoc\n@@ -98,7 +98,7 @@ supported for all return values.\n | Other return values\n | If a return value remains unresolved in any other way, it is treated as a model\n attribute, unless it is a simple type as determined by\n- {api-spring-framework}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n+ {spring-framework-api}/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-[BeanUtils#isSimpleProperty],\n in which case it remains unresolved.\n |===\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\nindex 0f58a97dd8d6..c034514f2760 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-modelattrib-methods.adoc\n@@ -76,7 +76,7 @@ Kotlin::\n \n \n NOTE: When a name is not explicitly specified, a default name is chosen based on the `Object`\n-type, as explained in the javadoc for {api-spring-framework}/core/Conventions.html[`Conventions`].\n+type, as explained in the javadoc for {spring-framework-api}/core/Conventions.html[`Conventions`].\n You can always assign an explicit name by using the overloaded `addAttribute` method or\n through the `name` attribute on `@ModelAttribute` (for a return value).\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\nindex 932c2f6b1419..aab730895f72 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc\n@@ -104,8 +104,8 @@ at the end of a path. `PathPattern` also restricts the use of `+**+` for matchin\n path segments such that it's only allowed at the end of a pattern. This eliminates many\n cases of ambiguity when choosing the best matching pattern for a given request.\n For full pattern syntax please refer to\n-{api-spring-framework}/web/util/pattern/PathPattern.html[PathPattern] and\n-{api-spring-framework}/util/AntPathMatcher.html[AntPathMatcher].\n+{spring-framework-api}/web/util/pattern/PathPattern.html[PathPattern] and\n+{spring-framework-api}/util/AntPathMatcher.html[AntPathMatcher].\n \n Some example patterns:\n \n@@ -226,8 +226,8 @@ some external configuration.\n When multiple patterns match a URL, the best match must be selected. This is done with\n one of the following depending on whether use of parsed `PathPattern` is enabled for use or not:\n \n-* {api-spring-framework}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n-* {api-spring-framework}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n+* {spring-framework-api}/web/util/pattern/PathPattern.html#SPECIFICITY_COMPARATOR[`PathPattern.SPECIFICITY_COMPARATOR`]\n+* {spring-framework-api}/util/AntPathMatcher.html#getPatternComparator-java.lang.String-[`AntPathMatcher.getPatternComparator(String path)`]\n \n Both help to sort patterns with more specific ones on top. A pattern is more specific if\n it has a lower count of URI variables (counted as 1), single wildcards (counted as 1),\n@@ -296,7 +296,7 @@ Many common path extensions are allowed as safe by default. Applications with cu\n negotiation to avoid having a `Content-Disposition` header added for those extensions.\n See xref:web/webmvc/mvc-config/content-negotiation.adoc[Content Types].\n \n-See https://pivotal.io/security/cve-2015-5211[CVE-2015-5211] for additional\n+See {spring-site-cve}/cve-2015-5211[CVE-2015-5211] for additional\n recommendations related to RFD.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\nindex a1528b55343f..923e024f8648 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc\n@@ -17,7 +17,7 @@ raise `MethodArgumentNotValidException` in case of validation errors. If you wan\n the errors in the controller method instead, you can declare an `Errors` or `BindingResult`\n method parameter immediately after the validated parameter.\n \n-Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method\n+Second, if {bean-validation-site}[Java Bean Validation] is present _AND_ other method\n parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint`\n annotations, then method validation is applied to all method arguments, raising\n `HandlerMethodValidationException` in case of validation errors. You can still declare an\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\nindex 17a10e537f7f..da03fba9b4a1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-http2.adoc\n@@ -8,7 +8,7 @@ Servlet 4 containers are required to support HTTP/2, and Spring Framework 5 is c\n with Servlet API 4. From a programming model perspective, there is nothing specific that\n applications need to do. However, there are considerations related to server configuration.\n For more details, see the\n-https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support[HTTP/2 wiki page].\n+{spring-framework-wiki}/HTTP-2-support[HTTP/2 wiki page].\n \n The Servlet API does expose one construct related to HTTP/2. You can use the\n `jakarta.servlet.http.PushBuilder` to proactively push resources to clients, and it\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\nindex 5b6aca1f70ad..446ae42c0414 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc\n@@ -4,7 +4,7 @@\n \n [.small]#xref:web/webflux/security.adoc[See equivalent in the Reactive stack]#\n \n-The https://spring.io/projects/spring-security[Spring Security] project provides support\n+The {spring-site-projects}/spring-security[Spring Security] project provides support\n for protecting web applications from malicious exploits. See the Spring Security\n reference documentation, including:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\nindex 173ee07e6797..189ae02988e1 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet.adoc\n@@ -70,7 +70,7 @@ NOTE: In addition to using the ServletContext API directly, you can also extend\n \n NOTE: For programmatic use cases, a `GenericWebApplicationContext` can be used as an\n alternative to `AnnotationConfigWebApplicationContext`. See the\n-{api-spring-framework}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n+{spring-framework-api}/web/context/support/GenericWebApplicationContext.html[`GenericWebApplicationContext`]\n javadoc for details.\n \n The following example of `web.xml` configuration registers and initializes the `DispatcherServlet`:\n@@ -111,7 +111,7 @@ the lifecycle of the Servlet container, Spring Boot uses Spring configuration to\n bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations\n are detected in Spring configuration and registered with the Servlet container.\n For more details, see the\n-https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container[Spring Boot documentation].\n+{spring-boot-docs}/web.html#web.servlet.embedded-container[Spring Boot documentation].\n \n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\nindex 64fcc6e1be63..2a8950c073fe 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/config.adoc\n@@ -8,7 +8,7 @@ Applications can declare the infrastructure beans listed in xref:web/webmvc/mvc-\n that are required to process requests. The `DispatcherServlet` checks the\n `WebApplicationContext` for each special bean. If there are no matching bean types,\n it falls back on the default types listed in\n-{spring-framework-main-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n+{spring-framework-code}/spring-webmvc/src/main/resources/org/springframework/web/servlet/DispatcherServlet.properties[`DispatcherServlet.properties`].\n \n In most cases, the xref:web/webmvc/mvc-config.adoc[MVC Config] is the best starting point. It declares the required\n beans in either Java or XML and provides a higher-level configuration callback API to\ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\nindex 23e8587b3bde..01cab7f3b7ed 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/exceptionhandlers.adoc\n@@ -19,7 +19,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio\n | A mapping between exception class names and error view names. Useful for rendering\n error pages in a browser application.\n \n-| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n+| {spring-framework-api}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[`DefaultHandlerExceptionResolver`]\n | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.\n See also alternative `ResponseEntityExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses].\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\nindex 44844ba9a06b..d23200eb2a91 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/multipart.adoc\n@@ -75,7 +75,7 @@ This resolver variant uses your Servlet container's multipart parser as-is,\n potentially exposing the application to container implementation differences.\n By default, it will try to parse any `multipart/` content type with any HTTP\n method but this may not be supported across all Servlet containers. See the\n-{api-spring-framework}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n+{spring-framework-api}/web/multipart/support/StandardServletMultipartResolver.html[`StandardServletMultipartResolver`]\n javadoc for details and configuration options.\n ====\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\nindex b6728feb674f..27daeeb49137 100644\n--- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/viewresolver.adoc\n@@ -32,7 +32,7 @@ The following table provides more details on the `ViewResolver` hierarchy:\n | Convenient subclass of `UrlBasedViewResolver` that supports `InternalResourceView` (in\n effect, Servlets and JSPs) and subclasses such as `JstlView`. You can specify the view\n class for all views generated by this resolver by using `setViewClass(..)`.\n- See the {api-spring-framework}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n+ See the {spring-framework-api}/web/reactive/result/view/UrlBasedViewResolver.html[`UrlBasedViewResolver`]\n javadoc for details.\n \n | `FreeMarkerViewResolver`\n@@ -103,7 +103,7 @@ Servlet/JSP engine. Note that you may also chain multiple view resolvers, instea\n == Content Negotiation\n [.small]#xref:web/webflux/dispatcher-handler.adoc#webflux-multiple-representations[See equivalent in the Reactive stack]#\n \n-{api-spring-framework}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n+{spring-framework-api}/web/servlet/view/ContentNegotiatingViewResolver.html[`ContentNegotiatingViewResolver`]\n does not resolve views itself but rather delegates\n to other view resolvers and selects the view that resembles the representation requested\n by the client. The representation can be determined from the `Accept` header or from a\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\nindex f565c2250a10..d929c7f985fd 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc\n@@ -23,20 +23,20 @@ change application code.\n \n SockJS consists of:\n \n-* The https://github.com/sockjs/sockjs-protocol[SockJS protocol]\n+* The {sockjs-protocol}[SockJS protocol]\n defined in the form of executable\n-https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tests].\n-* The https://github.com/sockjs/sockjs-client/[SockJS JavaScript client] -- a client library for use in browsers.\n+{sockjs-protocol-site}/sockjs-protocol-0.3.3.html[narrated tests].\n+* The {sockjs-client}[SockJS JavaScript client] -- a client library for use in browsers.\n * SockJS server implementations, including one in the Spring Framework `spring-websocket` module.\n * A SockJS Java client in the `spring-websocket` module (since version 4.1).\n \n SockJS is designed for use in browsers. It uses a variety of techniques\n to support a wide range of browser versions.\n For the full list of SockJS transport types and browsers, see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page. Transports\n+{sockjs-client}[SockJS client] page. Transports\n fall in three general categories: WebSocket, HTTP Streaming, and HTTP Long Polling.\n For an overview of these categories, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n The SockJS client begins by sending `GET /info` to\n obtain basic information from the server. After that, it must decide what transport\n@@ -130,13 +130,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket\n and SockJS support does not depend on Spring MVC. It is relatively simple to\n integrate into other HTTP serving environments with the help of\n-{api-spring-framework}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n+{spring-framework-api}/web/socket/sockjs/support/SockJsHttpRequestHandler.html[`SockJsHttpRequestHandler`].\n \n On the browser side, applications can use the\n-https://github.com/sockjs/sockjs-client/[`sockjs-client`] (version 1.0.x). It\n+{sockjs-client}[`sockjs-client`] (version 1.0.x). It\n emulates the W3C WebSocket API and communicates with the server to select the best\n transport option, depending on the browser in which it runs. See the\n-https://github.com/sockjs/sockjs-client/[sockjs-client] page and the list of\n+{sockjs-client}[sockjs-client] page and the list of\n transport types supported by browser. The client also provides several\n configuration options -- for example, to specify which transports to include.\n \n@@ -183,7 +183,7 @@ but can be configured to do so. In the future, it may set it by default.\n See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]\n of the Spring Security documentation for details on how to configure the\n setting of the `X-Frame-Options` header. You can also see\n-https://github.com/spring-projects/spring-security/issues/2718[gh-2718]\n+{spring-github-org}/spring-security/issues/2718[gh-2718]\n for additional background.\n ====\n \n@@ -219,7 +219,7 @@ The XML namespace provides a similar option through the `` ele\n NOTE: During initial development, do enable the SockJS client `devel` mode that prevents\n the browser from caching SockJS requests (like the iframe) that would otherwise\n be cached. For details on how to enable it see the\n-https://github.com/sockjs/sockjs-client/[SockJS client] page.\n+{sockjs-client}[SockJS client] page.\n \n \n \n@@ -231,7 +231,7 @@ from concluding that a connection is hung. The Spring SockJS configuration has a\n called `heartbeatTime` that you can use to customize the frequency. By default, a\n heartbeat is sent after 25 seconds, assuming no other messages were sent on that\n connection. This 25-second value is in line with the following\n-https://tools.ietf.org/html/rfc6202[IETF recommendation] for public Internet applications.\n+{rfc-site}/rfc6202[IETF recommendation] for public Internet applications.\n \n NOTE: When using STOMP over WebSocket and SockJS, if the STOMP client and server negotiate\n heartbeats to be exchanged, the SockJS heartbeats are disabled.\n@@ -248,7 +248,7 @@ should consider customizing the settings according to your specific needs.\n \n HTTP streaming and HTTP long polling SockJS transports require a connection to remain\n open longer than usual. For an overview of these techniques, see\n-https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n+{spring-site-blog}/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/[this blog post].\n \n In Servlet containers, this is done through Servlet 3 asynchronous support that\n allows exiting the Servlet container thread, processing a request, and continuing\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\nindex 5fc4da352e64..c9e6fa2b5d8f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc\n@@ -84,13 +84,13 @@ The preceding example is for use in Spring MVC applications and should be includ\n in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's\n WebSocket support does not depend on Spring MVC. It is relatively simple to\n integrate a `WebSocketHandler` into other HTTP-serving environments with the help of\n-{api-spring-framework}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n+{spring-framework-api}/web/socket/server/support/WebSocketHttpRequestHandler.html[`WebSocketHttpRequestHandler`].\n \n When using the `WebSocketHandler` API directly vs indirectly, e.g. through the\n xref:web/websocket/stomp.adoc[STOMP] messaging, the application must synchronize the sending of messages\n since the underlying standard WebSocket session (JSR-356) does not allow concurrent\n sending. One option is to wrap the `WebSocketSession` with\n-{api-spring-framework}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n+{spring-framework-api}/web/socket/handler/ConcurrentWebSocketSessionDecorator.html[`ConcurrentWebSocketSessionDecorator`].\n \n \n \n@@ -315,7 +315,7 @@ As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is t\n only same-origin requests. It is also possible to allow all or a specified list of origins.\n This check is mostly designed for browser clients. Nothing prevents other types\n of clients from modifying the `Origin` header value (see\n-https://tools.ietf.org/html/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n+{rfc-site}/rfc6454[RFC 6454: The Web Origin Concept] for more details).\n \n The three possible behaviors are:\n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\nindex 3ab57f8c878e..3bacb4a4907f 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc\n@@ -1,7 +1,7 @@\n [[websocket-stomp-authentication-token-based]]\n = Token Authentication\n \n-https://github.com/spring-projects/spring-security-oauth[Spring Security OAuth]\n+{spring-github-org}/spring-security-oauth[Spring Security OAuth]\n provides support for token based security, including JSON Web Token (JWT).\n You can use this as the authentication mechanism in Web applications,\n including STOMP over WebSocket interactions, as described in the previous\n@@ -11,13 +11,13 @@ At the same time, cookie-based sessions are not always the best fit (for example\n in applications that do not maintain a server-side session or in\n mobile applications where it is common to use headers for authentication).\n \n-The https://tools.ietf.org/html/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n+The {rfc-site}/rfc6455#section-10.5[WebSocket protocol, RFC 6455]\n \"doesn't prescribe any particular way that servers can authenticate clients during\n the WebSocket handshake.\" In practice, however, browser clients can use only standard\n authentication headers (that is, basic HTTP authentication) or cookies and cannot (for example)\n provide custom headers. Likewise, the SockJS JavaScript client does not provide\n a way to send HTTP headers with SockJS transport requests. See\n-https://github.com/sockjs/sockjs-client/issues/196[sockjs-client issue 196].\n+{sockjs-client}/issues/196[sockjs-client issue 196].\n Instead, it does allow sending query parameters that you can use to send a token,\n but that has its own drawbacks (for example, the token may be inadvertently\n logged with the URL in server logs).\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\nindex 5866ec3dc521..95af447e597e 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authorization.adoc\n@@ -6,7 +6,7 @@ Spring Security provides\n {docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]\n that uses a `ChannelInterceptor` to authorize messages based on the user header in them.\n Also, Spring Session provides\n-https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]\n+{docs-spring-session}/web-socket.html[WebSocket integration]\n that ensures the user's HTTP session does not expire while the WebSocket session is still active.\n \n \ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\nindex 8ff62f4c6752..433043984338 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc\n@@ -91,7 +91,7 @@ and xref:web/websocket/stomp/authentication.adoc[Authentication] for more inform\n \n For more example code see:\n \n-* https://spring.io/guides/gs/messaging-stomp-websocket/[Using WebSocket to build an\n+* {spring-site-guides}/gs/messaging-stomp-websocket/[Using WebSocket to build an\n interactive web application] -- a getting started guide.\n * https://github.com/rstoyanchev/spring-websocket-portfolio[Stock Portfolio] -- a sample\n application.\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\nindex 8db28f6dd504..8a59bd83f937 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc\n@@ -59,7 +59,7 @@ The following example shows the XML configuration equivalent of the preceding ex\n ----\n \n The STOMP broker relay in the preceding configuration is a Spring\n-{api-spring-framework}/messaging/MessageHandler.html[`MessageHandler`]\n+{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]\n that handles messages by forwarding them to an external message broker.\n To do so, it establishes TCP connections to the broker, forwards all messages to it,\n and then forwards all messages received from the broker to clients through their\ndiff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\nindex 275ab0a27bd0..1c4e3adb52c0 100644\n--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc\n@@ -7,18 +7,18 @@ connected clients. This section describes the flow of messages on the server sid\n The `spring-messaging` module contains foundational support for messaging applications\n that originated in https://spring.io/spring-integration[Spring Integration] and was\n later extracted and incorporated into the Spring Framework for broader use across many\n-https://spring.io/projects[Spring projects] and application scenarios.\n+{spring-site-projects}[Spring projects] and application scenarios.\n The following list briefly describes a few of the available messaging abstractions:\n \n-* {api-spring-framework}/messaging/Message.html[Message]:\n+* {spring-framework-api}/messaging/Message.html[Message]:\n Simple representation for a message, including headers and payload.\n-* {api-spring-framework}/messaging/MessageHandler.html[MessageHandler]:\n+* {spring-framework-api}/messaging/MessageHandler.html[MessageHandler]:\n Contract for handling a message.\n-* {api-spring-framework}/messaging/MessageChannel.html[MessageChannel]:\n+* {spring-framework-api}/messaging/MessageChannel.html[MessageChannel]:\n Contract for sending a message that enables loose coupling between producers and consumers.\n-* {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel]:\n+* {spring-framework-api}/messaging/SubscribableChannel.html[SubscribableChannel]:\n `MessageChannel` with `MessageHandler` subscribers.\n-* {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n+* {spring-framework-api}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]:\n `SubscribableChannel` that uses an `Executor` for delivering messages.\n \n Both the Java configuration (that is, `@EnableWebSocketMessageBroker`) and the XML namespace configuration\ndiff --git a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\nindex 37cbba42d8bf..9ba46a5f832a 100644\n--- a/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/forwarded-headers.adoc\n@@ -2,7 +2,7 @@ As a request goes through proxies such as load balancers the host, port, and\n scheme may change, and that makes it a challenge to create links that point to the correct\n host, port, and scheme from a client perspective.\n \n-https://tools.ietf.org/html/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n+{rfc-site}/rfc7239[RFC 7239] defines the `Forwarded` HTTP header\n that proxies can use to provide information about the original request.\n \n \ndiff --git a/framework-docs/modules/ROOT/partials/web/web-uris.adoc b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\nindex d6e94cec95dc..a8bde952e68e 100644\n--- a/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/web-uris.adoc\n@@ -240,9 +240,9 @@ Kotlin::\n \n `UriComponentsBuilder` exposes encoding options at two levels:\n \n-* {api-spring-framework}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n+* {spring-framework-api}/web/util/UriComponentsBuilder.html#encode--[UriComponentsBuilder#encode()]:\n Pre-encodes the URI template first and then strictly encodes URI variables when expanded.\n-* {api-spring-framework}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n+* {spring-framework-api}/web/util/UriComponents.html#encode--[UriComponents#encode()]:\n Encodes URI components _after_ URI variables are expanded.\n \n Both options replace non-ASCII and illegal characters with escaped octets. However, the first option\ndiff --git a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\nindex 339aea089be8..8598a214be91 100644\n--- a/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n+++ b/framework-docs/modules/ROOT/partials/web/websocket-intro.adoc\n@@ -1,7 +1,7 @@\n [[introduction-to-websocket]]\n = Introduction to WebSocket\n \n-The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized\n+The WebSocket protocol, {rfc-site}/rfc6455[RFC 6455], provides a standardized\n way to establish a full-duplex, two-way communication channel between client and server\n over a single TCP connection. It is a different TCP protocol from HTTP but is designed to\n work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.\ndiff --git a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties b/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\ndeleted file mode 100644\nindex e1e20afb8446..000000000000\n--- a/framework-docs/src/docs/asciidoc/anchor-rewrite.properties\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-aot=core.aot\n-aot-basics=core.aot.basics\n-aot-refresh=core.aot.refresh\n-aot-bean-factory-initialization-contributions=core.aot.bean-factory-initialization-contributions\n-aot-bean-registration-contributions=core.aot.bean-registration-contributions\n-aot-hints=core.aot.hints\n-aot-hints-import-runtime-hints=core.aot.hints.import-runtime-hints\n-aot-hints-reflective=core.aot.hints.reflective\n-aot-hints-register-reflection-for-binding=core.aot.hints.register-reflection-for-binding\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/DataAccessException.png b/framework-docs/src/docs/asciidoc/images/DataAccessException.png\ndeleted file mode 100644\nindex 746f17399b99..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/DataAccessException.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png\ndeleted file mode 100644\nindex de6be86ed543..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png b/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png\ndeleted file mode 100644\nindex 8ece077d3445..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/aop-proxy-plain-pojo-call.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/container-magic.png b/framework-docs/src/docs/asciidoc/images/container-magic.png\ndeleted file mode 100644\nindex 2628e59b00e8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/container-magic.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png b/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png\ndeleted file mode 100644\nindex 3cf93fa1439c..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-broker-relay.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png b/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png\ndeleted file mode 100644\nindex 9afd54f57c23..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/message-flow-simple-broker.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png\ndeleted file mode 100644\nindex 9c4a950caadb..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg b/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\ndeleted file mode 100644\nindex 07148744b549..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/mvc-context-hierarchy.svg\n+++ /dev/null\n@@ -1,612 +0,0 @@\n-\n-\n-\n-image/svg+xmlPage-1DispatcherServlet\n-Servlet WebApplicationContext\n-(containing controllers, view resolvers,and other web-related beans)\n-Controllers\n-ViewResolver\n-HandlerMapping\n-Root WebApplicationContext\n-(containing middle-tier services, datasources, etc.)\n-Services\n-Repositories\n-Delegates if no bean found\n-\n\\ No newline at end of file\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\ndeleted file mode 100644\nindex 4b72bf45285b..000000000000\n--- a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.graffle\n+++ /dev/null\n@@ -1,1619 +0,0 @@\n-\n-\n-\n-\n-\tActiveLayerIndex\n-\t0\n-\tApplicationVersion\n-\t\n-\t\tcom.omnigroup.OmniGraffle\n-\t\t137.11.0.108132\n-\t\n-\tAutoAdjust\n-\t\n-\tBackgroundGraphic\n-\t\n-\t\tBounds\n-\t\t{{0, 0}, {756, 553}}\n-\t\tClass\n-\t\tSolidGraphic\n-\t\tID\n-\t\t2\n-\t\tStyle\n-\t\t\n-\t\t\tshadow\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\tstroke\n-\t\t\t\n-\t\t\t\tDraws\n-\t\t\t\tNO\n-\t\t\t\n-\t\t\n-\t\n-\tCanvasOrigin\n-\t{0, 0}\n-\tColumnAlign\n-\t1\n-\tColumnSpacing\n-\t36\n-\tCreationDate\n-\t2009-09-11 10:15:26 -0400\n-\tCreator\n-\tThomas Risberg\n-\tDisplayScale\n-\t1 0/72 in = 1 0/72 in\n-\tGraphDocumentVersion\n-\t6\n-\tGraphicsList\n-\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t42\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{334.726, 144}\n-\t\t\t\t{394.042, 102.288}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t41\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{489.5, 143.713}\n-\t\t\t\t{430.452, 102.287}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t40\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{230, 217}\n-\t\t\t\t{275.683, 175.337}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tClass\n-\t\t\tLineGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tHead\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t4\n-\t\t\t\n-\t\t\tID\n-\t\t\t39\n-\t\t\tPoints\n-\t\t\t\n-\t\t\t\t{430.381, 216.81}\n-\t\t\t\t{329.369, 175.19}\n-\t\t\t\n-\t\t\tStyle\n-\t\t\t\n-\t\t\t\tstroke\n-\t\t\t\t\n-\t\t\t\t\tHeadArrow\n-\t\t\t\t\tFilledArrow\n-\t\t\t\t\tTailArrow\n-\t\t\t\t\t0\n-\t\t\t\t\n-\t\t\t\n-\t\t\tTail\n-\t\t\t\n-\t\t\t\tID\n-\t\t\t\t5\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{56, 217}, {249, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t6\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{325.5, 217}, {283.5, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t5\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 UnmarshallingFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{184, 145}, {217, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t4\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 MarshallingException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{430, 145}, {239, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t3\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\fs36 \\cf0 ValidationFailureException}\n-\t\t\t\n-\t\t\n-\t\t\n-\t\t\tBounds\n-\t\t\t{{294, 72}, {244, 30}}\n-\t\t\tClass\n-\t\t\tShapedGraphic\n-\t\t\tFontInfo\n-\t\t\t\n-\t\t\t\tFont\n-\t\t\t\tHelvetica\n-\t\t\t\tSize\n-\t\t\t\t18\n-\t\t\t\n-\t\t\tID\n-\t\t\t1\n-\t\t\tShape\n-\t\t\tRectangle\n-\t\t\tStyle\n-\t\t\t\n-\t\t\tText\n-\t\t\t\n-\t\t\t\tText\n-\t\t\t\t{\\rtf1\\ansi\\ansicpg1252\\cocoartf949\\cocoasubrtf540\n-{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n-{\\colortbl;\\red255\\green255\\blue255;}\n-\\deftab720\n-\\pard\\pardeftab720\\qc\n-\n-\\f0\\i\\fs36 \\cf0 XmlMappingException}\n-\t\t\t\n-\t\t\tWrap\n-\t\t\tNO\n-\t\t\n-\t\n-\tGridInfo\n-\t\n-\tGuidesLocked\n-\tNO\n-\tGuidesVisible\n-\tYES\n-\tHPages\n-\t1\n-\tImageCounter\n-\t1\n-\tKeepToScale\n-\t\n-\tLayers\n-\t\n-\t\t\n-\t\t\tLock\n-\t\t\tNO\n-\t\t\tName\n-\t\t\tLayer 1\n-\t\t\tPrint\n-\t\t\tYES\n-\t\t\tView\n-\t\t\tYES\n-\t\t\n-\t\n-\tLayoutInfo\n-\t\n-\t\tAnimate\n-\t\tNO\n-\t\tcircoMinDist\n-\t\t18\n-\t\tcircoSeparation\n-\t\t0.0\n-\t\tlayoutEngine\n-\t\tdot\n-\t\tneatoSeparation\n-\t\t0.0\n-\t\ttwopiSeparation\n-\t\t0.0\n-\t\n-\tLinksVisible\n-\tNO\n-\tMagnetsVisible\n-\tNO\n-\tMasterSheets\n-\t\n-\tModificationDate\n-\t2009-09-11 10:38:54 -0400\n-\tModifier\n-\tThomas Risberg\n-\tNotesVisible\n-\tNO\n-\tOrientation\n-\t2\n-\tOriginVisible\n-\tNO\n-\tPageBreaks\n-\tYES\n-\tPrintInfo\n-\t\n-\t\tNSBottomMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t41\n-\t\t\n-\t\tNSLeftMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSOrientation\n-\t\t\n-\t\t\tint\n-\t\t\t1\n-\t\t\n-\t\tNSPaperSize\n-\t\t\n-\t\t\tsize\n-\t\t\t{792, 612}\n-\t\t\n-\t\tNSRightMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\tNSTopMargin\n-\t\t\n-\t\t\tfloat\n-\t\t\t18\n-\t\t\n-\t\n-\tPrintOnePage\n-\t\n-\tQuickLookPreview\n-\t\n-\tJVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmls\n-\tdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGVlk1vG0cMhu/zK3h0Dx4Ph/N5rZsA\n-\tDRCgqdW0V0GVGhkryZGdoj+/L2e1q4W1cloLhhZrfr0PORx/pU/0lRw+OSaKUei4pt9p\n-\tT84m135oS3f3z0yrZ+L2eV7RrbPx9Nfz0ymAQYAN3f2yPq7WTy/flh0dt0jhU2ppoidf\n-\thIIkWu3o7ucd00+HVoRPPFgEriRJTG/hRwupgwVnUYtTDBksxI1ZhION5Csqb3mCGfLk\n-\tc56pQeyD3P267pYv27/X94fucNzu1i/H7Uo1+BooRCYfAonrZTJ9AJPHntD9Q6vO0cM9\n-\tBPdJbvVLsaIIDZAhv/kr5wfoBltvwNYRuDrAnngGThTADb4/LohLC3+L79tSbQwZDDMt\n-\toO49W4eEi425+WPXfVw+PW33f737RxuwPex/oMUjvVsg2ZtNDeJIciEPyoO+STGjDLXj\n-\tAHLNbqpDZ2RORwwol6S2hr5Swi7aUpVMr8SflNDN53PdkzLeilWj9d7ly1DLbvsnenrY\n-\tv19uu2/H9Ws05jtouKDlioYz0KjkzbRPIxq1a2ianY7I0OJraHz1PZq5Jkc0WWqkbFqT\n-\tz2g+Lo/PX5Zd9/+7bMQjKkQkPYbt6bqc3lZFT20HSVenNmXrkcK3k/e63R6nMpZxcJsm\n-\ts9jQzW/73VnVlT59b4Sxwpqy8PYEw6yJamb/ZYC5YM2pIt1IrxWxWBdlZuomXZrTYy6O\n-\t5GTMx5HCabNSOKDiZIvDNOxIpNjowZdzsTVxNd0waG1P6zpv51CELXtsH8nZuhJzc85W\n-\tcvV4x9anINQhYLUpKY6MJNwCfsHbS+8NAn/A7+Ps/I8enKOtjNg7I3LKx4VtFtQwycfI\n-\tx6Uw3k3ynb2brNOSNXN4PI6j9hLbNRUrSQ9gwVC5gpA6qT4H6zP2i0qT4kszxWNI1UgW\n-\t6x2msYMdOOutU2zOIKYFzfleB6CzMXqosMTY9lpYnw3dqjaDyjkb9gU2VlAkk2yDr9lN\n-\t5c8CD3oRYOWIzQzYuFYxGTHhlcu2ZqhtFEwQZZJxgWEVJ48rRG3Ra5GId9hBudUVgutp\n-\thZBtKNI35sIblV3noJts9GAnmLaiHMZ8zM4G36gP+YxeA5FTbSTmvLWXw207NwgiwWaf\n-\twCKgOimYP8DoORSvhDWCYN2Ggk3eODD+OVBbNAFDg3fQrBwxoCXjQNRoGpsk/TzMeb/N\n-\tYfRoHHB8W22nfE2zL+1AnPJRYyOpn4gLb1SrKj79C2PwIN4KZW5kc3RyZWFtCmVuZG9i\n-\tago1IDAgb2JqCjkyNgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50\n-\tIDMgMCBSIC9SZXNvdXJjZXMgNiAwIFIgL0NvbnRlbnRzIDQgMCBSIC9NZWRpYUJveCBb\n-\tMCAwIDc1NiA1NTNdCj4+CmVuZG9iago2IDAgb2JqCjw8IC9Qcm9jU2V0IFsgL1BERiAv\n-\tVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9Db2xvclNwYWNlIDw8IC9DczIg\n-\tMTggMCBSCi9DczEgNyAwIFIgPj4gL0ZvbnQgPDwgL0YxLjAgMTkgMCBSIC9GMi4wIDIw\n-\tIDAgUiA+PiAvWE9iamVjdCA8PCAvSW0yIDEwIDAgUgovSW0zIDEyIDAgUiAvSW00IDE0\n-\tIDAgUiAvSW01IDE2IDAgUiAvSW0xIDggMCBSID4+ID4+CmVuZG9iagoxMCAwIG9iago8\n-\tPCAvTGVuZ3RoIDExIDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dp\n-\tZHRoIDUyMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQoyMSAwIFIgL1NNYXNrIDIyIDAg\n-\tUiAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVh\n-\tbQp4Ae3QMQEAAADCoPVPbQhfiEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM\n-\tGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB\n-\tAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg\n-\twIABAwYMGDBgwIABAwYMvAMDfE4AAQplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjcz\n-\tNAplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL1R5cGUgL1hPYmplY3Qg\n-\tL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA0NzggL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UK\n-\tMjQgMCBSIC9TTWFzayAyNSAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9G\n-\tbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T+1pCYhAYcCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOADA0auAAEKZW5kc3RyZWFtCmVuZG9iagox\n-\tMyAwIG9iago2NzQKZW5kb2JqCjE0IDAgb2JqCjw8IC9MZW5ndGggMTUgMCBSIC9UeXBl\n-\tIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNjEyIC9IZWlnaHQgMTA0IC9D\n-\tb2xvclNwYWNlCjI3IDAgUiAvU01hc2sgMjggMCBSIC9CaXRzUGVyQ29tcG9uZW50IDgg\n-\tL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4AiFUGHA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgIE/MOn+AAEKZW5kc3RyZWFtCmVuZG9iagoxNSAwIG9iago4NTYK\n-\tZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9YT2JqZWN0IC9T\n-\tdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTQyIC9IZWlnaHQgMTA0IC9Db2xvclNwYWNlCjMw\n-\tIDAgUiAvU01hc2sgMzEgMCBSIC9CaXRzUGVyQ29tcG9uZW50IDggL0ZpbHRlciAvRmxh\n-\tdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dAxAQAAAMKg9U9tCy+IQGHAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED\n-\tBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA\n-\tgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY\n-\tMGDAgAEDBgy8BwaUrgABCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKNzYxCmVuZG9i\n-\tago4IDAgb2JqCjw8IC9MZW5ndGggOSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUg\n-\tL0ltYWdlIC9XaWR0aCA1MzIgL0hlaWdodCAxMDQgL0NvbG9yU3BhY2UKMzMgMCBSIC9T\n-\tTWFzayAzNCAwIFIgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29k\n-\tZSA+PgpzdHJlYW0KeAHt0DEBAAAAwqD1T20KP4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG\n-\tDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA\n-\tAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw\n-\tYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMDAa2CIfgABCmVuZHN0\n-\tcmVhbQplbmRvYmoKOSAwIG9iago3NDcKZW5kb2JqCjIyIDAgb2JqCjw8IC9MZW5ndGgg\n-\tMjMgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTIyIC9I\n-\tZWlnaHQgMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50\n-\tIDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3tT1PZFsZBCqXvLZS2\n-\t9GVaTgvtaSmdY4sFCtM2bXhHFISpM0LQqhkYkNHYSAZ1MIwSiSI4EF6iyBDRgEPAECVG\n-\tzfxrd53CvXOFcrD3fto96/lATDYmez/rl7XXaTlrZWWh0AF0AB1AB9ABdAAdQAfQAXQA\n-\tHfh/HMhGZaADaREB5z/xj3JQGeHAPxE9AQH+CiD2KICzCwS5qIxzQCCA0LJQHAdDkoM9\n-\tCPKEwvw9iVDEO7AfSqEwD+AGHI5hYZ+D3Nw8gEAkFkskEqlUKkNlgAMQSAinWCzKz2dp\n-\t4GaBBSEH7gTAACCQyuRyhVKpQmWIA0qlQi6XAQ9igGGPhSOuiCQIkA9YDmRyhUpVUKhW\n-\tFxVpNFoU8Q5oNEVFanVhgUqlkMtYFiAvwBWRGgU2I7AJgeVACRRotLpivd5gNJpQxDtg\n-\tNBr0+mKdVgM0KJMsQFpgUUjxEJEEAQoEiRQ4AAyAAZPZYimhrKgMcIAqsVjMJuABYAAW\n-\tpBK2XEiNQjZbIwhFkBBUhRqdHiigrKVldgdNO50uFNEOOJ007bCXlVopoEGv0xSqIC2I\n-\thGzdeDgpQEoAEPIlMoVKrdWbLJStjHaWuz0ehmFOogh3AILo8bjLnXSZjbKY9Fq1SiGD\n-\trJArSHE/QEqAYlGcBMFgpkodLreH8Vae8lfXgAIogh1gI1jtP1XpZTxul6OUMhuSKIih\n-\tbEyRFLIhJeSLpXKVWmcwW+2uCsbnrw7UBUPhSCQSRRHtAIQwHArWBar9PqbCZbeaDTq1\n-\tSi4V50NSOHg97KUECYCgNVhstJvxVQWC4Wh9Y1NLa9tpFOEOtLW2NDXWR8PBQJWPcdM2\n-\tC5sV5JJUSYElAe4GJYBgttEer782FGlobmvv6OzqjqGId6C7q7Ojva25IRKq9Xs9tI29\n-\tIJQySAqHrge4HPLyJfICjd5spSt8NcFoU+vZc7Efe3r7LsXjl1FEOxCPX+rr7fkxdu5s\n-\ta1M0WOOroK1mvaaATQqHrofsE/AECSlBZ6Lsbm9NqL7lTNf5nr741f6fB4euDaOIduDa\n-\t0ODP/VfjfT3nu8601IdqvG47ZdJBUoAnyYOFAns5QJWg0VtKXYw/WN/aEbtw8Ur/4PCN\n-\tm4lbIyjCHbiVuHljeLD/ysULsY7W+qCfcZVa9Bq2UoDr4cuPGZMkKAq1JspR4auNAgi9\n-\t8f6h64mR0Tt3x+6hCHdg7O6d0ZHE9aH+eC+gEK31VTgok7ZQkZKEPJFUqS4221xMVajp\n-\tTKz38sBwYuTO2Pj9iYeTKMIdeDhxf3zszkhieOByb+xMU6iKcdnMxWqlVJR3KCcI8kQy\n-\t9nIoc/sCkbauC/GBXxKjY79PTD5+Mv0URbgD008eT078Pjaa+GUgfqGrLRLwucvY60Em\n-\tgpLxwO0gEIrlBVoj5fD4v2s4e/7iT8OJ0XsPJqdmZucWFhZRRDuwsDA3OzM1+eDeaGL4\n-\tp4vnzzZ85/c4KKO2QC4WpiBBIocywepkqsPN53quDAIIE4+mZ+eXni2/WEER7cCL5WdL\n-\t87PTjyYAhcErPeeaw9WM0wqFglySggR4dFAXf1Na7oXLIdbXf33ktwePZuYWn6+svlx7\n-\thSLagbWXqyvPF+dmHj34beR6f18Mrgdveek3xWp4eDiUE+AhUqFmy4TKuvr2H+KDidvj\n-\tk9NzS8t/rr1e33iDItqBjfXXa38uL81NT47fTgzGf2ivr6tkCwU1+/BwsE4AEpRAgt3j\n-\tDzZ29FwdHhmbmJpdXF59tfFmc2sbRbQDW5tvNl6tLi/OTk2MjQxf7eloDPo9diBBmZIE\n-\tqbJIXwIFY6ips7f/xq/jkzPzzwGEze23OyjCHXi7vQkoPJ+fmRz/9UZ/b2dTCErGEn2R\n-\tUpoqJ0hVRQaK/rY63NLVN3Dz9v3HfyytrK1vbu+8e7+LItqB9+92tjfX11aW/nh8//bN\n-\tgb6ulnD1tzRlKFIdQYLGSNFMTaS1+9Jg4u7E1Nyz1dd/be282/2AItyB3Xc7W3+9Xn02\n-\tNzVxNzF4qbs1UsPQlFFzNAnwEAkkfB8fujX28Mn88sv1zbcAwsdPKKId+Phh993bzfWX\n-\ty/NPHo7dGop/z5LgtB5LQlssfm3k3uTMwou1ja2d9wDCZxTRDnz6+OH9ztbG2ouFmcl7\n-\tI9fi8Bh5FAnwpXS+VKUxJnNCChL+RhHswGduEr74+7XsnFz42gE+YnSdDERPxy4PQ054\n-\turjy6s32zu6HT58JdgG3Dg58/vRhd2f7zauVxaeQE4Yvx05HAydd8CEjfPGQm4Mk8AcS\n-\tJIE/seY+KZLA7Q9/VpEE/sSa+6RIArc//FlFEvgTa+6TIgnc/vBnFUngT6y5T4okcPvD\n-\tn1UkgT+x5j4pksDtD39WkQT+xJr7pEgCtz/8WUUS+BNr7pMiCdz+8GcVSeBPrLlPiiRw\n-\t+8OfVSSBP7HmPimSwO0Pf1aRBP7EmvukSAK3P/xZRRL4E2vukyIJ3P7wZxVJ4E+suU+K\n-\tJHD7w59VJIE/seY+KZLA7Q9/VtMhAd+QzWAu0nlDNusYEoh+Zxw3z/2u9IHOnP/11jx2\n-\t0iC6bUaKzf8PnTSwuw7hbXSO2H663XWw4xbRfbWO3ny6HbewCx/hvfaO3n56XfiwMyfR\n-\t3Te5Np9mZ07s1kt0R16uzafVrVeAHbyJbtLNufm0OngLhNjVn+jO/VybT6+rP076IHqY\n-\tB+fm05v0gdN/CJ/ww7X9dKb/5OBEMMKnfnFtP52JYOy8SJwSSPgwwCO3n9aUQJwcSvh0\n-\tUK7tpzE5FKcJEz0u+JjNpzNNGCeMEz1C/JjNpzdhHAoFMYwY1xrMNtrj9deGIg3Nbe0d\n-\tnV3dMRTxDnR3dXa0tzU3REK1fq+HtpkNWhgwLmbHSn/RwDsrKxsGS+exM8YBBYuNdjO+\n-\tqkAwHK1vbGppbTuNItyBttaWpsb6aDgYqPIxbtpmARDY+eJ5h0kAFASQFKSAgs5gttpd\n-\tFYzPXx2oC4bCkUgkiiLaAQhhOBSsC1T7fUyFy241G3QAghRSguBgSvh3UhDLFGxWMFOl\n-\tDpfbw3grT/mra0ABFMEOsBGs9p+q9DIet8tRSrFXg0oBd0OqlAA5AZKCMF+SREFvslC2\n-\tMtpZ7vZ4GIY5iSLcAQiix+Mud9JlNspi0idBkOQLISUczglspQAoiCQyuapQo9ObzBbK\n-\tWlpmd9C00+lCEe2A00nTDntZqZWymE16naZQJZdJRADCoXqR/etWSApQNEJWkMqVBWqN\n-\tVm8wAg2WEsqKygAHqBILUGA06LUadYFSLoWMwN4NKVLCPgpwQYghLSgLCgEGXbEeeDCa\n-\tUMQ7YAQG9MU6wKAQOJBJxHA1HAVCVnYyK8CzZJIFhUoFNKiLijQaLYp4BzSaoiI1UKBS\n-\tKZIcQLGYBOHAhwn7rz4kURDkQloAFiRSmVyuUCpVqAxxQKlUyOUyqQTyAZsQoEY4kZ0a\n-\tBLgfICuwdSNbLuSLxICDRCqVylAZ4AAEEsIpFosAA8gHLAdHg8CWjXssAAxAA+CQlAhF\n-\tvAP7oRSyFOQKjuUg+QjBsnAiJydHwOKAyjAHAIIcNh1w5oP9aoFNDEka2N8Hwf9EZYAD\n-\te9FM/oQA/yfYX/MP+H1UxjnwNZHH30EH0AF0AB1AB9ABdAAdQAfQAXTgaAf+BYU9EtcK\n-\tZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iagoyNzE5CmVuZG9iagoyOCAwIG9iago8PCAv\n-\tTGVuZ3RoIDI5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRo\n-\tIDYxMiAvSGVpZ2h0IDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNv\n-\tbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d7U9T2RaH\n-\tBQql7y2U03LaTutpS3taS+fYaoXitKRNESm+oDh1FIJWzVSLHY2NzaAOxlEi8Q1HghhF\n-\txohGHSKGqDGjmX/trl3MnTt290jvyf101+8DMfvI/vDkyVq7B9hrwwYMEkACSAAJIAEk\n-\tgASQABJAAkgACSCB/wWBOgwSWD+B2hSEfev/TgMGCYgR+FuVejBnPaqt+QV7ymSNGCSw\n-\tXgIyGThDdPuqZmXD1vRqksub16LAIIFqBD47Ipc3gY0g2tcs+2xYY2MT6KVQKlUqlVqt\n-\t1mCQQHUCYAh4olQqmpuJZ1+xjCjWAB0SBAO91BqtVqfXGzBIQJyAXq/TajVgmhI0W7Os\n-\tWsMsKwY1jBim0eoMhpZWo7GtjWFMGCRQjQDDtLUZja0tBoNOqyGWQS2DhllFMlLFSBEj\n-\t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\n-\tWX1DQ4OMiIZBAusjAHo1kBImXsM+n8pIMSt7Rr4BAt+KQQLVCaxpUv4K5vzbonX9A74B\n-\tgwTWS2BdTuF/QgJIAAkgASSABJAAEkACSAAJIAEkUDuBfwFWtww3CmVuZHN0cmVhbQpl\n-\tbmRvYmoKMjkgMCBvYmoKMzAwNwplbmRvYmoKMzEgMCBvYmoKPDwgL0xlbmd0aCAzMiAw\n-\tIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCA1NDIgL0hlaWdo\n-\tdCAxMDQgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0JpdHNQZXJDb21wb25lbnQgOCAv\n-\tRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHtnetPU+kWxrkUer9B2S29TMtu\n-\tueyW0tlSLFCclrQBykXkOnUUghTNwICMxkYyqINhlEgUwYFwiSJDRAMOAUOUGDXzr521\n-\tCzlzhLKZnk/nvHs9H4zJWz+sZ/1ca+1e3pWWhkIH0AF0AB1AB9ABdAAdQAfQAXTg/9GB\n-\tdJRAHEiJTvAk429looh14O8sZ0DS/wEkB2SAHyJRFkoQDohEkG4OlNMASbBxAEa2WCw5\n-\tkBRFpAOH6RWLs+E/ASByCh+HbGRlZQMYUplMLpcrFAolilAHILmQYplMKpFwhPDzwcGR\n-\tCf0E0AAwFEqVSq3RaFEEO6DRqFUqJTAiA0AO+DihvSTggLrBsaFUqbXanFydLi+PovQo\n-\tIh2gqLw8nS43R6tVq5QcH1A/oL0kx4OrHFzh4NjQABmU3pBvNJrMZguKSAfMZpPRmG/Q\n-\tU0CIJsEHlA8OjyQPLwk4YOCQK4ANQAO4sFhttgLajiLUAbrAZrNagBEABPhQyLnxIzke\n-\t6dzMIZZC4dDmUgYjkEHbC4uKSxjG6XShiHPA6WSYkuKiQjsNhBgNVK4WyodUzM2mx4sH\n-\tlA6AQyJXqrU6vdFiox1FjLPU7fGwLHsGRaADkFiPx13qZIoctM1i1Ou0aiVUjyxRkt4C\n-\tpQMGUlkCDpOVLixxuT1secVZX1U1yI8izAEuq1W+sxXlrMftKimkraYEHjIYTZMUj3Qo\n-\tHRKZQqXVGUxWe7GrjPX6qvznAsHaUCgURhHnAKS1Nhg456/yedkyV7HdajLotCqFTALF\n-\t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\n-\tYQ5wWa3yna0oZz1uV0khzbUVrRr6SrLSAbUDiodYIk/gYbTYaEcR4yx1ezwsy55BEegA\n-\tJNbjcZc6mSIHbbMYE3DIJWIoHUfHDviSKcylgIdUrlRpcymD0WK10fbCouIShnE6XSji\n-\tHHA6GaakuKjQTtusFqOBytWqlHIpwHFsJuW+gQzFIzMrG6qHQqXJ0VF6o8kMhNgKaDuK\n-\tUAfoAhuQYTYZ9ZQuR6NSQOXg+kqS0nGIBzQXGZQPTU4uAGLINwIjZguKSAfMwIUx3wBo\n-\t5AIbSrkM2spJcKSlJ6pHVrYkwYdaqwVCdHl5FKVHEekAReXl6YAMrVadYAMG0gQcR94K\n-\tO/xpSwIPURaUD+BDrlCqVGqNRosi2AGNRq1SKRVyqBtc4YCZIyM9ORzQW6B6cLMpN35I\n-\tpDJARK5QKJQoQh2A5EKKZTIpoAF1g2PjZDi40fSADwAECAFEEpKiiHTgML1ijows0als\n-\tJB5dOD4yMjMzRRwiKAE4AGBkcmWDt24cTh9cAUkQwr0eBP8SRagDBxlO/AlJ/zcA/+Qv\n-\t8HqUIBz4JzTga9ABdAAdQAfQAXQAHUAH0AF0AB3433PgX6y7qcQKZW5kc3RyZWFtCmVu\n-\tZG9iagozMiAwIG9iagoyNzYyCmVuZG9iagoyNSAwIG9iago8PCAvTGVuZ3RoIDI2IDAg\n-\tUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ3OCAvSGVpZ2h0\n-\tIDEwNCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAvQml0c1BlckNvbXBvbmVudCA4IC9G\n-\taWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae2d/U8T2RfGeSn0fToD7bRM222Z\n-\tUui0lO4IWAFdIBAUAV9Q3LorBK2ahQW7GhubRV0Mq8RGEVwIL1FkiWjAJWCIErOa/de+\n-\tZ4rZXaEdvt2f7iTn+cFoLiaH58Nz723pnJOTg0IH0AF0AB1AB9ABdAAdQAfQgf/mQC5K\n-\tIQ5kxRe+p7x/lI8i1oF/KOUBtP8D8g5Z+H5UqgKUIhxQqQCXBHo/wCm2O2AL1WrNjrQo\n-\tIh34jEetLoQfQkC8D9/PbAsKCgGsVqfT6/UGg8GIItQBgAOIdDqtRiMRlucrwc2H/RjQ\n-\t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\n-\tKjV28CWuS69cQdl18MXu28Q12JYtKLvu29g5n8Du+HIlZdM5Px+nXhA42UKupGymXkjz\n-\tiHBiDYGDaTKWlNXEGpw2ReBEKbmSspg2hZPiiBsFt09B2UyKwymPxI1x3Keg7KY84oRW\n-\tIsewyhSVzYRWaTA6TlcmcIpyppKymK6cg5PRiZt9Ll9QNpPRga4UXp3RJM1Gd/FeXyAY\n-\tEqtrD4br6kENKMIckKjUhQ/WVouhYMDn5aXB2YwJJmcX7h2dnQN081QFao0+hZdzuvmy\n-\tcsFfGQyFRFE8gCLQAQATCgUr/UJ5Ge92cim4eo26QJW3e7gyfMgKwgt4tXojxRSzNs7p\n-\tcvMeb3mFTxD8/gCKOAf8fkHwVZR7Pbzb5eRsbDFDGfUwN1u1Z+q99Ak6CC/szZBeA0UX\n-\tmVkrZ3cAYXcp70ER6gBf6gayDjtnZc1FNGWA5Er7cprofsYLm7MO4ksXFQNgWwkHjB1O\n-\tFJEOOIArV2IDtMXA1qjXwbacCW5Obiq9cLVK8TUxDBA2Wywsa0UR6QDLWixmIMswphRb\n-\tuFCl4H4x8eLvDzan8KoKIL7AV28wUpSJphkUwQ7QtImijAY95FYKLpy5ebnp4cLeDOmV\n-\t7lbS8avR6gCx3mAwGFGEOgBwAJFOpwW0kFuJbWa40tVqhy8ABsKAOCUtikgHPuNRS2QL\n-\tVPuyTV2dJb55+fn5KgkxSgEOANh8Kbayuf3X+ZsiLH09CP4nilAHdgil/szNeN7+zfWL\n-\tv8DXoxThwBfY8B/oADqADqAD6AA6gA6gA+gAOpCFA/8DclEtHwplbmRzdHJlYW0KZW5k\n-\tb2JqCjI2IDAgb2JqCjI1NTgKZW5kb2JqCjM0IDAgb2JqCjw8IC9MZW5ndGggMzUgMCBS\n-\tIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNTMyIC9IZWlnaHQg\n-\tMTA0IC9Db2xvclNwYWNlCi9EZXZpY2VHcmF5IC9CaXRzUGVyQ29tcG9uZW50IDggL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7Z3rT1PpFsZBCqX3Fnqjl2nZbaG7\n-\tpXS2LZZSmLZpwx1REKbOCEGrZmBARmMjGdTBMEokiuBAuESRIaIBh4AhSoya86+dtQvn\n-\t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\n-\tkC48a6HuVQ+qfWqL2gpNPaa2q21qF9+OqgPlHcOclYkLrNtl9Sn2YGOa3spJV2aL4N/C\n-\tL4b/pV5hC9c0NPkPTbi5jGkJ3xHcNnCHlP/DX7MDDd4KZW5kc3RyZWFtCmVuZG9iagoz\n-\tNyAwIG9iago3OTIKZW5kb2JqCjcgMCBvYmoKWyAvSUNDQmFzZWQgMzYgMCBSIF0KZW5k\n-\tb2JqCjM4IDAgb2JqCjw8IC9MZW5ndGggMzkgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2\n-\taWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1XiTvU2xs/YwnZ\n-\t953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfRvT9Kda97ht99\n-\t+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAdnZyRdDOAHtAC\n-\tBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyTTf+oWXDeZCwA\n-\tCDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5UnBEaHAoAPRQ\n-\tABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmIbXEEHAUvQIwh\n-\tBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZwVEG9mpAFSIT\n-\tgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBIeNaeXQHaggAB\n-\toGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8DoOQFQMM7bBgp\n-\tfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBDZCAaEJOIb1QS\n-\tVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4ROgC6Arpeek96f\n-\t/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd2Gc43DiWOYM4\n-\tv3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoDbmL8YtPilyQc\n-\tJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAzVdfSwByS1ZQ8\n-\tLKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZTtjR2qva+x0sc\n-\tph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk6lDusDPhXyKJ\n-\tUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2hXREobijxLOMu\n-\tH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5iBxmHUWMbT3+\n-\tOL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/t8I/h3d2fuXC\n-\tr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcUzsMDX8iLFC7E\n-\tQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGwx8GVYK9O2KMz\n-\tQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB/CSBCMFYodPC\n-\tqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgHj2O0laVU2FS+\n-\tqr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnltumi2YP7KYs7y\n-\t5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMbS4vj8BbxkcOr\n-\t+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2xT2Ln0h4nDhy\n-\tejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15lZfS8gkFxwpV\n-\tLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1yI67O7aZuvWj9\n-\tTsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94XfdehXvUd3b2ag\n-\t7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaDp+SnVp9VT3s/\n-\tF3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZl9veua7QrNS9\n-\tt3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosEqy1bAvtNjlRO\n-\tLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfcUfwPiSxJlOSA\n-\tlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXnKhmqOqq/q1Wp\n-\tO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMzE1aTKdNGs3Rz\n-\tbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6yRmYM3XueR5x\n-\tnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJn8g9oWlh9uHI\n-\t8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immqbOp8Wl66eQbI\n-\taDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7rwozqLo65onnl\n-\tS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ubvHmqXqJ+rCGs\n-\tUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oyerV71++U9dne\n-\tpb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZc1mesDGxm3Ik\n-\tc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+UiJdUkNyWeqi\n-\ttL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVFdVwtD8ZdSGP+\n-\tUIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2YT5sUWEZe5Rs\n-\t5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPckeDljTXFq3uI+\n-\t7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGaGBN0Kig2OC4k\n-\tnpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQvMl78lDuV13Wp\n-\tJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+oWaydvDFYd/tm\n-\tfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698z2rA737yg9LB\n-\t2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6pzDssRL7OWapb\n-\tfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFSgMTABP8fbh7Y\n-\t2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iagozOSAwIG9iagoyNjM0\n-\tCmVuZG9iagoyNyAwIG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNDAgMCBv\n-\tYmoKPDwgL0xlbmd0aCA0MSAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0Zp\n-\tbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7VeJO9TbGz9jCdn3nck+jKWxJjvZ\n-\tQ0iWrDOMbQYzdtmibKFEiCwhkexbQpKSrSKSJJQkV9G9P0p1r3uG3336Pb/n9h90vs97\n-\tzue87znvOd953+f7eQcAVpy+jY0lDQCAQAwl2ZoYIB2dnJF0M4Ae0AIG2LN7YsnBlDVw\n-\tyU/a1jOAoJieok3sjxrcNx2oe7dJzZI92sinuV6U/JNN/6hZcN5kLAAINFR4kODhAFBx\n-\tQcyF38MyFOy1h7UomGRvawjX2EBhwu9impMU7LWL9/lScERocCgA9FAAFzaYRMHFEJ/1\n-\tCtjVp1L04Vg81DNIALCPA+vriQOAVQPq0TgCEWLEOYhtcQQcBS9AjCEEhsF77jbK2zJ5\n-\tE4/bwdEIihAwBWHAG0QBG2ALrAESGIIgEAiFBLElnBnBUQb2akAVIhOAAQpQkEAfKEGk\n-\tBB/UT/yr7fp3BPLQsx8IhacggRkgAizcR/EZsfsogEh41p5dAdqCAAGgYEz//c48uz7/\n-\t7Y5KAFDiD+2wEfkBMKD8djw/dM69AGTCmAiif+jkvwOg5AVAwztsGCl8by/in4Ea0AFG\n-\twA744G1RQAW+sRVwhfdPALmgBvSB5+B3BDNCFmGG8ENkIBoQk4hvVBJU1lQxVDVUM9T7\n-\tqbWpSdQ11K9phGicaPJppmn5aV1pr9Ku7lPeF7dvhE6ALoCul56T3p/+HoMwQzTDzP5D\n-\t+4sZEYx4xidMmkzVzDzMZ5m3WYgsb1ndWGfYHNim2B3YZzjcOJY5gzi/caVx83PX8ujy\n-\tTPES+Oj5KvkN+ZcEUgTRgpNCccIo4WmRFFFN0Y/IqgNuYvxi0+KXJBwlhSTfSN2QDpcx\n-\tRHGglmQ75LLQPvJ6CsIK3xVfKd09WI05rxytgld1UDNV19LAHJLVlDwspnVAW1xHWldB\n-\tT01f38Da0N0o5MgZ42KTNtNxs3ULVkvM0RNW8dY1NlO2NHaq9r7HSxymHdmdrJyzXJ64\n-\tcrm5uFd6bHjpYLNxr33U8dm+7/2NA6oIdMSAoImQw6TqUO6wM+FfIolRyzEep+biXOPn\n-\tE7GnV5PJZ3ZSstJE05vPmWYuZp+6wJ9zK/fkJUR+TaFdEShuKPEs4y4frThbZVCNuN5f\n-\te6bOsp67YaGpviW+zbZD5hbomu3u7C3oi+n3GDB9gHmIHGYdRYxtPf44vvL07dTS9PLM\n-\t6uynuW8L9K95l2SWtVfsVwlraR+vbwz//nGT+7POtv+3wj+Hd3Z+5cKvXPiVC7++C///\n-\tXfjBG1tT/60b5H7oQDQkjjgovj/hLn9oE9rl12DItxTOwwNfyIsULsRChkGC/+VKNJxj\n-\tdvn1IGTQPaS+y5z6kJ8DoZXCqnseyLszb0CGHEsC4bDHwZVgr07YozNAjYDlBawICFQz\n-\tNMa0zXSi9BkMXxhxTOMs2qy17DwcSZzr3Cd5PHnxfIH8JIEIwVih08KpIpmiF5GFB0rE\n-\tKsVrJBokL0nFSnvLWKKUZQXlqOTeo8flOxVKFVOUiAePY7SVpVTYVL6qvlEbU+/QKDuU\n-\trkk+7Kploq2kI6BLo/tBb03/N4P3hitG7468NV4yeW26aLZg/spizvLl0RdWM9arNl9t\n-\tGe2E7NHHtR2sTrg5BjklOJ93KT/Z7Nrv9tR9wWPNcxtLi+PwFvGRw6v7GvnZ+LsG+AeG\n-\tE5KI2UFVwbdDxknL5O9hHOEyETqRdlF+0fExeaduxPbFPYufSHicOHJ6MOlect+Z7rOd\n-\tKa2pjWk302syqs6VZ5Zknc72OW9+QTGHM+fzxZe5fXmVl9LyCQXHClUvC1z+q+hlcdeV\n-\t/JKwUrsypXKW8rWrwxXVlWeqsNf0q0Wqv1+fq+mpvXIjrs7tpm69aP1Ow0JjX1N5c2KL\n-\tV6tBm1g7VftiR19n6a24LtfbWt2C3V97Zno77+T3hd916Fe9R3dvZqDuftwDm0Hxwc2H\n-\tg0OFw4EjOqNso2/G2h6lPDZ6QvXkzvipiUMTW09bJoOn5KdWn1VPez8Xez4/U/zCehYx\n-\t2/oSPycwN/YqYR4z/3ahYNFi8a/XjW+wSzxLvW99lpmX2965rtCs1L23f/99teI3i9/+\n-\tWLv8weDDKoy/ApULdRpNB+0SHQe9HgNhfxHjENMWiwSrLVsC+02OVE4slw6sLf7D84i3\n-\thi+Z311AU5BbcENoRLhKJEFUULQdeQy5diBFTEysR9xR/A+JLEmU5ICUu9RX6TwZA5kN\n-\t1BVZC9kvctfQdvII+XoFF0UGxXYl3EH2g3cwJGVJ5ecqGao6qr+rVak7ajBq9B4K0ZTQ\n-\tfH44Q0tHm0Z7SCdb97ieoN6ifrVBoCHG8ItR75FkYzMTVpMp00azdHNvC11LAcvNo4+t\n-\taq2TbdyPHbLlsl23G7KvPJ7pEHHCw9HMSdlZyGWfy/rJGZgzde55HnGevl7HsCgcAjfj\n-\t3eiTivfw1fBj9XvnfycgPzCIYEwUIW4F9QdnhTiRJEmfyD2haWH24cjwtYjOyOQo62jB\n-\t6HcxQ6fqYrPiguPtElQTeRO/nn6Z1JtcfibprHeKaaps6nxaXrp5BshoOxeQicx8lpWR\n-\trZ+9db7ugmcOb87oxYxc8zz6vMFLZ/ONCqgL+gsTLuvCjOoujrmieeVLSUspoUy6bLG8\n-\t+KpDBVvFMMwq3artay3VxOsy11/XpNcq187eSKqTq5u8eapeon6sIaxRuPF+E7GZp7m3\n-\tJaCVt3WgLbhduH2oI7xTrPPxrZguma7J24nd8t0vejJ6tXvX75T12d6lvtvW73OP797Q\n-\tQMx99P1XD7IH9WH8tagiqVtpNvah6XzpKxkWGIWYHJlzWZ6wMbGbciRz4rnMuNE8LDyf\n-\teJ/ytfMXCMQIugnpCYuL0IqsiA4jIw9IHXgqliiuKP5SIl1SQ3JZ6qK0vvS6TDHKHPVF\n-\t9rqcI5oefUveT4FfYUgxSgml9OJgOkYTs6p8WcVclUV1XC0Pxl1IY/5QhabPYdnDH7Sa\n-\ttEN11HW+6fbqFeiHGFgYShj+ZTR9pMk43QRnqm3Ga7ZhPmxRYRl7lGzlZ+1h43DsqK2h\n-\tnaa90nFpB+ETnI77nYDTZ+cPLrMnH7q2u1W6X/CI9yR4OWNNcWre4j7sPjv4Nd8XfhP+\n-\tIwEDgd2ENmJ90LXg0pAC0nlyWujpsOhwckRgZGAUIZoYE3QqKDY4LiSelEBKJJ8OTQpN\n-\thsXp2YgU11TDNFQ6a/pmxuy5u5nVWZnZ5PNOF3RzJC8yXvyUO5XXdakkP6kAX2hxWamI\n-\tq2i7eO5Kf8m10vSyoHK7qyYVmpXyVchrXNV01V+vf6hZrJ28MVh3+2Z9fXlDbmNhU2lz\n-\tZUtNa31bS3tnR09n/63BrrHbE93TPS97F+98v8vbr3zPasDvfvKD0sHbD58NfRphGpUe\n-\tM3zk9jjqSdF4z8T8JGJK/JnxtO/z9Jm6F49mN+Y4XqnMOyxEvs5Zqlt+sLKw+vUD17ri\n-\tJ7M/sJuxn/O3m76N/Pl2ZwcAso8yZpcREMzbANAtQVKAxMAE/x9uHtjZ2dmCGeK+s/Mn\n-\tN0AIhf8N2jTKGQplbmRzdHJlYW0KZW5kb2JqCjQxIDAgb2JqCjI2MzQKZW5kb2JqCjI0\n-\tIDAgb2JqClsgL0lDQ0Jhc2VkIDQwIDAgUiBdCmVuZG9iago0MiAwIG9iago8PCAvTGVu\n-\tZ3RoIDQzIDAgUiAvTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN2\n-\t2aJsoUSILCGR7FtCkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf\n-\t5/t5BwBWnL6NjSUNAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6i\n-\tTeyPGtw3Hah7t0nNkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWH\n-\ttSiYZG9rCNfYQGHC72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzU\n-\t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\n-\tqu1rLdXE6zLXX9ek1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24\n-\tfagjvFOs8/GtmC6Zrsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1\n-\tYfy1qCKpW2k29qHpfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6\n-\tCekJi4vQiqyIDiMjD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95P\n-\tgV9hSDFKCaX04mA6RhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV\n-\t6IcYWBhKGP5lNH2kyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROc\n-\tjvudgNNn5w8usycfura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3Q\n-\tteDSkALSeXJa6Omw6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0\n-\tVDpr+mbG7Lm7mdVZmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS\n-\t9LKgcrurJhWalfJVyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dH\n-\tT2f/rcGusdsT3dM9L3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjP\n-\txPwkYkr8mfG07/P0mboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87eb\n-\tvo38+XZnBwCyjzJmlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZ\n-\tCmVuZHN0cmVhbQplbmRvYmoKNDMgMCBvYmoKMjYzNAplbmRvYmoKMjEgMCBvYmoKWyAv\n-\tSUNDQmFzZWQgNDIgMCBSIF0KZW5kb2JqCjQ0IDAgb2JqCjw8IC9MZW5ndGggNDUgMCBS\n-\tIC9OIDEgL0FsdGVybmF0ZSAvRGV2aWNlR3JheSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+\n-\tPgpzdHJlYW0KeAGFUk9IFFEc/s02EoSIQYV4iHcKCZUprKyg2nZ1WZVtW5XSohhn37qj\n-\tszPTm9k1xZMEXaI8dQ+iY3Ts0KGbl6LArEvXIKkgCDx16PvN7OoohG95O9/7/f1+33tE\n-\tbZ2m7zspQVRzQ5UrpaduTk2Lgx8pRR3UTlimFfjpYnGMseu5kr+719Zn0tiy3se1dvv2\n-\tPbWVZWAh6i22txD6IZFmAB+ZnyhlgLPAHZav2D4BPFgOrBrwI6IDD5q5MNPRnHSlsi2R\n-\tU+aiKCqvYjtJrvv5uca+i7WJg/5cj2bWjr2z6qrRTNS090ShvA+uRBnPX1T2bDUUpw3j\n-\tnEhDGinyrtXfK0zHEZErEEoGUjVkuZ9qTp114HUYu126k+P49hClPslgqIm16bKZHYV9\n-\tAHYqy+wQ8AXo8bJiD+eBe2H/W1HDk8AnYT9kh3nWrR/2F65T4HuEPTXgzhSuxfHaih9e\n-\tLQFD91QjaIxzTcTT1zlzpIjvMdQZmPdGOaYLMXeWqhM3gDthH1mqZgqxXfuu6iXuewJ3\n-\t0+M70Zs5C1ygHElysRXZFNA8CVgUfYuwSQ48Ps4eVeB3qJjAHLmJ3M0o9x7VERtno1KB\n-\tVnqNV8ZP47nxxfhlbBjPgH6sdtd7fP/p4xV117Y+PPmNetw5rr2dG1VhVnFlC93/xzKE\n-\tj9knOabB06FZWGvYduQPmsxMsAwoxH8FPpf6khNV3NXu7bhFEsxQPixsJbpLVG4p1Oo9\n-\tg0qsHCvYAHZwksQsWhy4U2u6OXh32CJ6bflNV7Lrhv769nr72vIebcqoKSgTzbNEZpSx\n-\tW6Pk3Xjb/WaREZ84Or7nvYpayf5JRRA/hTlaKvIUVfRWUNbEb2cOfhu2flw/pef1Qf08\n-\tCT2tn9Gv6KMRvgx0Sc/Cc1Efo0nwsGkh4hKgioMz1E5UY40D4inx8rRbZJH9D0AZ/WYK\n-\tZW5kc3RyZWFtCmVuZG9iago0NSAwIG9iago3MDQKZW5kb2JqCjE4IDAgb2JqClsgL0lD\n-\tQ0Jhc2VkIDQ0IDAgUiBdCmVuZG9iago0NiAwIG9iago8PCAvTGVuZ3RoIDQ3IDAgUiAv\n-\tTiAzIC9BbHRlcm5hdGUgL0RldmljZVJHQiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+Pgpz\n-\tdHJlYW0KeAHtV4k71NsbP2MJ2fedyT6MpbEmO9lDSJasM4xtBjN22aJsoUSILCGR7FtC\n-\tkpKtIpIklCRX0b0/SnWve4bfffo9v+f2H3S+z3vO57zvOe8533nf5/t5BwBWnL6NjSUN\n-\tAIBADCXZmhggHZ2ckXQzgB7QAgbYs3tiycGUNXDJT9rWM4CgmJ6iTeyPGtw3Hah7t0nN\n-\tkj3ayKe5XpT8k03/qFlw3mQsAAg0VHiQ4OEAUHFBzIXfwzIU7LWHtSiYZG9rCNfYQGHC\n-\t72KakxTstYv3+VJwRGhwKAD0UAAXNphEwcUQn/UK2NWnUvThWDzUM0gAsI8D6+uJA4BV\n-\tA+rROAIRYsQ5iG1xBBwFL0CMIQSGwXvuNsrbMnkTj9vB0QiKEDAFYcAbRAEbYAusARIY\n-\tgiAQCIUEsSWcGcFRBvZqQBUiE4ABClCQQB8oQaQEH9RP/Kvt+ncE8tCzHwiFpyCBGSAC\n-\tLNxH8Rmx+yiASHjWnl0B2oIAAaBgTP/9zjy7Pv/tjkoAUOIP7bAR+QEwoPx2PD90zr0A\n-\tZMKYCKJ/6OS/A6DkBUDDO2wYKXxvL+KfgRrQAUbADvjgbVFABb6xFXCF908AuaAG9IHn\n-\t4HcEM0IWYYbwQ2QgGhCTiG9UElTWVDFUNVQz1PuptalJ1DXUr2mEaJxo8mmmaflpXWmv\n-\t0q7uU94Xt2+EToAugK6XnpPen/4egzBDNMPM/kP7ixkRjHjGJ0yaTNXMPMxnmbdZiCxv\n-\tWd1YZ9gc2KbYHdhnONw4ljmDOL9xpXHzc9fy6PJM8RL46Pkq+Q35lwRSBNGCk0Jxwijh\n-\taZEUUU3Rj8iqA25i/GLT4pckHCWFJN9I3ZAOlzFEcaCWZDvkstA+8noKwgrfFV8p3T1Y\n-\tjTmvHK2CV3VQM1XX0sAcktWUPCymdUBbXEdaV0FPTV/fwNrQ3SjkyBnjYpM203GzdQtW\n-\tS8zRE1bx1jU2U7Y0dqr2vsdLHKYd2Z2snLNcnrhyubm4V3pseOlgs3GvfdTx2b7v/Y0D\n-\tqgh0xICgiZDDpOpQ7rAz4V8iiVHLMR6n5uJc4+cTsadXk8lndlKy0kTTm8+ZZi5mn7rA\n-\tn3Mr9+QlRH5NoV0RKG4o8SzjLh+tOFtlUI243l97ps6ynrthoam+Jb7NtkPmFuia7e7s\n-\tLeiL6fcYMH2AeYgcZh1FjG09/ji+8vTt1NL08szq7Ke5bwv0r3mXZJa1V+xXCWtpH69v\n-\tDP/+cZP7s862/7fCP4d3dn7lwq9c+JULv74L//9d+MEbW1P/rRvkfuhANCSOOCi+P+Eu\n-\tf2gT2uXXYMi3FM7DA1/IixQuxEKGQYL/5Uo0nGN2+fUgZNA9pL7LnPqQnwOhlcKqex7I\n-\tuzNvQIYcSwLhsMfBlWCvTtijM0CNgOUFrAgIVDM0xrTNdKL0GQxfGHFM4yzarLXsPBxJ\n-\tnOvcJ3k8efF8gfwkgQjBWKHTwqkimaIXkYUHSsQqxWskGiQvScVKe8tYopRlBeWo5N6j\n-\tx+U7FUoVU5SIB49jtJWlVNhUvqq+URtT79AoO5SuST7sqmWiraQjoEuj+0FvTf83g/eG\n-\tK0bvjrw1XjJ5bbpotmD+ymLO8uXRF1Yz1qs2X20Z7YTs0ce1HaxOuDkGOSU4n3cpP9ns\n-\t2u/21H3BY81zG0uL4/AW8ZHDq/sa+dn4uwb4B4YTkojZQVXBt0PGScvk72Ec4TIROpF2\n-\tUX7R8TF5p27E9sU9i59IeJw4cnow6V5y35nus50pramNaTfTazKqzpVnlmSdzvY5b35B\n-\tMYcz5/PFl7l9eZWX0vIJBccKVS8LXP6r6GVx15X8krBSuzKlcpbytavDFdWVZ6qw1/Sr\n-\tRaq/X5+r6am9ciOuzu2mbr1o/U7DQmNfU3lzYotXq0GbWDtV+2JHX2fprbgu19ta3YLd\n-\tX3tmejvv5PeF33XoV71Hd29moO5+3AObQfHBzYeDQ4XDgSM6o2yjb8baHqU8NnpC9eTO\n-\t+KmJQxNbT1smg6fkp1afVU97Pxd7Pj9T/MJ6FjHb+hI/JzA39iphHjP/dqFg0WLxr9eN\n-\tb7BLPEu9b32WmZfb3rmu0KzUvbd//3214jeL3/5Yu/zB4MMqjL8ClQt1Gk0H7RIdB70e\n-\tA2F/EeMQ0xaLBKstWwL7TY5UTiyXDqwt/sPziLeGL5nfXUBTkFtwQ2hEuEokQVRQtB15\n-\tDLl2IEVMTKxH3FH8D4ksSZTkgJS71FfpPBkDmQ3UFVkL2S9y19B28gj5egUXRQbFdiXc\n-\tQfaDdzAkZUnl5yoZqjqqv6tVqTtqMGr0HgrRlNB8fjhDS0ebRntIJ1v3uJ6g3qJ+tUGg\n-\tIcbwi1HvkWRjMxNWkynTRrN0c28LXUsBy82jj61qrZNt3I8dsuWyXbcbsq88nukQccLD\n-\t0cxJ2VnIZZ/L+skZmDN17nkecZ6+XsewKBwCN+Pd6JOK9/DV8GP1e+d/JyA/MIhgTBQh\n-\tbgX1B2eFOJEkSZ/IPaFpYfbhyPC1iM7I5CjraMHodzFDp+pis+KC4+0SVBN5E7+efpnU\n-\tm1x+Jumsd4ppqmzqfFpeunkGyGg7F5CJzHyWlZGtn711vu6CZw5vzujFjFzzPPq8wUtn\n-\t840KqAv6CxMu68KM6i6OuaJ55UtJSymhTLpssbz4qkMFW8UwzCrdqu1rLdXE6zLXX9ek\n-\t1yrXzt5IqpOrm7x5ql6ifqwhrFG48X4TsZmnubcloJW3daAtuF24fagjvFOs8/GtmC6Z\n-\trsnbid3y3S96Mnq1e9fvlPXZ3qW+29bvc4/v3tBAzH30/VcPsgf1Yfy1qCKpW2k29qHp\n-\tfOkrGRYYhZgcmXNZnrAxsZtyJHPiucy40TwsPJ94n/K18xcIxAi6CekJi4vQiqyIDiMj\n-\tD0gdeCqWKK4o/lIiXVJDclnqorS+9LpMMcoc9UX2upwjmh59S95PgV9hSDFKCaX04mA6\n-\tRhOzqnxZxVyVRXVcLQ/GXUhj/lCFps9h2cMftJq0Q3XUdb7p9uoV6IcYWBhKGP5lNH2k\n-\tyTjdBGeqbcZrtmE+bFFhGXuUbOVn7WHjcOyoraGdpr3ScWkH4ROcjvudgNNn5w8usycf\n-\tura7Vbpf8Ij3JHg5Y01xat7iPuw+O/g13xd+E/4jAQOB3YQ2Yn3QteDSkALSeXJa6Omw\n-\t6HByRGBkYBQhmhgTdCooNjguJJ6UQEoknw5NCk2GxenZiBTXVMM0VDpr+mbG7Lm7mdVZ\n-\tmdnk804XdHMkLzJe/JQ7ldd1qSQ/qQBfaHFZqYiraLt47kp/ybXS9LKgcrurJhWalfJV\n-\tyGtc1XTVX69/qFmsnbwxWHf7Zn19eUNuY2FTaXNlS01rfVtLe2dHT2f/rcGusdsT3dM9\n-\tL3sX73y/y9uvfM9qwO9+8oPSwdsPnw19GmEalR4zfOT2OOpJ0XjPxPwkYkr8mfG07/P0\n-\tmboXj2Y35jheqcw7LES+zlmqW36wsrD69QPXuuInsz+wm7Gf87ebvo38+XZnBwCyjzJm\n-\tlxEQzNsA0C1BUoDEwAT/H24e2NnZ2YIZ4r6z8yc3QAiF/w3aNMoZCmVuZHN0cmVhbQpl\n-\tbmRvYmoKNDcgMCBvYmoKMjYzNAplbmRvYmoKMzMgMCBvYmoKWyAvSUNDQmFzZWQgNDYg\n-\tMCBSIF0KZW5kb2JqCjQ4IDAgb2JqCjw8IC9MZW5ndGggNDkgMCBSIC9OIDMgL0FsdGVy\n-\tbmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae1X\n-\tiTvU2xs/YwnZ953JPoylsSY72UNIlqwzjG0GM3bZomyhRIgsIZHsW0KSkq0ikiSUJFfR\n-\tvT9Kda97ht99+j2/5/YfdL7Pe87nvO857znfed/n+3kHAFacvo2NJQ0AgEAMJdmaGCAd\n-\tnZyRdDOAHtACBtize2LJwZQ1cMlP2tYzgKCYnqJN7I8a3DcdqHu3Sc2SPdrIp7lelPyT\n-\tTf+oWXDeZCwACDRUeJDg4QBQcUHMhd/DMhTstYe1KJhkb2sI19hAYcLvYpqTFOy1i/f5\n-\tUnBEaHAoAPRQABc2mETBxRCf9QrY1adS9OFYPNQzSACwjwPr64kDgFUD6tE4AhFixDmI\n-\tbXEEHAUvQIwhBIbBe+42ytsyeROP28HRCIoQMAVhwBtEARtgC6wBEhiCIBAIhQSxJZwZ\n-\twVEG9mpAFSITgAEKUJBAHyhBpAQf1E/8q+36dwTy0LMfCIWnIIEZIAIs3EfxGbH7KIBI\n-\teNaeXQHaggABoGBM//3OPLs+/+2OSgBQ4g/tsBH5ATCg/HY8P3TOvQBkwpgIon/o5L8D\n-\toOQFQMM7bBgpfG8v4p+BGtABRsAO+OBtUUAFvrEVcIX3TwC5oAb0gefgdwQzQhZhhvBD\n-\tZCAaEJOIb1QSVNZUMVQ1VDPU+6m1qUnUNdSvaYRonGjyaaZp+Wldaa/Sru5T3he3b4RO\n-\tgC6Arpeek96f/h6DMEM0w8z+Q/uLGRGMeMYnTJpM1cw8zGeZt1mILG9Z3Vhn2BzYptgd\n-\t2Gc43DiWOYM4v3GlcfNz1/Lo8kzxEvjo+Sr5DfmXBFIE0YKTQnHCKOFpkRRRTdGPyKoD\n-\tbmL8YtPilyQcJYUk30jdkA6XMURxoJZkO+Sy0D7yegrCCt8VXyndPViNOa8crYJXdVAz\n-\tVdfSwByS1ZQ8LKZ1QFtcR1pXQU9NX9/A2tDdKOTIGeNikzbTcbN1C1ZLzNETVvHWNTZT\n-\ttjR2qva+x0scph3Znaycs1yeuHK5ubhXemx46WCzca991PHZvu/9jQOqCHTEgKCJkMOk\n-\t6lDusDPhXyKJUcsxHqfm4lzj5xOxp1eTyWd2UrLSRNObz5lmLmafusCfcyv35CVEfk2h\n-\tXREobijxLOMuH604W2VQjbjeX3umzrKeu2Ghqb4lvs22Q+YW6Jrt7uwt6Ivp9xgwfYB5\n-\tiBxmHUWMbT3+OL7y9O3U0vTyzOrsp7lvC/SveZdklrVX7FcJa2kfr28M//5xk/uzzrb/\n-\tt8I/h3d2fuXCr1z4lQu/vgv//134wRtbU/+tG+R+6EA0JI44KL4/4S5/aBPa5ddgyLcU\n-\tzsMDX8iLFC7EQoZBgv/lSjScY3b59SBk0D2kvsuc+pCfA6GVwqp7Hsi7M29AhhxLAuGw\n-\tx8GVYK9O2KMzQI2A5QWsCAhUMzTGtM10ovQZDF8YcUzjLNqstew8HEmc69wneTx58XyB\n-\t/CSBCMFYodPCqSKZoheRhQdKxCrFayQaJC9JxUp7y1iilGUF5ajk3qPH5TsVShVTlIgH\n-\tj2O0laVU2FS+qr5RG1Pv0Cg7lK5JPuyqZaKtpCOgS6P7QW9N/zeD94YrRu+OvDVeMnlt\n-\tumi2YP7KYs7y5dEXVjPWqzZfbRnthOzRx7UdrE64OQY5JTifdyk/2eza7/bUfcFjzXMb\n-\tS4vj8BbxkcOr+xr52fi7BvgHhhOSiNlBVcG3Q8ZJy+TvYRzhMhE6kXZRftHxMXmnbsT2\n-\txT2Ln0h4nDhyejDpXnLfme6znSmtqY1pN9NrMqrOlWeWZJ3O9jlvfkExhzPn88WXuX15\n-\tlZfS8gkFxwpVLwtc/qvoZXHXlfySsFK7MqVylvK1q8MV1ZVnqrDX9KtFqr9fn6vpqb1y\n-\tI67O7aZuvWj9TsNCY19TeXNii1erQZtYO1X7YkdfZ+mtuC7X21rdgt1fe2Z6O+/k94Xf\n-\tdehXvUd3b2ag7n7cA5tB8cHNh4NDhcOBIzqjbKNvxtoepTw2ekL15M74qYlDE1tPWyaD\n-\tp+SnVp9VT3s/F3s+P1P8wnoWMdv6Ej8nMDf2KmEeM/92oWDRYvGv141vsEs8S71vfZaZ\n-\tl9veua7QrNS9t3//fbXiN4vf/li7/MHgwyqMvwKVC3UaTQftEh0HvR4DYX8R4xDTFosE\n-\tqy1bAvtNjlROLJcOrC3+w/OIt4Yvmd9dQFOQW3BDaES4SiRBVFC0HXkMuXYgRUxMrEfc\n-\tUfwPiSxJlOSAlLvUV+k8GQOZDdQVWQvZL3LX0HbyCPl6BRdFBsV2JdxB9oN3MCRlSeXn\n-\tKhmqOqq/q1WpO2owavQeCtGU0Hx+OENLR5tGe0gnW/e4nqDeon61QaAhxvCLUe+RZGMz\n-\tE1aTKdNGs3RzbwtdSwHLzaOPrWqtk23cjx2y5bJdtxuyrzye6RBxwsPRzEnZWchln8v6\n-\tyRmYM3XueR5xnr5ex7AoHAI3493ok4r38NXwY/V7538nID8wiGBMFCFuBfUHZ4U4kSRJ\n-\tn8g9oWlh9uHI8LWIzsjkKOtoweh3MUOn6mKz4oLj7RJUE3kTv55+mdSbXH4m6ax3immq\n-\tbOp8Wl66eQbIaDsXkInMfJaVka2fvXW+7oJnDm/O6MWMXPM8+rzBS2fzjQqoC/oLEy7r\n-\twozqLo65onnlS0lLKaFMumyxvPiqQwVbxTDMKt2q7Wst1cTrMtdf16TXKtfO3kiqk6ub\n-\tvHmqXqJ+rCGsUbjxfhOxmae5tyWglbd1oC24Xbh9qCO8U6zz8a2YLpmuyduJ3fLdL3oy\n-\terV71++U9dnepb7b1u9zj+/e0EDMffT9Vw+yB/Vh/LWoIqlbaTb2oel86SsZFhiFmByZ\n-\tc1mesDGxm3Ikc+K5zLjRPCw8n3if8rXzFwjECLoJ6QmLi9CKrIgOIyMPSB14KpYorij+\n-\tUiJdUkNyWeqitL70ukwxyhz1Rfa6nCOaHn1L3k+BX2FIMUoJpfTiYDpGE7OqfFnFXJVF\n-\tdVwtD8ZdSGP+UIWmz2HZwx+0mrRDddR1vun26hXohxhYGEoY/mU0faTJON0EZ6ptxmu2\n-\tYT5sUWEZe5Rs5WftYeNw7KitoZ2mvdJxaQfhE5yO+52A02fnDy6zJx+6trtVul/wiPck\n-\teDljTXFq3uI+7D47+DXfF34T/iMBA4HdhDZifdC14NKQAtJ5clro6bDocHJEYGRgFCGa\n-\tGBN0Kig2OC4knpRASiSfDk0KTYbF6dmIFNdUwzRUOmv6ZsbsubuZ1VmZ2eTzThd0cyQv\n-\tMl78lDuV13WpJD+pAF9ocVmpiKtou3juSn/JtdL0sqByu6smFZqV8lXIa1zVdNVfr3+o\n-\tWaydvDFYd/tmfX15Q25jYVNpc2VLTWt9W0t7Z0dPZ/+twa6x2xPd0z0vexfvfL/L2698\n-\tz2rA737yg9LB2w+fDX0aYRqVHjN85PY46knReM/E/CRiSvyZ8bTv8/SZuhePZjfmOF6p\n-\tzDssRL7OWapbfrCysPr1A9e64iezP7CbsZ/zt5u+jfz5dmcHALKPMmaXERDM2wDQLUFS\n-\tgMTABP8fbh7Y2dnZghnivrPzJzdACIX/Ddo0yhkKZW5kc3RyZWFtCmVuZG9iago0OSAw\n-\tIG9iagoyNjM0CmVuZG9iagozMCAwIG9iagpbIC9JQ0NCYXNlZCA0OCAwIFIgXQplbmRv\n-\tYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFswIDAgNzU2IDU1M10g\n-\tL0NvdW50IDEgL0tpZHMgWyAyIDAgUiBdID4+CmVuZG9iago1MCAwIG9iago8PCAvVHlw\n-\tZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKNTEg\n-\tMCBvYmoKPDwgL0xlbmd0aCA1MiAwIFIgL0xlbmd0aDEgNzE3MiAvRmlsdGVyIC9GbGF0\n-\tZURlY29kZSA+PgpzdHJlYW0KeAG9WXtYlNW6f9f3fXNBUG4Kw3Vm+BiugwgooJiMOMNF\n-\tTFEUGfMygCCSGClSlhK7dJd4OVtNbWtHs4s7JXME0gG2Ru7c6a6dVrub2043szpPPtU5\n-\tdWqHzJzf+mYk7dn1+EdPfM87613X97d+77vW960FMSIKoDYSyVLTWNVEa2gAJa9AWmta\n-\tmg2bP5+0l4hNIxKX1TUtaQz+4C9/I5JcRMMClixbXff11rzpRCNeJNIa6murFn+jX9ZN\n-\tFHYJ/bPrURAwMOIOovBo5OPrG5vvtm1UP4O8BXnLsjtqqkJygxzItyEf11h1d5N25bDv\n-\tkX8SecPyqsbahPzouchjfEppumNlM3tGqEP+K+QLmlbUNv35geUZRLqxwHcOZQwP/wsg\n-\tNa1AaqOxvhKlWPkRflSv08TrdK8qIVFB1BANRAsh8qNh5I/xhys5TN2XBqJxPwWpTlCS\n-\tqo0ipXTSE3nehVzgqXuO57LqJQpyN3q+FvPQp4eL4M6fSP20mfbQEdh5GnoSLaRH6Cxr\n-\t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\n-\tMlwC69SfSnRJSF6IRc4SqO+P2at/PmaJ/iSkw1t1KBktjukPxizTb491sd2d+m0xLoY+\n-\tW73Jqhh0PaZvTN6pX5yh1E/b6RI6OvXjUV9h8ddn5xr142Iu6dMTXVqGfFrMNH1Kxt/1\n-\t8eiIZgYMarIE66NjtusnoCo2xpY4AdLHDrE9lML2dJqm6nuhYrpdJcm5O13s3q7ipAyT\n-\ti91jyS5O2plcnGhKnqY3JRcmJkKvOKNZp7lNM1mTqUnFBW2CxqiJ0ozUhmiDtCO0Adph\n-\tWq1W42LPdObr1X2sg/JBS0eXVq1VudizKJT62GGl8PBxraQVtKQd6fJ8gH/mMBrpYh3d\n-\tCAxGUI6pFU3tYoexFnjRYYseoYwNRKkIQoTxj2H+SwLTCgghJ9vsUtP6sJZ8XX7IpODx\n-\thdaf+3EoNdd+U3/+T8dinDtxF+M8FGPHtRcUT4z9WnPdNeVn0+ZVqKotSE0tnbW6q6Wp\n-\toU65xpNttQ7c5jk3tuBata3aYDja0OS7o0xwVNfU83ukqlpnk1xrdTbIVsPRFqUfL76u\n-\tuo5Xt8jWo1Rnm115tM5Sa+1ssbTY+HVmV3XBigU32NowZGtFwb+xVcAHW8FtVSv9fmJr\n-\tAa+u5rYWcFsLuK1qS7Vii0/etrS8YGUzohNXfbhqSyp3lsycV4kbbbvVxQ7w+79V9P+8\n-\trYdICmVuZHN0cmVhbQplbmRvYmoKNTIgMCBvYmoKNDM3MQplbmRvYmoKNTMgMCBvYmoK\n-\tPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Bc2NlbnQgNzcwIC9DYXBIZWlnaHQgNzI3\n-\tIC9EZXNjZW50IC0yMzAgL0ZsYWdzIDk2Ci9Gb250QkJveCBbLTkzMyAtNDgxIDE1NzEg\n-\tMTEzOF0gL0ZvbnROYW1lIC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUgL0l0YWxpY0Fu\n-\tZ2xlCi0xMiAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MzEgL0ZvbnRG\n-\taWxlMiA1MSAwIFIgPj4KZW5kb2JqCjU0IDAgb2JqClsgNjY3IDAgMCAwIDAgMCAwIDAg\n-\tODMzIDAgMCAwIDAgMCAwIDAgMCAwIDAgNjY3IDAgMCAwIDAgMCAwIDAgMCA1NTYgMCA1\n-\tMDAKMCA1NTYgMCA1NTYgMCAyMjIgMCAwIDIyMiA4MzMgNTU2IDU1NiA1NTYgMCAwIDAg\n-\tMjc4IDAgMCAwIDUwMCBdCmVuZG9iagoxOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3Vi\n-\tdHlwZSAvVHJ1ZVR5cGUgL0Jhc2VGb250IC9YUUlGU1crSGVsdmV0aWNhLU9ibGlxdWUg\n-\tL0ZvbnREZXNjcmlwdG9yCjUzIDAgUiAvV2lkdGhzIDU0IDAgUiAvRmlyc3RDaGFyIDY5\n-\tIC9MYXN0Q2hhciAxMjAgL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5nCj4+CmVuZG9i\n-\tago1NSAwIG9iago8PCAvTGVuZ3RoIDU2IDAgUiAvTGVuZ3RoMSA5OTcyIC9GaWx0ZXIg\n-\tL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab16e3iU1bX32vu9ziWTmcncM5PJZDIzmdxD\n-\tSMiQQMaQhHsMBCFBggkQCAg1YIyiwkGFIhGpQrkIPVS05RKKGUIKAxQ/ykHR1lPxitdW\n-\tj2i1T/N4Tg/aVpiZb+13Qgo+/fr5R5/OO/u+373X+q2199qXFwgAaGEdcBBeuKK9C54n\n-\t4zHnFXRrF/Z0Zz7+xfi9AGQaALd8cdeSFYaP/uNXAHwUQK1dsnz14rJtr8wH0J0HMF7u\n-\t7Ghf9Kf/XX4SwHMQ3y/vxAx1llSE6Y8wnd25ovu+RRUqC0AWj+l5y+9a2F4WHVuO6TZM\n-\tF69ov69LfkD9V0w/genM77Wv6Jj7wMPbMB3BdFbXXXd3000clmW9ienGrlUdXb945Hsl\n-\tAN5spO9VzCP4sJ8WRFiFYR2Mxhyq5F33uOuR4ZAH4Vs5yaSIgQQyqDBUgwbbZL8U0EEq\n-\t6MGAcSOkgQnMSj5yJZwFvXAGcoR14OCLwA2QeBfdeyyM35b4TLgA+viKxP9wlfgGogQn\n-\taby6Cs7C47AH+pHigxjPgfmwC14my+AkmQeD8DbJgEKUDw9RmAavkETiNVgMP8H63XAO\n-\ttsNRpCsHViAV02AL8SXux3QY4wtgfeIZyIYK+D6cgRC2ugWGEocSx7B0JtwGfXAY3/81\n-\t8dKjfFriucRl5HQGtrkeS15LTEv0I3f5UAONmLsetcLHvZfoBBtUInU/gh/DPvgl/JE8\n-\t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\n-\tVrXe1Nemkb5W1fydvmpYY6tYXwuU977VVysrXsD6amV9tbK+FoQXKH0xCOqWNtXc3Y3a\n-\tiVfbeLWc0xSZPGNuM37B0VIbJfvZffc98H8BcaX7nAplbmRzdHJlYW0KZW5kb2JqCjU2\n-\tIDAgb2JqCjY2ODkKZW5kb2JqCjU3IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRv\n-\tciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0IDcyNyAvRGVzY2VudCAtMjMwIC9GbGFncyAz\n-\tMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9Gb250TmFtZSAvWFlVVFBT\n-\tK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgOTggL01heFdpZHRoIDE1MDAg\n-\tL1N0ZW1IIDg1IC9YSGVpZ2h0IDUzMSAvRm9udEZpbGUyIDU1IDAgUiA+PgplbmRvYmoK\n-\tNTggMCBvYmoKWyA2NjcgNjExIDAgMCAwIDAgMCAwIDgzMyAwIDAgMCAwIDAgMCAwIDcy\n-\tMiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTYgMAo1MDAgNTU2IDU1NiAwIDU1NiA1\n-\tNTYgMjIyIDAgMCAyMjIgODMzIDU1NiA1NTYgNTU2IDAgMzMzIDUwMCAyNzggNTU2IDAg\n-\tMCA1MDAKXQplbmRvYmoKMjAgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1Ry\n-\tdWVUeXBlIC9CYXNlRm9udCAvWFlVVFBTK0hlbHZldGljYSAvRm9udERlc2NyaXB0b3IK\n-\tNTcgMCBSIC9XaWR0aHMgNTggMCBSIC9GaXJzdENoYXIgNjkgL0xhc3RDaGFyIDEyMCAv\n-\tRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1Rp\n-\tdGxlIChVbnRpdGxlZCkgL0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpIC9DcmVhdG9yIChP\n-\tbW5pR3JhZmZsZSkgL1Byb2R1Y2VyCihNYWMgT1MgWCAxMC41LjggUXVhcnR6IFBERkNv\n-\tbnRleHQpIC9DcmVhdGlvbkRhdGUgKEQ6MjAwOTA5MTExNDQwMzFaMDAnMDAnKQovTW9k\n-\tRGF0ZSAoRDoyMDA5MDkxMTE0NDAzMVowMCcwMCcpID4+CmVuZG9iagp4cmVmCjAgNTkK\n-\tMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDQ5MjUyIDAwMDAwIG4gCjAwMDAwMDEwNDEg\n-\tMDAwMDAgbiAKMDAwMDAzNjY3MiAwMDAwMCBuIAowMDAwMDAwMDIyIDAwMDAwIG4gCjAw\n-\tMDAwMDEwMjIgMDAwMDAgbiAKMDAwMDAwMTE0NSAwMDAwMCBuIAowMDAwMDIxNzk2IDAw\n-\tMDAwIG4gCjAwMDAwMDUyMDQgMDAwMDAgbiAKMDAwMDAwNjEzMiAwMDAwMCBuIAowMDAw\n-\tMDAxMzY3IDAwMDAwIG4gCjAwMDAwMDIyODQgMDAwMDAgbiAKMDAwMDAwMjMwNCAwMDAw\n-\tMCBuIAowMDAwMDAzMTYxIDAwMDAwIG4gCjAwMDAwMDMxODEgMDAwMDAgbiAKMDAwMDAw\n-\tNDIyMCAwMDAwMCBuIAowMDAwMDA0MjQwIDAwMDAwIG4gCjAwMDAwMDUxODQgMDAwMDAg\n-\tbiAKMDAwMDAzMTA0NSAwMDAwMCBuIAowMDAwMDQxNjkwIDAwMDAwIG4gCjAwMDAwNDkw\n-\tNzcgMDAwMDAgbiAKMDAwMDAzMDE4MCAwMDAwMCBuIAowMDAwMDA2MTUxIDAwMDAwIG4g\n-\tCjAwMDAwMDkwNDQgMDAwMDAgbiAKMDAwMDAyNzM4NSAwMDAwMCBuIAowMDAwMDE1MjI0\n-\tIDAwMDAwIG4gCjAwMDAwMTc5NTYgMDAwMDAgbiAKMDAwMDAyNDU5MCAwMDAwMCBuIAow\n-\tMDAwMDA5MDY1IDAwMDAwIG4gCjAwMDAwMTIyNDYgMDAwMDAgbiAKMDAwMDAzNjYzNSAw\n-\tMDAwMCBuIAowMDAwMDEyMjY3IDAwMDAwIG4gCjAwMDAwMTUyMDMgMDAwMDAgbiAKMDAw\n-\tMDAzMzg0MCAwMDAwMCBuIAowMDAwMDE3OTc3IDAwMDAwIG4gCjAwMDAwMjA4NjAgMDAw\n-\tMDAgbiAKMDAwMDAyMDg4MSAwMDAwMCBuIAowMDAwMDIxNzc2IDAwMDAwIG4gCjAwMDAw\n-\tMjE4MzIgMDAwMDAgbiAKMDAwMDAyNDU2OSAwMDAwMCBuIAowMDAwMDI0NjI3IDAwMDAw\n-\tIG4gCjAwMDAwMjczNjQgMDAwMDAgbiAKMDAwMDAyNzQyMiAwMDAwMCBuIAowMDAwMDMw\n-\tMTU5IDAwMDAwIG4gCjAwMDAwMzAyMTcgMDAwMDAgbiAKMDAwMDAzMTAyNSAwMDAwMCBu\n-\tIAowMDAwMDMxMDgyIDAwMDAwIG4gCjAwMDAwMzM4MTkgMDAwMDAgbiAKMDAwMDAzMzg3\n-\tNyAwMDAwMCBuIAowMDAwMDM2NjE0IDAwMDAwIG4gCjAwMDAwMzY3NTUgMDAwMDAgbiAK\n-\tMDAwMDAzNjgxOSAwMDAwMCBuIAowMDAwMDQxMjgwIDAwMDAwIG4gCjAwMDAwNDEzMDEg\n-\tMDAwMDAgbiAKMDAwMDA0MTUzNiAwMDAwMCBuIAowMDAwMDQxODczIDAwMDAwIG4gCjAw\n-\tMDAwNDg2NTIgMDAwMDAgbiAKMDAwMDA0ODY3MyAwMDAwMCBuIAowMDAwMDQ4OTA5IDAw\n-\tMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNTkgL1Jvb3QgNTAgMCBSIC9JbmZvIDEgMCBS\n-\tIC9JRCBbIDxmOTA3NjFiZGExNmY3ZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4KPGY5MDc2MWJk\n-\tYTE2ZjdlMmUwOTIyMDYyODdmZDhmMDNhPiBdID4+CnN0YXJ0eHJlZgo0OTQ2MAolJUVP\n-\tRgoxIDAgb2JqCjw8L0F1dGhvciAoVGhvbWFzIFJpc2JlcmcpL0NyZWF0aW9uRGF0ZSAo\n-\tRDoyMDA5MDkxMTE0MTUwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIDUuMS4xKS9Nb2RE\n-\tYXRlIChEOjIwMDkwOTExMTQzODAwWikvUHJvZHVjZXIgKE1hYyBPUyBYIDEwLjUuOCBR\n-\tdWFydHogUERGQ29udGV4dCkvVGl0bGUgKFVudGl0bGVkKT4+CmVuZG9iagp4cmVmCjEg\n-\tMQowMDAwMDUwNzk4IDAwMDAwIG4gCnRyYWlsZXIKPDwvSUQgWzxmOTA3NjFiZGExNmY3\n-\tZTJlMDkyMjA2Mjg3ZmQ4ZjAzYT4gPGY5MDc2MWJkYTE2ZjdlMmUwOTIyMDYyODdmZDhm\n-\tMDNhPl0gL0luZm8gMSAwIFIgL1ByZXYgNDk0NjAgL1Jvb3QgNTAgMCBSIC9TaXplIDU5\n-\tPj4Kc3RhcnR4cmVmCjUwOTkzCiUlRU9GCg==\n-\t\n-\tQuickLookThumbnail\n-\t\n-\t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\n-\tAdQB+wIkAk8CewKpAtkDCgM9A3IDqQPiBBwEWQSXBNcFGQVdBaIF6gYzBn4GywcaB2sH\n-\tvggTCGoIwwkdCXoJ2Qo5CpwLAQtnC9AMOgynDRYNhg35Dm4O5Q9eD9kQVhDVEVYR2RJe\n-\tEuYTbxP7FIkVGRWqFj8W1RdtGAgYpBlDGeQahxssG9Qcfh0pHdcehx86H+4gpSFeIhki\n-\t1yOWJFglHCXjJqsndihDKRIp5Cq3K44sZi1ALh0u/C/eMMExpzKQM3o0ZzVWNkg3PDgy\n-\tOSo6JTsiPCE9Iz4nPy5ANkFBQk9DX0RxRYVGnEe1SNFJ70sPTDJNV05/T6lQ1VIEUzVU\n-\taFWeVtdYEVlOWo5b0F0UXltfpGDwYj5jj2TiZjdnj2jpakZrpW0Hbmtv0nE7cqd0FXWF\n-\tdvh4bnnme2B83X5df9+BY4LqhHOF/4eOiR+KsoxIjeGPfJEZkrmUXJYBl6mZU5sAnK+e\n-\tYaAVocyjhqVCpwGowqqFrEyuFa/gsa6zf7VStyi5ALrbvLi+mMB7wmDESMYyyCDKD8wB\n-\tzfbP7tHo0+XV5Nfm2erb8d374AjiF+Qo5j3oVOpt7InuqPDK8u71Ffc++Wr7mf3K//9j\n-\tdXJ2AAAAAAAAAQAAAAAAAAEAAwAHAAsAEQAYACAAKQA0AEEATgBdAG4AgACUAKkAwADY\n-\tAPIBDQEqAUkBaQGLAa8B1AH7AiQCTwJ7AqkC2QMKAz0DcgOpA+IEHARZBJcE1wUZBV0F\n-\togXqBjMGfgbLBxoHawe+CBMIagjDCR0JegnZCjkKnAsBC2cL0Aw6DKcNFg2GDfkObg7l\n-\tD14P2RBWENURVhHZEl4S5hNvE/sUiRUZFaoWPxbVF20YCBikGUMZ5BqHGywb1Bx+HSkd\n-\t1x6HHzof7iClIV4iGSLXI5YkWCUcJeMmqyd2KEMpEinkKrcrjixmLUAuHS78L94wwTGn\n-\tMpAzejRnNVY2SDc8ODI5KjolOyI8IT0jPic/LkA2QUFCT0NfRHFFhUacR7VI0UnvSw9M\n-\tMk1XTn9PqVDVUgRTNVRoVZ5W11gRWU5ajlvQXRReW1+kYPBiPmOPZOJmN2ePaOlqRmul\n-\tbQdua2/ScTtyp3QVdYV2+HhueeZ7YHzdfl1/34FjguqEc4X/h46JH4qyjEiN4Y98kRmS\n-\tuZRclgGXqZlTmwCcr55hoBWhzKOGpUKnAajCqoWsTK4Vr+CxrrN/tVK3KLkAutu8uL6Y\n-\twHvCYMRIxjLIIMoPzAHN9s/u0ejT5dXk1+bZ6tvx3fvgCOIX5CjmPehU6m3sie6o8Mry\n-\t7vUV9z75avuZ/cr//2N1cnYAAAAAAAABAAAAAAAAAQADAAcACwARABgAIAApADQAQQBO\n-\tAF0AbgCAAJQAqQDAANgA8gENASoBSQFpAYsBrwHUAfsCJAJPAnsCqQLZAwoDPQNyA6kD\n-\t4gQcBFkElwTXBRkFXQWiBeoGMwZ+BssHGgdrB74IEwhqCMMJHQl6CdkKOQqcCwELZwvQ\n-\tDDoMpw0WDYYN+Q5uDuUPXg/ZEFYQ1RFWEdkSXhLmE28T+xSJFRkVqhY/FtUXbRgIGKQZ\n-\tQxnkGocbLBvUHH4dKR3XHocfOh/uIKUhXiIZItcjliRYJRwl4yarJ3YoQykSKeQqtyuO\n-\tLGYtQC4dLvwv3jDBMacykDN6NGc1VjZINzw4MjkqOiU7IjwhPSM+Jz8uQDZBQUJPQ19E\n-\tcUWFRpxHtUjRSe9LD0wyTVdOf0+pUNVSBFM1VGhVnlbXWBFZTlqOW9BdFF5bX6Rg8GI+\n-\tY49k4mY3Z49o6WpGa6VtB25rb9JxO3KndBV1hXb4eG555ntgfN1+XX/fgWOC6oRzhf+H\n-\tjokfirKMSI3hj3yRGZK5lFyWAZepmVObAJyvnmGgFaHMo4alQqcBqMKqhaxMrhWv4LGu\n-\ts3+1UrcouQC627y4vpjAe8JgxEjGMsggyg/MAc32z+7R6NPl1eTX5tnq2/Hd++AI4hfk\n-\tKOY96FTqbeyJ7qjwyvLu9RX3Pvlq+5n9yv//WFlaIAAAAAAAAPbVAAEAAAAA0ytYWVog\n-\tAAAAAAAAAHoAAAB+AAAAaG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAagAAABwAQwBvAHAA\n-\teQByAGkAZwBoAHQAIAAoAGMAKQAgAFgALQBSAGkAdABlACwAIAAyADAAMAAxAC0AMgAw\n-\tADAANwAuACAAQQBsAGwAIABSAGkAZwBoAHQAcwAgAFIAZQBzAGUAcgB2AGUAZAAuAAB2\n-\tY2d0AAAAAAAAAAAAAwEAAAIAAAFtAtkERgWyBx8Iiwn4C2QM0Q49D6oRFhKDE+8VXBZh\n-\tF2cYbBlyGncbfRyCHYgejR+TIJkhniKkI6kkryWWJn0nZShMKTMqGysCK+ks0S24Lp8v\n-\thzBuMVUyPTMmNBA0+jXjNs03tzigOYo6cztdPEc9MD4aPwQ/7UDsQetC6UPoROdF5Ubk\n-\tR+JI4UngSt5L3UzcTdpO2U/qUPpSC1McVCxVPVZOV15Yb1mAWpBboVyyXcJe01/gYOxh\n-\t+WMFZBJlHmYrZzdoRGlQal1ramx2bYNuj2+lcLtx0XLmc/x1EnYodz54U3lpen97lXyr\n-\tfcB+1n/SgM+By4LHg8OEwIW8hriHtIiwia2KqYuljKGNno6Cj2aQSpEvkhOS95PclMCV\n-\tpJaJl22YUZk1mhqa/pvcnLqdl551n1OgMKEOoeyiyqOnpIWlY6ZBpx6n/Kjdqb2qnat+\n-\trF6tP64frv+v4LDAsaGygbNitEK1IrYCtuG3wLifuX66Xbs8vBu8+r3Zvri/l8B2wVbC\n-\tNcMHw9nErMV+xlDHI8f1yMfJmcpsyz7MEMzjzbXOh89E0ALQv9F80jnS9tOz1HDVLdXq\n-\t1qfXZdgi2N/ZnNpP2wHbtNxn3Rrdzd6A3zLf5eCY4Uvh/uKw42PkFuS+5WbmDea1513o\n-\tBOis6VTp/Oqj60vr8+ya7ULt6gAAAS4CWwOJBLcF5AcSCEAJbQqbC8kM9g4kD1IQgBGt\n-\tEogTYxQ+FRkV9BbOF6kYhBlfGjobFRvwHMsdpR6AHxsftiBRIOwhhyIiIr0jWCPzJI4l\n-\tKSXEJl8m+ieVKEIo8CmdKksq+CumLFMtAS2uLlsvCS+2MGQxETG/MnIzJTPYNIs1PjXy\n-\tNqU3WDgLOL45cTokOtg7izw+PQQ9yT6PP1VAG0DhQadCbEMyQ/hEvkWERklHD0fVSLBJ\n-\tikplSz9MGkz1Tc9Oqk+EUF9ROVIUUu9TyVSkVY1Wd1dgWElZM1ocWwZb71zZXcJerF+V\n-\tYH5haGJRYylkAWTZZbBmiGdgaDhpD2nnar9rl2xvbUZuHm72b8JwjnFZciVy8XO9dIl1\n-\tVHYgdux3uHiEeU96G3rne8l8rH2OfnB/U4A1gReB+oLcg76EoYWDhmWHSIgqiN+JlYpK\n-\tiwCLtYxrjSCN1o6Lj0GP9pCskWGSF5LMk4uUSpUIlceWhpdEmAOYwpmAmj+a/pu8nHud\n-\tOp34nrOfbaAnoOGhnKJWoxCjyqSFpT+l+aazp26oKKjiqYqqM6rbq4OsK6zUrXyuJK7N\n-\tr3WwHbDFsW6yFrK+s2u0F7TEtXC2HbbJt3a4IrjPuXu6KLrUu4G8LbzavYu+Pb7vv6DA\n-\tUsEDwbXCZsMYw8nEe8Usxd7Gj8dBAAABPAJ4A7QE8AYsB2gIpAngCxwMWA2UDtAQDBFI\n-\tEoQTZxRJFSwWDhbxF9MYthmYGnsbXhxAHSMeBR7oH8ogeCEmIdMigSMvI9wkiiU4JeYm\n-\tkydBJ+8onClKKfgqqCtYLAgsuS1pLhkuyS95MCkw2jGKMjoy6jOaNEo1DjXRNpU3WDgc\n-\tON85ozpmOyo77TyxPXQ+Nz77P75AmEFxQktDJEP+RNdFsUaKR2RIPUkXSfBKykujTH1N\n-\tc05pT2BQVlFNUkNTOlQwVSdWHVcTWApZAFn3Wu1b21zIXbZepF+RYH9hbWJaY0hkNmUj\n-\tZhFm/2fsaNpp0mrLa8RsvG21bq5vpnCfcZhykHOJdIJ1enZzd2x4bHltem57b3xvfXB+\n-\tcX9ygHKBc4J0g3SEdYV2hneHXYhDiSmKD4r1i9uMwY2njo2Pc5BZkT+SJZMLk/GU1ZW6\n-\tlp6Xg5hnmUuaMJsUm/mc3Z3CnqafiqBvoVOiR6M6pC2lIKYUpwen+qjtqeGq1KvHrLut\n-\trq6hr5SwmbGfsqSzqbSutbO2uLe9uMK5x7rNu9K8173cvuG//MEXwjPDTsRpxYTGn8e7\n-\tyNbJ8csMzCfNQ85ez3nQm9G90t/UAdUj1kbXaNiK2azaztvw3RLeNN9W4HjikuSs5sbo\n-\t4Or67RTvL/FJ82P1ffeX+bH7y/3l//8AAHNmMzIAAAAAAAEN+QAAB+QAAAIBAAAMYwAA\n-\t9SH////2AAABX////RUAARx2\n-\t\n-\tReadOnly\n-\tNO\n-\tRowAlign\n-\t1\n-\tRowSpacing\n-\t36\n-\tSheetTitle\n-\tCanvas 1\n-\tSmartAlignmentGuidesActive\n-\tYES\n-\tSmartDistanceGuidesActive\n-\tYES\n-\tUniqueID\n-\t1\n-\tUseEntirePage\n-\t\n-\tVPages\n-\t1\n-\tWindowInfo\n-\t\n-\t\tCurrentSheet\n-\t\t0\n-\t\tExpandedCanvases\n-\t\t\n-\t\t\t\n-\t\t\t\tname\n-\t\t\t\tCanvas 1\n-\t\t\t\n-\t\t\n-\t\tFrame\n-\t\t{{218, 52}, {999, 826}}\n-\t\tListView\n-\t\t\n-\t\tOutlineWidth\n-\t\t142\n-\t\tRightSidebar\n-\t\t\n-\t\tShowRuler\n-\t\t\n-\t\tSidebar\n-\t\t\n-\t\tSidebarWidth\n-\t\t120\n-\t\tVisibleRegion\n-\t\t{{-54, -59}, {864, 672}}\n-\t\tZoom\n-\t\t1\n-\t\tZoomValues\n-\t\t\n-\t\t\t\n-\t\t\t\tCanvas 1\n-\t\t\t\t1\n-\t\t\t\t1\n-\t\t\t\n-\t\t\n-\t\n-\tsaveQuickLookFiles\n-\tYES\n-\n-\ndiff --git a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png b/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png\ndeleted file mode 100644\nindex 8515e7c4887a..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/oxm-exceptions.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/prototype.png b/framework-docs/src/docs/asciidoc/images/prototype.png\ndeleted file mode 100644\nindex 26fa2c1cf2d9..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/prototype.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/singleton.png b/framework-docs/src/docs/asciidoc/images/singleton.png\ndeleted file mode 100644\nindex 591520ec1dcc..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/singleton.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png b/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png\ndeleted file mode 100644\nindex 6e0eeab744d4..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/spring-mvc-and-webflux-venn.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx.png b/framework-docs/src/docs/asciidoc/images/tx.png\ndeleted file mode 100644\nindex 06f2e77c76f8..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png b/framework-docs/src/docs/asciidoc/images/tx_prop_required.png\ndeleted file mode 100644\nindex 218790aca635..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_required.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png b/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png\ndeleted file mode 100644\nindex a8ece48193f3..000000000000\nBinary files a/framework-docs/src/docs/asciidoc/images/tx_prop_requires_new.png and /dev/null differ\ndiff --git a/framework-docs/src/docs/asciidoc/index-docinfo-header.html b/framework-docs/src/docs/asciidoc/index-docinfo-header.html\ndeleted file mode 100644\nindex 485f2e4e9803..000000000000\n--- a/framework-docs/src/docs/asciidoc/index-docinfo-header.html\n+++ /dev/null\n@@ -1,9 +0,0 @@\n-

\n-

Spring Framework Documentation

\n-\n-{revnumber}\n-
\ndiff --git a/framework-docs/src/docs/asciidoc/spring-framework.adocbook b/framework-docs/src/docs/asciidoc/spring-framework.adocbook\ndeleted file mode 100644\nindex e020f7337c2d..000000000000\n--- a/framework-docs/src/docs/asciidoc/spring-framework.adocbook\n+++ /dev/null\n@@ -1,26 +0,0 @@\n-:noheader:\n-:toc:\n-:toclevels: 4\n-:tabsize: 4\n-include::attributes.adoc[]\n-= Spring Framework Documentation\n-Rod Johnson; Juergen Hoeller; Keith Donald; Colin Sampaleanu; Rob Harrop; Thomas Risberg; Alef Arendsen; Darren Davison; Dmitriy Kopylenko; Mark Pollack; Thierry Templier; Erwin Vervaet; Portia Tung; Ben Hale; Adrian Colyer; John Lewis; Costin Leau; Mark Fisher; Sam Brannen; Ramnivas Laddad; Arjen Poutsma; Chris Beams; Tareq Abedrabbo; Andy Clement; Dave Syer; Oliver Gierke; Rossen Stoyanchev; Phillip Webb; Rob Winch; Brian Clozel; Stephane Nicoll; Sebastien Deleuze; Jay Bryant; Mark Paluch\n-\n-NOTE: This documentation is also available in {docs-spring-framework}/reference/html/index.html[HTML] format.\n-\n-[[legal]]\n-== Legal\n-\n-Copyright \u00a9 2002 - 2023 VMware, Inc. All Rights Reserved.\n-\n-Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.\n-\n-include::overview.adoc[leveloffset=+1]\n-include::core.adoc[leveloffset=+1]\n-include::testing.adoc[leveloffset=+1]\n-include::data-access.adoc[leveloffset=+1]\n-include::web.adoc[leveloffset=+1]\n-include::web-reactive.adoc[leveloffset=+1]\n-include::integration.adoc[leveloffset=+1]\n-include::languages.adoc[leveloffset=+1]\n-include::appendix.adoc[leveloffset=+1]\n", "metadata": {"problem_domain": "Documentation Updates", "difficulty": "low", "estimated_review_effort": 3}} +{"instance_id": "spring-projects__spring-framework-29727@4fc2689", "repo": "spring-projects/spring-framework", "language": "Java", "pull_number": 29727, "title": "Add Kotlin DSL support for MockMVC andExpectAll", "body": "As the DSL internally calls `ResultActions.andExpect`, this is done with a trick where a synthetic `ResultActions` is provided at top level which stores each `ResultMatcher` in a mutable list. Once the DSL usage is done, the top level DSL `andExpectAll` turns that list into a `vararg` passed down to the actual `actions.andExpectAll`.\r\n\r\nCloses gh-27317\r\n", "created_at": "2022-12-21T16:12:03Z", "problem_statement": "Introduce Kotlin DSL for `ResultActions.andExpectAll()`\n## Overview\r\n\r\nCommit dd9b99e13d6b30462fb168799e6bbca1456123da introduced `ResultActions.andExpectAll()` to support _soft assertions_ in `MockMvc`.\r\n\r\n`ResultActionsDsl.kt` already has support for `andExpect()`.\r\n\r\n\r\n## Related Issues\r\n\r\n- #27318\r\n\r\n## Deliverables\r\n\r\n- [x] Introduce Kotlin support for `ResultActions.andExpectAll()` in `ResultActionsDsl.kt`. => #29727 \r\n- [x] Add a Kotlin example using `andExpectAll()` in the reference manual alongside the Java example introduced in dd9b99e13d6b30462fb168799e6bbca1456123da. => #29766", "hints_text": "", "resolved_issues": [{"number": 27317, "title": "Introduce Kotlin DSL for `ResultActions.andExpectAll()`", "body": "## Overview\r\n\r\nCommit dd9b99e13d6b30462fb168799e6bbca1456123da introduced `ResultActions.andExpectAll()` to support _soft assertions_ in `MockMvc`.\r\n\r\n`ResultActionsDsl.kt` already has support for `andExpect()`.\r\n\r\n\r\n## Related Issues\r\n\r\n- #27318\r\n\r\n## Deliverables\r\n\r\n- [x] Introduce Kotlin support for `ResultActions.andExpectAll()` in `ResultActionsDsl.kt`. => #29727 \r\n- [x] Add a Kotlin example using `andExpectAll()` in the reference manual alongside the Java example introduced in dd9b99e13d6b30462fb168799e6bbca1456123da. => #29766 "}], "base_commit": "697292ba0ca5aa69454e7a184197be90c75de3ab", "commit_to_review": {"head_commit": "4fc268959235c12426202938f479ba079a3a3e9b", "head_commit_message": "Add Kotlin DSL support for MockMVC andExpectAll\n\nAs the DSL internally calls ResultActions.andExpect, this is done with\na trick where a synthetic ResultActions is provided at top level which\nstores each ResultMatcher in a mutable list. Once the DSL usage is done,\n the top level DSL andExpectAll turns that list into a vararg passed\n down to the actual `actions.andExpectAll`.\n\nFixes gh-27317.", "patch_to_review": "diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\nindex 8971a80f4b5c..0ba22eafa1c4 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {\n+\t\tactions.andExpectAll(*matchers)\n+\t}\n }\ndiff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\nindex 128b9492b8c4..2bc0ffb426d3 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {\n+\t\tval softMatchers = mutableListOf()\n+\t\tval softActions = object : ResultActions {\n+\t\t\toverride fun andExpect(matcher: ResultMatcher): ResultActions {\n+\t\t\t\tsoftMatchers.add(matcher)\n+\t\t\t\treturn this\n+\t\t\t}\n+\n+\t\t\toverride fun andDo(handler: ResultHandler): ResultActions {\n+\t\t\t\tthrow UnsupportedOperationException(\"andDo should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t\toverride fun andReturn(): MvcResult {\n+\t\t\t\tthrow UnsupportedOperationException(\"andReturn should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t}\n+\t\t// the use of softActions as the matchers DSL actions parameter will store ResultMatchers in list\n+\t\tMockMvcResultMatchersDsl(softActions).dsl()\n+\t\tactions.andExpectAll(*softMatchers.toTypedArray())\n+\t\treturn this;\n+\t}\n+\n \t/**\n \t * Provide access to [MockMvcResultHandlersDsl] Kotlin DSL.\n \t * @see MockMvcResultHandlersDsl.handle\ndiff --git a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\nindex d1e731f3bc27..40e1ded9caf1 100644\n--- a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n+++ b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n@@ -17,6 +17,7 @@\n package org.springframework.test.web.servlet\n \n import org.assertj.core.api.Assertions.assertThat\n+import org.assertj.core.api.Assertions.assertThatCode\n import org.assertj.core.api.Assertions.assertThatExceptionOfType\n import org.hamcrest.CoreMatchers\n import org.junit.jupiter.api.Test\n@@ -25,6 +26,7 @@ import org.springframework.http.HttpStatus\n import org.springframework.http.MediaType.APPLICATION_ATOM_XML\n import org.springframework.http.MediaType.APPLICATION_JSON\n import org.springframework.http.MediaType.APPLICATION_XML\n+import org.springframework.http.MediaType.TEXT_PLAIN\n import org.springframework.test.web.Person\n import org.springframework.test.web.servlet.setup.MockMvcBuilders\n import org.springframework.web.bind.annotation.GetMapping\n@@ -183,6 +185,22 @@ class MockMvcExtensionsTests {\n \t\t}\n \t}\n \n+\t@Test\n+\tfun `andExpectAll reports multiple assertion errors`() {\n+\t\tassertThatCode {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\") {\n+\t\t\t\taccept = APPLICATION_JSON\n+\t\t\t}.andExpectAll {\n+\t\t\t\tstatus { is4xxClientError() }\n+\t\t\t\tcontent { contentType(TEXT_PLAIN) }\n+\t\t\t\tjsonPath(\"$.name\") { value(\"Lee\") }\n+\t\t\t}\n+\t\t}\n+\t\t\t\t.hasMessage(\"Multiple Exceptions (2):\\n\" +\n+\t\t\t\t\t\t\"Range for response status value 200 expected: but was:\\n\" +\n+\t\t\t\t\t\t\"Content type expected: but was:\")\n+\t}\n+\n \n \t@RestController\n \tprivate class PersonController {\n"}, "reference_review_comments": [{"text": "@user1:\nMaybe add a related usage in tests?\n\n@author:\ndone", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diff_hunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {", "line": 153, "start_line": null, "original_line": 152, "original_start_line": null}, {"text": "@user1:\nClever trick, seems to provide a desired behavior, so good catch!", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diff_hunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {", "line": 28, "start_line": null, "original_line": 27, "original_start_line": null}, {"text": "@user2:\nMaybe add `@user1 6.0.4`?", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diff_hunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll", "line": 151, "start_line": null, "original_line": 150, "original_start_line": null}, {"text": "@user2:\nMaybe add `@user1 6.0.4`?", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diff_hunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll", "line": 26, "start_line": null, "original_line": 25, "original_start_line": null}], "merged_commit": "16bbf3ed40891259aaa4cde17da700027bb481bc", "merged_patch": "diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\nindex 8971a80f4b5c..593f666ec2ea 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt\n@@ -145,4 +145,12 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @since 6.0.4\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {\n+\t\tactions.andExpectAll(*matchers)\n+\t}\n }\ndiff --git a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\nindex 128b9492b8c4..5d413702467d 100644\n--- a/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n+++ b/spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt\n@@ -19,6 +19,35 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @since 6.0.4\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {\n+\t\tval softMatchers = mutableListOf()\n+\t\tval softActions = object : ResultActions {\n+\t\t\toverride fun andExpect(matcher: ResultMatcher): ResultActions {\n+\t\t\t\tsoftMatchers.add(matcher)\n+\t\t\t\treturn this\n+\t\t\t}\n+\n+\t\t\toverride fun andDo(handler: ResultHandler): ResultActions {\n+\t\t\t\tthrow UnsupportedOperationException(\"andDo should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t\toverride fun andReturn(): MvcResult {\n+\t\t\t\tthrow UnsupportedOperationException(\"andReturn should not be part of andExpectAll DSL calls\")\n+\t\t\t}\n+\n+\t\t}\n+\t\t// the use of softActions as the matchers DSL actions parameter will store ResultMatchers in list\n+\t\tMockMvcResultMatchersDsl(softActions).dsl()\n+\t\tactions.andExpectAll(*softMatchers.toTypedArray())\n+\t\treturn this;\n+\t}\n+\n \t/**\n \t * Provide access to [MockMvcResultHandlersDsl] Kotlin DSL.\n \t * @see MockMvcResultHandlersDsl.handle\ndiff --git a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\nindex d1e731f3bc27..737e235d4e33 100644\n--- a/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n+++ b/spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt\n@@ -17,6 +17,7 @@\n package org.springframework.test.web.servlet\n \n import org.assertj.core.api.Assertions.assertThat\n+import org.assertj.core.api.Assertions.assertThatCode\n import org.assertj.core.api.Assertions.assertThatExceptionOfType\n import org.hamcrest.CoreMatchers\n import org.junit.jupiter.api.Test\n@@ -25,6 +26,7 @@ import org.springframework.http.HttpStatus\n import org.springframework.http.MediaType.APPLICATION_ATOM_XML\n import org.springframework.http.MediaType.APPLICATION_JSON\n import org.springframework.http.MediaType.APPLICATION_XML\n+import org.springframework.http.MediaType.TEXT_PLAIN\n import org.springframework.test.web.Person\n import org.springframework.test.web.servlet.setup.MockMvcBuilders\n import org.springframework.web.bind.annotation.GetMapping\n@@ -97,6 +99,24 @@ class MockMvcExtensionsTests {\n \t\tassertThat(handlerInvoked).isTrue()\n \t}\n \n+\t@Test\n+\tfun `request with two custom matchers and matchAll`() {\n+\t\tvar matcher1Invoked = false\n+\t\tvar matcher2Invoked = false\n+\t\tval matcher1 = ResultMatcher { matcher1Invoked = true; throw AssertionError(\"expected\") }\n+\t\tval matcher2 = ResultMatcher { matcher2Invoked = true }\n+\t\tassertThatExceptionOfType(AssertionError::class.java).isThrownBy {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\")\n+\t\t\t\t\t.andExpect {\n+\t\t\t\t\t\tmatchAll(matcher1, matcher2)\n+\t\t\t\t\t}\n+\t\t}\n+\t\t\t\t.withMessage(\"expected\")\n+\n+\t\tassertThat(matcher1Invoked).describedAs(\"matcher1\").isTrue()\n+\t\tassertThat(matcher2Invoked).describedAs(\"matcher2\").isTrue()\n+\t}\n+\n \t@Test\n \tfun get() {\n \t\tmockMvc.get(\"/person/{name}\", \"Lee\") {\n@@ -183,6 +203,22 @@ class MockMvcExtensionsTests {\n \t\t}\n \t}\n \n+\t@Test\n+\tfun `andExpectAll reports multiple assertion errors`() {\n+\t\tassertThatCode {\n+\t\t\tmockMvc.request(HttpMethod.GET, \"/person/{name}\", \"Lee\") {\n+\t\t\t\taccept = APPLICATION_JSON\n+\t\t\t}.andExpectAll {\n+\t\t\t\tstatus { is4xxClientError() }\n+\t\t\t\tcontent { contentType(TEXT_PLAIN) }\n+\t\t\t\tjsonPath(\"$.name\") { value(\"Lee\") }\n+\t\t\t}\n+\t\t}\n+\t\t\t\t.hasMessage(\"Multiple Exceptions (2):\\n\" +\n+\t\t\t\t\t\t\"Range for response status value 200 expected: but was:\\n\" +\n+\t\t\t\t\t\t\"Content type expected: but was:\")\n+\t}\n+\n \n \t@RestController\n \tprivate class PersonController {\n", "metadata": {"problem_domain": "New Feature Additions", "difficulty": "medium", "estimated_review_effort": 3}} +{"instance_id": "spring-projects__spring-framework-27735@3017beb", "repo": "spring-projects/spring-framework", "language": "Java", "pull_number": 27735, "title": "DataAccessUtils result accessors with Optional return value", "body": "Closes #27728\r\n(https://github.com/spring-projects/spring-framework/issues/27728)\r\n\r\nHi everyone, this is my first PR in any project here on github with the goal of improving my understanding of java. Hope i understood the enhancement request correctly.", "created_at": "2021-11-26T00:46:59Z", "problem_statement": "DataAccessUtils result accessors with Optional return value\nRelated to #724, `DataAccessUtils` should provide an `optionalResult` method for `Collection` as well as `Stream` arguments (and also for `Iterator` because we need that internally anyway), returning a corresponding `Optional` wrapper or `Optional.empty()`.\r\n\r\nIn addition, a `singleResult` overload for a `Stream` argument (and for `Iterator`) would complete the overall arrangement in `DataAccessUtils`.", "hints_text": "Superseded by #27735.", "resolved_issues": [{"number": 27728, "title": "DataAccessUtils result accessors with Optional return value", "body": "Related to #724, `DataAccessUtils` should provide an `optionalResult` method for `Collection` as well as `Stream` arguments (and also for `Iterator` because we need that internally anyway), returning a corresponding `Optional` wrapper or `Optional.empty()`.\r\n\r\nIn addition, a `singleResult` overload for a `Stream` argument (and for `Iterator`) would complete the overall arrangement in `DataAccessUtils`."}], "base_commit": "2f32806bcb6cefa6479074d5fb66cb68043cedc9", "commit_to_review": {"head_commit": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f", "head_commit_message": "fix closing bracket", "patch_to_review": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..95db075cdc9a 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..92218d0a7410 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n"}, "reference_review_comments": [{"text": "@user1:\nI think IncorrectResultSizeDataAccessException should contain the size of the results stream.\r\nif `resultList.size()` will be used, actual size of IncorrectResultSizeDataAccessException is `<=2` always unlike actual size of results.\r\n\r\nIf prefer stream way, How about utilze `teeing`?\r\n```java\r\n\t\tresults.collect(teeing(counting(), reducing((first, second) -> first), (count, result) -> {\r\n\t\t\tif (count > 1) {\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, count.intValue());\r\n\t\t\t}\r\n\t\t\treturn result.orElse(null);\r\n\t\t}))\r\n```\n\n@user2:\nJust a suggestion. There are multiple constructors provided by `IncorrectResultSizeDataAccessException` class. \r\n\r\n* One of the constructors doesn't take `actualSize` argument and assigns the value `-1` if the size if unknown. You can consider using it\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-)\r\n* Another constructor explicitly suggests setting the value of `actualSize` to `-1` if size is unknown\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize, int actualSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-int-)\r\n\r\nBoth of them would be suitable for this scenario since size is unknown\n\n@user1:\nIt makes sense.\n\n@user2:\n```suggestion\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour\n\n@author:\nyeah let's use the `public IncorrectResultSizeDataAccessException(int expectedSize)` for the iterator and stream method. \r\nWhat do you mean by \"UT\"?\r\n\r\nEdit: nevermind, figured it out \ud83d\ude04", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "start_line": null, "original_line": 80, "original_start_line": null}, {"text": "@user1:\nSame suggestion as above - [Link](https://github.com/spring-projects/spring-framework/pull/27735/files#r757849057). Since `actualSize` of the iterator isn't known beforehand, we can use `public IncorrectResultSizeDataAccessException(int expectedSize)` constructor and set the `actualSize` as `-1`\r\n```suggestion\r\n\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diff_hunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);", "line": null, "start_line": null, "original_line": 102, "original_start_line": null}], "merged_commit": "1891fa45b5d43a3741905531f8b84944a7c820e0", "merged_patch": "diff --git a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\nindex adb80a3afb7a..ce359d4be574 100644\n--- a/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n+++ b/spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\n@@ -17,6 +17,10 @@\n package org.springframework.dao.support;\n \n import java.util.Collection;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.stream.Stream;\n \n import org.springframework.dao.DataAccessException;\n import org.springframework.dao.EmptyResultDataAccessException;\n@@ -56,6 +60,89 @@ public static T singleResult(@Nullable Collection results) throws Incorre\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\treturn Optional.ofNullable(singleResult(results));\n+\t}\n+\n \t/**\n \t * Return a single result object from the given Collection.\n \t *

Throws an exception if 0 or more than 1 element found.\ndiff --git a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\nindex 8d5ac6e9412f..0efee06ca6ac 100644\n--- a/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n+++ b/spring-tx/src/test/java/org/springframework/dao/support/DataAccessUtilsTests.java\n@@ -23,6 +23,7 @@\n import java.util.HashMap;\n import java.util.HashSet;\n import java.util.Map;\n+import java.util.Optional;\n import java.util.function.Consumer;\n \n import org.junit.jupiter.api.Test;\n@@ -47,6 +48,13 @@ public void withEmptyCollection() {\n \n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isNull();\n \n+\t\tassertThat(DataAccessUtils.singleResult(col)).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isNull();\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isNull();\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();\n+\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.requiredUniqueResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 0));\n@@ -89,6 +97,30 @@ public void withTooLargeCollection() {\n \t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.longResult(col))\n \t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.singleResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col))\n+\t\t\t.satisfies(sizeRequirements(1, 2));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.stream()))\n+\t\t\t.satisfies(sizeRequirements(1));\n+\n+\t\tassertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->\n+\t\t\t\tDataAccessUtils.optionalResult(col.iterator()))\n+\t\t\t.satisfies(sizeRequirements(1));\n \t}\n \n \t@Test\n@@ -102,6 +134,12 @@ public void withInteger() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5));\n \t}\n \n \t@Test\n@@ -139,6 +177,12 @@ public void withLong() {\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"5\");\n \t\tassertThat(DataAccessUtils.intResult(col)).isEqualTo(5);\n \t\tassertThat(DataAccessUtils.longResult(col)).isEqualTo(5);\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(5L));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(5L));\n \t}\n \n \t@Test\n@@ -149,6 +193,12 @@ public void withString() {\n \t\tassertThat(DataAccessUtils.uniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(\"test1\");\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(\"test1\");\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(\"test1\"));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(\"test1\"));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -167,6 +217,12 @@ public void withDate() {\n \t\tassertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);\n \t\tassertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());\n+\t\tassertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);\n+\t\tassertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));\n+\t\tassertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));\n \n \t\tassertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->\n \t\t\t\tDataAccessUtils.intResult(col));\n@@ -199,6 +255,13 @@ private Consumer sizeRequi\n \t\t};\n \t}\n \n+\tprivate Consumer sizeRequirements(\n+\t\t\tint expectedSize) {\n+\t\treturn ex -> {\n+\t\t\tassertThat(ex.getExpectedSize()).as(\"expected size\").isEqualTo(expectedSize);\n+\t\t};\n+\t}\n+\n \tpublic static class MapPersistenceExceptionTranslator implements PersistenceExceptionTranslator {\n \n \t\t// in to out\n", "metadata": {"problem_domain": "New Feature Additions", "difficulty": "low", "estimated_review_effort": 3}} diff --git a/results/graphql_prs_data/spring-projects__spring-framework_graphql_prs_data.jsonl b/results/graphql_prs_data/spring-projects__spring-framework_graphql_prs_data.jsonl new file mode 100644 index 0000000..26d7b7c --- /dev/null +++ b/results/graphql_prs_data/spring-projects__spring-framework_graphql_prs_data.jsonl @@ -0,0 +1,20 @@ +{"id": "PR_kwDOABGHUc6wyjia", "title": "Fix PathMatchingResourcePatternResolver to handle absolute paths in JAR manifests", "body": "When JAR manifest Class-Path entries contain absolute paths (as Gradle creates on Windows for long classpaths), PathMatchingResourcePatternResolver incorrectly rejected them.\r\n\r\nFixes #35730\r\n", "number": 35732, "url": "https://github.com/spring-projects/spring-framework/pull/35732", "author": {"login": "Artur-"}, "createdAt": "2025-10-31T09:34:56Z", "mergedAt": "2025-11-01T11:25:20Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "01a58a253b0631bbaa2a3e5a4a2d098fa316ba69", "baseRefName": "6.2.x", "headRefOid": "089c627c5b0610a0325fe93b4d6535d45429b516", "headRefName": "manifest-absolute-paths", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "type: bug"}, {"name": "in: core"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "089c627c5b0610a0325fe93b4d6535d45429b516", "message": "fix: Fix PathMatchingResourcePatternResolver to handle absolute paths in JAR manifests\n\nWhen JAR manifest Class-Path entries contain absolute paths (as Gradle\ncreates on Windows for long classpaths), PathMatchingResourcePatternResolver\nincorrectly rejected them.\n\nFixes #35730\n\nSigned-off-by: Artur Signell ", "changedFilesIfAvailable": 2, "authoredDate": "2025-10-31T09:19:52Z", "author": {"user": {"login": "Artur-"}}, "committedDate": "2025-10-31T12:28:44Z", "committer": {"user": {"login": "Artur-"}}, "parents": {"nodes": [{"oid": "01a58a253b0631bbaa2a3e5a4a2d098fa316ba69"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc7VA6yV", "number": 35730, "url": "https://github.com/spring-projects/spring-framework/issues/35730", "title": "PathMatchingResourcePatternResolver fails with absolute paths in JAR manifest Class-Path entries", "body": "PathMatchingResourcePatternResolver incorrectly rejects absolute paths in JAR manifest Class-Path entries, causing classpath scanning to fail with patterns like `classpath*:**/*.class`.\n\nMinimal reproduction: https://github.com/Artur-/spring-manifest-bug-demo\n\n```sh\ngit clone https://github.com/Artur-/spring-manifest-bug-demo.git\ncd spring-manifest-bug-demo\nmvn dependency:resolve\n./create-classpath-jar.sh\n./run-test.sh\n```\n\nResult:\n- classpath*:**/*.class \u2192 2 classes \u274c (missing dependencies)\n- classpath*:org/**/*.class \u2192 458 classes \u2713 (works correctly)\n\n## Root Cause\n\nFile: PathMatchingResourcePatternResolver.java:615\n\n```java\nFile candidate = new File(parent, path);\nif (candidate.isFile() && candidate.getCanonicalPath().contains(parent.getCanonicalPath())) {\n manifestEntries.add(ClassPathManifestEntry.of(candidate));\n}\n```\n\nThe security check rejects JARs that aren't within the parent directory. However, when Gradle creates a classpath JAR on Windows (to avoid the ~8KB command-line limit), it uses absolute paths to dependency JARs in the user's .gradle/caches/ directory. These are legitimate dependencies, not files that should be restricted to the parent directory.\n\nExample of valid manifest created by Gradle:\nClasspath JAR location: `C:/project/build/tmp/bootRun/classpath.jar`\nManifest Class-Path: `C:/Users/developer/.gradle/caches/modules-2/files-2.1/.../spring-core-6.2.1.jar`\n\nThe code extracts:\n```\nparent = \"C:/project/build/tmp/bootRun/\" (parent of classpath.jar)\npath = \"C:/Users/developer/.gradle/caches/.../spring-core-6.2.1.jar\" (from manifest)\n```\n\nThe check fails because the Gradle cache path doesn't contain the bootRun directory path, but these are valid dependency JARs that should be loaded.\n\n## When This Occurs\n\n - Windows with Gradle (classpath exceeds ~8KB limit)\n - IntelliJ IDEA with classpath shortening\n - Any build tool using absolute paths in manifest Class-Path\n\n\nRelated Issues\n\n- #18260, #28276, #24480\n- vaadin/flow#21051\n", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: core"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOzv_Rng=="}, "nodes": [{"id": "IC_kwDOABGHUc7O_9Ge", "author": {"login": "jhoeller"}, "body": "Superseded by PR #35732.", "createdAt": "2025-10-31T12:25:45Z", "updatedAt": "2025-10-31T12:25:45Z"}]}}]}} +{"id": "PR_kwDOABGHUc6qfC5j", "title": "Remove redundant object allocation in cglib proxy method calls", "body": "Fixes gh-35542\r\n\r\nI've noticed ~1.2TB of memory allocations of `java.lang.Boolean` in 10 minute long JMC dump.\r\nThis seemed a lot to me so I have fixed it. After the patch, the bytecode of generated cglib proxies now display a more memory saving `valueOf()` calls to box primitives (especially the Boolean)", "number": 35543, "url": "https://github.com/spring-projects/spring-framework/pull/35543", "author": {"login": "Entea"}, "createdAt": "2025-09-25T11:19:46Z", "mergedAt": "2025-10-02T19:22:19Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "ba0de1edce63630173784b2b2b2d60489f8c2d3c", "baseRefName": "main", "headRefOid": "96d8109b780a97a3c8780003d25b5a8a1f9ce90f", "headRefName": "main", "changedFiles": 1, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: core"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "96d8109b780a97a3c8780003d25b5a8a1f9ce90f", "message": "Remove redundant object allocation in cglib proxy method calls\n* Fixes gh-35542\n\nSigned-off-by: Nurlan Turdaliev ", "changedFilesIfAvailable": 1, "authoredDate": "2025-09-25T11:19:14Z", "author": {"user": {"login": "Entea"}}, "committedDate": "2025-09-25T11:47:10Z", "committer": {"user": {"login": "Entea"}}, "parents": {"nodes": [{"oid": "5df082132dbb2881d600e002d5dfe4ba8f31a9a1"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc7N0xkO", "number": 35542, "url": "https://github.com/spring-projects/spring-framework/issues/35542", "title": "Remove redundant object allocation in cglib proxy method calls", "body": "Hello!\n\nI've noticed a huge amount of memory allocations of java.lang.Boolean being made in calls to CGLIB proxies with a primitive boolean in the method signature. Tracing down the issue, I found that the method invocation code uses the new Boolean(boolean) constructor (which has been deprecated for removal since Java 9, by the way) to box the boolean, instead of the more efficient Boolean.valueOf().\n\nIt would be nice to fix this small issue.", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: core"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOxrWHBg=="}, "nodes": [{"id": "IC_kwDOABGHUc7GtYcG", "author": {"login": "sbrannen"}, "body": "Thanks for raising the issue.\n\nWe will take your PR into consideration.\n\nIn the future, please do not submit both an issue and a PR. One will suffice.\n\nIn light of that, I am closing this as:\n\n- Superseded by #35543", "createdAt": "2025-09-25T12:51:09Z", "updatedAt": "2025-09-25T12:51:09Z"}]}}]}} +{"id": "PR_kwDOABGHUc6PXzD0", "title": "Introduce Stream variant methods for SqlQuery", "body": "Closes GH-34474", "number": 34623, "url": "https://github.com/spring-projects/spring-framework/pull/34623", "author": {"login": "quaff"}, "createdAt": "2025-03-20T00:44:05Z", "mergedAt": "2025-03-21T17:38:28Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "6505c4b839b06fca22aac9d179f2b678e196dc5f", "baseRefName": "main", "headRefOid": "2745eab27a78e9262a7363bb8912aebc4d43ca27", "headRefName": "patch-104", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "2745eab27a78e9262a7363bb8912aebc4d43ca27", "message": "Introduce Stream variant methods for SqlQuery\n\nCloses GH-34474\n\nSigned-off-by: Yanming Zhou ", "changedFilesIfAvailable": 2, "authoredDate": "2025-02-24T03:43:08Z", "author": {"user": {"login": "quaff"}}, "committedDate": "2025-03-21T01:20:54Z", "committer": {"user": {"login": "quaff"}}, "parents": {"nodes": [{"oid": "cacc63da20f54d93111b86ffd7961b3ce3dcce53"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc6rSmMp", "number": 34474, "url": "https://github.com/spring-projects/spring-framework/issues/34474", "title": "Introduce Stream variant methods for SqlQuery", "body": "`queryForStream()` was introduced for `JdbcOperations` since 5.3, It would be nice if `SqlQuery` could leverage it to process large result too.\n\nI would like to prepare PR if the proposal is accepted.", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}]}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOo46IwQ=="}, "nodes": [{"id": "IC_kwDOABGHUc6jF6nX", "author": {"login": "jhoeller"}, "body": "Sounds good, let's consider that for 7.0 then.", "createdAt": "2025-03-19T11:08:26Z", "updatedAt": "2025-03-19T11:08:26Z"}, {"id": "IC_kwDOABGHUc6jjojB", "author": {"login": "jhoeller"}, "body": "Superseded by PR #34623.", "createdAt": "2025-03-21T17:36:00Z", "updatedAt": "2025-03-21T17:36:00Z"}]}}]}} +{"id": "PR_kwDOABGHUc5hdDgb", "title": "Add `MySQLIdentityColumnMaxValueIncrementer`", "body": "The PR adds `MySQLIdentityColumnMaxValueIncrementer` to resolve #18989.\r\n\r\nUsing a MySQL auto-increment column as a sequence with `AbstractIdentityColumnMaxValueIncrementer` was not practical before MySQL 8 as the auto-increment counter was only stored in memory but not persisted. With MySQL 8.0 and InnoDB, this behavior has changed: https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html#innodb-auto-increment-initialization\r\n\r\nWith MySQL 8 and InnoDB, the new incrementer can be used safely in a setup with active-active replication. If the database parameters [`auto_increment_increment`](https://dev.mysql.com/doc/refman/8.0/en/replication-options-source.html#sysvar_auto_increment_increment) and [`auto_increment_offset`](https://dev.mysql.com/doc/refman/8.0/en/replication-options-source.html#sysvar_auto_increment_offset) are configured appropriately, the incrementer will not produce duplicate ids even if different database instances are queried.\r\n\r\nI've assembled a toy setup with a multi-threaded test against two MySQL instances with active-active replication here: https://github.com/hpoettker/mysql-incrementer-demo", "number": 31784, "url": "https://github.com/spring-projects/spring-framework/pull/31784", "author": {"login": "hpoettker"}, "createdAt": "2023-12-07T18:47:52Z", "mergedAt": "2023-12-08T15:12:29Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "2e07f9ab33d882876f46912fcea08030b2593d49", "baseRefName": "main", "headRefOid": "dfadac8207bb53e9d44c9efb4ac44a1ae74279d7", "headRefName": "mysql-incrementer", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "dfadac8207bb53e9d44c9efb4ac44a1ae74279d7", "message": "Adds `MySQLIdentityColumnMaxValueIncrementer`\n\nThe new `DataFieldMaxValueIncrementer` can be used with identity columns in MySQL 8.0 or later.", "changedFilesIfAvailable": 2, "authoredDate": "2023-12-07T18:20:02Z", "author": {"user": {"login": "hpoettker"}}, "committedDate": "2023-12-07T18:20:02Z", "committer": {"user": {"login": "hpoettker"}}, "parents": {"nodes": [{"oid": "2e07f9ab33d882876f46912fcea08030b2593d49"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWUzOTgxOTQ5MTQ=", "number": 18989, "url": "https://github.com/spring-projects/spring-framework/issues/18989", "title": "MySQLMaxValueIncrementer is not multi-master replication-safe [SPR-14418]", "body": "**[Tim Gokcen](https://jira.spring.io/secure/ViewProfile.jspa?name=hexetic)** opened **[SPR-14418](https://jira.spring.io/browse/SPR-14418?redirect=false)** and commented\n\nThe Spring `org.springframework.jdbc.support.incrementer` subsystem is used by Spring Batch, among others, to generate increasing \"unique\" IDs.\n\nHowever, `org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer` is not safe to use in multi-master MySQL or MariaDB environments, e.g. master-master replication or MySQL/Galera cluster. This is because of the way in which it always kicks forward last_insert_id() by getCacheSize(), which will result in duplicate IDs across hosts and result in collisions if those IDs are used to, for example, insert rows into a table that has a unique key on the ID.\n\nThe global MySQL variable `auto_increment_increment` is available and used by clustering systems to ensure that AUTO_INCREMENT columns do not collide across the cluster (see the [Galera documentation](https://mariadb.org/auto-increments-in-galera/)). The same value could also be used by MySQLMaxValueIncrementer to avoid collisions.\n\nIn multi-master environments, the cacheSize would also have to always be equal to 1; there is no way to pre-allocate IDs without guaranteeing that they were not already selected by another host.\n\nAlternatively, the whole idea of using the backing RDBMS to generate increasing IDs could be abandoned in favour of generating non-linearly increasing \"probably-unique\" IDs, as for example in in [Twitter Snowflake](https://github.com/twitter/snowflake/tree/snowflake-2010), which uses a combination of \"timestamp + host-ID + thread-ID + counter\" to produce a very-likely-to-be-unique 64-bit integer.\n\n\n---\n\n**Affects:** 4.2.6\n", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHObgrLnw=="}, "nodes": [{"id": "MDEyOklzc3VlQ29tbWVudDQ1MzQ0MTcxNQ==", "author": {"login": "spring-projects-issues"}, "body": "**[krishna81m@gmail.com](https://jira.spring.io/secure/ViewProfile.jspa?name=krishna81m)** commented\n\nSpring Batch does not seem to provide support to inject/override custom implementations as they not annotated beans that you can override using `@Primary` at runtime. However, src/main/resources/data-source-context.xml already has externalized this class based on src/main/resources/batch-mysql.properties based on the ENVIRONMENT\n\n```java\n\n\n \n\nbatch-mysql.properties\n..\nbatch.jdbc.password=test\nbatch.database.incrementer.class=org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer\n..\n```\n\nWe probably have to implement a custom class and override this properties file in classpath if I am not wrong. Worst case, we were able to fork and inject our own Incrementer to resolve this problem in our Galera cluster across DCs besides thinking about stopping replication completely.\n\n", "createdAt": "2018-04-03T01:35:29Z", "updatedAt": "2019-01-11T09:08:22Z"}, {"id": "IC_kwDOABGHUc5uCsuf", "author": {"login": "jhoeller"}, "body": "Superseded by PR #31784.", "createdAt": "2023-12-07T22:23:13Z", "updatedAt": "2023-12-07T22:23:13Z"}]}}]}} +{"id": "PR_kwDOABGHUc5ggDmA", "title": "Correct conversion from Resource[] with length 1 to Collection", "body": "Fix GH-31693", "number": 31699, "url": "https://github.com/spring-projects/spring-framework/pull/31699", "author": {"login": "quaff"}, "createdAt": "2023-11-28T01:40:01Z", "mergedAt": "2023-11-30T13:05:13Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "4e2d3573189b7c0afce62bce29cd915de4077f56", "baseRefName": "main", "headRefOid": "acecf3753ff9f0b8856c56b4605ddc4d1a975177", "headRefName": "patch-37", "changedFiles": 3, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "type: regression"}, {"name": "in: core"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "acecf3753ff9f0b8856c56b4605ddc4d1a975177", "message": "Correct conversion from Resource[] with length 1 to Collection\n\nFix GH-31693", "changedFilesIfAvailable": 3, "authoredDate": "2023-11-27T09:03:00Z", "author": {"user": {"login": "quaff"}}, "committedDate": "2023-11-28T01:35:21Z", "committer": {"user": {"login": "quaff"}}, "parents": {"nodes": [{"oid": "4e2d3573189b7c0afce62bce29cd915de4077f56"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc536E_Q", "number": 31693, "url": "https://github.com/spring-projects/spring-framework/issues/31693", "title": "Resource collection injection by @Value regression", "body": "```java\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\n\r\nimport java.util.List;\r\n\r\nimport org.junit.jupiter.api.Test;\r\nimport org.springframework.beans.factory.annotation.Value;\r\nimport org.springframework.core.io.Resource;\r\nimport org.springframework.test.context.junit.jupiter.SpringJUnitConfig;\r\n\r\n@SpringJUnitConfig\r\npublic class ResourcesInjectionByFieldTests {\r\n\r\n\t@Value(\"classpath:application.yaml\")\r\n\tprivate Resource[] resourcesArray;\r\n\r\n\t@Value(\"classpath:application.yaml\")\r\n // @Value(\"classpath*:application.yaml\") will works with 6.1\r\n\tprivate List resourcesList;\r\n\r\n\t@Test\r\n\tvoid test() {\r\n\t\tassertThat(resourcesArray).isNotEmpty();\r\n\t\tassertThat(resourcesList).isNotEmpty();\r\n\t}\r\n\r\n}\r\n\r\n```\r\nThis test case failed after upgrading spring framework from 6.0 to 6.1, I believe it introduced by https://github.com/spring-projects/spring-framework/commit/84b3335e711bee38efdf6518e72d0ec441704fce which fixed https://github.com/spring-projects/spring-framework/issues/24845. It's possible that this will fix a [spring boot regression](https://github.com/spring-projects/spring-boot/issues/38556).\r\n```\r\n15:51:49.983 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.example.demo.ResourcesInjectionByFieldTests]: ResourcesInjectionByFieldTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.\r\n15:51:50.141 [main] ERROR org.springframework.test.context.TestContextManager -- Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener] to prepare test instance [com.example.demo.ResourcesInjectionByFieldTests@737a135b]\r\norg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.demo.ResourcesInjectionByFieldTests': Unsatisfied dependency expressed through field 'resourcesList': Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; Cannot convert value of type 'java.lang.String' to required type 'java.util.List': PropertyEditor [org.springframework.core.io.support.ResourceArrayPropertyEditor] returned inappropriate value of type 'org.springframework.core.io.ClassPathResource'\r\n\tat org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:772)\r\n\tat org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:752)\r\n\tat org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145)\r\n\tat org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:493)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:397)\r\n\tat org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142)\r\n\tat org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97)\r\n\tat org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)\r\n\tat org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)\r\n...\r\nCaused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; Cannot convert value of type 'java.lang.String' to required type 'java.util.List': PropertyEditor [org.springframework.core.io.support.ResourceArrayPropertyEditor] returned inappropriate value of type 'org.springframework.core.io.ClassPathResource'\r\n\tat org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:87)\r\n\tat org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:71)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1379)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1348)\r\n\tat org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:769)\r\n\t... 76 common frames omitted\r\nCaused by: java.lang.IllegalArgumentException: Cannot convert value of type 'java.lang.String' to required type 'java.util.List': PropertyEditor [org.springframework.core.io.support.ResourceArrayPropertyEditor] returned inappropriate value of type 'org.springframework.core.io.ClassPathResource'\r\n\tat org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:268)\r\n\tat org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80)\r\n\t... 80 common frames omitted\r\n```\r\n", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "type: regression"}, {"name": "in: core"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHObUzIkQ=="}, "nodes": [{"id": "IC_kwDOABGHUc5tTMiR", "author": {"login": "jhoeller"}, "body": "Superseded by PR #31699.", "createdAt": "2023-11-30T13:03:33Z", "updatedAt": "2023-11-30T13:03:33Z"}]}}]}} +{"id": "PR_kwDOABGHUc5fvsZy", "title": "Extract recurring asciidoc links to attributes", "body": "This commit extracts Spring-related links and recurring external links into asciidoctor attributes to be used by the Antora toolchain.\r\n\r\nIt notably homogenizes links to:\r\n - IETF RFCs\r\n - Java Community Process JSRs\r\n - Java API Documentation (Java 17 version)\r\n - Kotlin documentation (Kotlinlang.org version)\r\n - the Spring Boot reference guide (`html` version)\r\n\r\nThis commit also reworks most link attributes to follow a Project-Category-Misc syntax. For example, `spring-boot-docs` rather than `docs-spring-boot`.\r\n\r\nCloses gh-26864", "number": 31619, "url": "https://github.com/spring-projects/spring-framework/pull/31619", "author": {"login": "simonbasle"}, "createdAt": "2023-11-17T12:29:55Z", "mergedAt": "2023-11-21T14:59:24Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "bec385d310865331db34b1ef8f93f0b0c29eac2e", "baseRefName": "main", "headRefOid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3", "headRefName": "asciidocAttributes", "changedFiles": 202, "labels": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"name": "type: documentation"}]}, "commits": {"totalCount": 8, "pageInfo": {"hasNextPage": false, "endCursor": "OA"}, "nodes": [{"commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794", "message": "Extract recurring asciidoc links to attributes\n\nThis commit extract spring-related links and recurring\nexternal links into asciidoctor attributes to be used\nby the Antora toolchain.\n\nIt notably homogenizes links to:\n - IETF RFCs\n - Java Community Process JSRs\n - the Java API Documentation (on the Java 17 version)\n - Kotlin documentations (on the Kotlinlang.org version)\n - the Spring Boot reference guide (on the `html` version)\n\nThis commit also reworks most link attributes to follow\na Project-Category-Misc syntax. For example, spring-boot-docs rather than docs-spring-boot.\n\nCloses gh-26864", "changedFilesIfAvailable": 183, "authoredDate": "2023-11-16T11:03:09Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-17T12:19:34Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "dd97dee7fda7c0a29a5c943961816a77124a0676"}]}}}, {"commit": {"oid": "366681fc95787637ac509e23e40b4070e4b7767c", "message": "revert attribute of JIRA link, this section should have been removed on main", "changedFilesIfAvailable": 1, "authoredDate": "2023-11-21T10:28:45Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T10:28:45Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}]}}}, {"commit": {"oid": "e481fb2149ffdc1b472cd56fae9cd383e4baf459", "message": "review: fold attribute, inline spring-repo, remove issues-old", "changedFilesIfAvailable": 1, "authoredDate": "2023-11-21T10:29:51Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T10:29:51Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "366681fc95787637ac509e23e40b4070e4b7767c"}]}}}, {"commit": {"oid": "c771d63a24dd7d420c208af409545b7ec2398bc9", "message": "review: (actually) remove issues-old attribute", "changedFilesIfAvailable": 1, "authoredDate": "2023-11-21T10:36:11Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T10:36:11Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "e481fb2149ffdc1b472cd56fae9cd383e4baf459"}]}}}, {"commit": {"oid": "21c016fe3ecbd8c07903d74397f3d4432148157e", "message": "Remove now irrelevant src/docs/asciidoc folder", "changedFilesIfAvailable": 19, "authoredDate": "2023-11-21T10:38:00Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T10:38:00Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "c771d63a24dd7d420c208af409545b7ec2398bc9"}]}}}, {"commit": {"oid": "fe605cf708ea42d9be5525888404fcddadac892c", "message": "fixup: convert the correct JIRA issue to a gh link, keep the other one", "changedFilesIfAvailable": 1, "authoredDate": "2023-11-21T10:56:16Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T10:56:16Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "21c016fe3ecbd8c07903d74397f3d4432148157e"}]}}}, {"commit": {"oid": "c7ce9fdc3f7c3147388e2ae3472fef965ddeba2a", "message": "Merge branch 'main' into asciidocAttributes", "changedFilesIfAvailable": 93, "authoredDate": "2023-11-21T11:10:30Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T11:10:30Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "fe605cf708ea42d9be5525888404fcddadac892c"}, {"oid": "bec385d310865331db34b1ef8f93f0b0c29eac2e"}]}}}, {"commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3", "message": "remove redundant attributes.adoc", "changedFilesIfAvailable": 1, "authoredDate": "2023-11-21T14:49:53Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-11-21T14:49:53Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "c7ce9fdc3f7c3147388e2ae3472fef965ddeba2a"}]}}}]}, "reviews": {"totalCount": 8, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0xMS0yMVQxODo1MTowMSswODowMLkyMDIzLTExLTIxVDE4OjUxOjAxKzA4OjAwzmfQAyY="}, "nodes": [{"id": "PRR_kwDOABGHUc5niSvO", "author": {"login": "bclozel"}, "state": "APPROVED", "body": "Thanks for putting this together, this is solving quite a few consistency issues and will make the docs much easier to maintain!", "submittedAt": "2023-11-17T13:50:28Z", "updatedAt": "2023-11-17T13:50:28Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5nnzbz", "author": {"login": "snicoll"}, "state": "APPROVED", "body": "\ud83d\udc4d ", "submittedAt": "2023-11-18T21:31:21Z", "updatedAt": "2023-11-18T21:31:21Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5nzAj1", "author": {"login": "sbrannen"}, "state": "CHANGES_REQUESTED", "body": "This is much needed.\r\n\r\nThanks so much for taking this on! \ud83d\udc4f \r\n\r\nI've left a few questions.", "submittedAt": "2023-11-21T09:04:19Z", "updatedAt": "2023-11-21T09:04:19Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTowMzoyNlrOU3Xt1w=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5Tdbsg", "author": {"login": "sbrannen"}, "body": "Since this is specific to Framework (as opposed to the Spring portfolio in general) and is only used once, I suggest we remove it and inline it in `spring-framework-github`.", "createdAt": "2023-11-21T08:53:49Z", "updatedAt": "2023-11-21T09:04:19Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"", "line": null, "startLine": null, "originalLine": 28, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}, {"id": "PRRC_kwDOABGHUc5TddiE", "author": {"login": "sbrannen"}, "body": "A quick search reveals that we're only using that base URL for a single `SPR-` issue.\r\n\r\nSince all `SPR-` issues have been migrated to GitHub, I suggest we remove the `issues-old` attribute.\r\n\r\nIn fact, I'll replace that JIRA link with a GitHub link on `main`.", "createdAt": "2023-11-21T08:59:23Z", "updatedAt": "2023-11-21T09:04:19Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'", "line": null, "startLine": null, "originalLine": 33, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}, {"id": "PRRC_kwDOABGHUc5TdeaB", "author": {"login": "sbrannen"}, "body": "This appears to be overridden in `attributes.adoc`.\r\n\r\nDo we need both?", "createdAt": "2023-11-21T09:02:02Z", "updatedAt": "2023-11-21T09:04:19Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'", "line": 19, "startLine": null, "originalLine": 19, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}, {"id": "PRRC_kwDOABGHUc5Tde3X", "author": {"login": "sbrannen"}, "body": "Do we still need this file?\r\n\r\nIn other words, can we move `chomp` and `fold` to `antora.yml` and remove this one?", "createdAt": "2023-11-21T09:03:26Z", "updatedAt": "2023-11-21T09:04:19Z", "path": "framework-docs/modules/ROOT/pages/attributes.adoc", "diffHunk": "@@ -1,20 +1,20 @@\n // Spring Portfolio\n-:docs-site: https://docs.spring.io\n-:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference\n-:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference\n-:docs-spring-security: {docs-site}/spring-security/reference\n+// :docs-site: https://docs.spring.io", "line": null, "startLine": null, "originalLine": 2, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}]}}, {"id": "PRR_kwDOABGHUc5nzML9", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-11-21T09:16:48Z", "updatedAt": "2023-11-21T09:16:48Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOToxNjo0OFrOU3Yyog=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TdjKi", "author": {"login": "simonbasle"}, "body": "@sbrannen let's perhaps do the replace in this PR? (this would avoid a merge conflict)", "createdAt": "2023-11-21T09:16:48Z", "updatedAt": "2023-11-21T09:16:48Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'", "line": null, "startLine": null, "originalLine": 33, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc5TddiE"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}]}}, {"id": "PRR_kwDOABGHUc5nzZiG", "author": {"login": "sbrannen"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-11-21T09:41:27Z", "updatedAt": "2023-11-21T09:41:27Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTo0MToyNlrOU3a4mw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5Tdrib", "author": {"login": "sbrannen"}, "body": "It turns out the sections related to that SPR issue were obsolete, so I removed them in 617ba845771f8cf6d8f7e30ba8ff66214e97bc54.\r\n\r\nApologies if that causes troubling merge conflicts.", "createdAt": "2023-11-21T09:41:26Z", "updatedAt": "2023-11-21T09:53:14Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'\n include-java: 'example$docs-src/main/java/org/springframework/docs'\n- spring-framework-main-code: 'https://github.com/spring-projects/spring-framework/tree/main'\n+ spring-site: 'https://spring.io'\n+ spring-site-blog: '{spring-site}/blog'\n+ spring-site-cve: \"{spring-site}/security\"\n+ spring-site-guides: '{spring-site}/guides'\n+ spring-site-projects: '{spring-site}/projects'\n+ spring-site-tools: \"{spring-site}/tools\"\n+ spring-org: 'spring-projects'\n+ spring-repo: \"{spring-org}/spring-framework\"\n+ spring-github-org: \"https://github.com/{spring-org}\"\n+ spring-framework-github: \"https://github.com/{spring-repo}\"\n+ spring-framework-code: '{spring-framework-github}/tree/main'\n+ spring-framework-issues: '{spring-framework-github}/issues'\n+ issues-old: 'https://jira.spring.io/browse'", "line": null, "startLine": null, "originalLine": 33, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc5TddiE"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}]}}, {"id": "PRR_kwDOABGHUc5nze6s", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-11-21T09:50:37Z", "updatedAt": "2023-11-21T09:50:37Z", "commit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTo1MDozN1rOU3bugg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5Tdu6C", "author": {"login": "simonbasle"}, "body": "I don't think so, not even sure `attributes.adoc` is used anymore in the antora toolchain \ud83e\udd14\r\nactually, let me double check that the whole `src/docs/asciidoc` folder is even relevant at all now...", "createdAt": "2023-11-21T09:50:37Z", "updatedAt": "2023-11-21T09:50:37Z", "path": "framework-docs/antora.yml", "diffHunk": "@@ -18,15 +18,73 @@ asciidoc:\n # FIXME: The package is not renamed\n chomp: 'all'", "line": 19, "startLine": null, "originalLine": 19, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc5TdeaB"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "1f9b099dfb4e4e57248d07de28ebc2f9878b9794"}}]}}, {"id": "PRR_kwDOABGHUc5nz7FD", "author": {"login": "sbrannen"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-11-21T10:40:08Z", "updatedAt": "2023-11-21T10:40:08Z", "commit": {"oid": "366681fc95787637ac509e23e40b4070e4b7767c"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQxMDo0MDowN1rOU3gLKg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TeAsq", "author": {"login": "sbrannen"}, "body": "This remaining link somehow didn't show up in my local searches.\r\n\r\nIt can be replaced with the [GitHub issue](https://github.com/spring-projects/spring-framework/issues/14870).\r\n\r\n```asciidoc\r\n{spring-framework-issues}/14870[gh-14870]\r\n```", "createdAt": "2023-11-21T10:40:07Z", "updatedAt": "2023-11-21T10:40:08Z", "path": "framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc", "diffHunk": "@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see {issues-old}/SPR-10237[SPR-10237]\n+unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]", "line": null, "startLine": null, "originalLine": 70, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "366681fc95787637ac509e23e40b4070e4b7767c"}}]}}, {"id": "PRR_kwDOABGHUc5n0AMm", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-11-21T10:51:01Z", "updatedAt": "2023-11-21T10:51:01Z", "commit": {"oid": "366681fc95787637ac509e23e40b4070e4b7767c"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQxMDo1MTowMVrOU3hGZA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TeEZk", "author": {"login": "simonbasle"}, "body": "that's my bad, I somehow reintroduced the wrong link / missed the fact that there were 2 jira links in the doc \ud83d\ude2e\u200d\ud83d\udca8 will fix right away", "createdAt": "2023-11-21T10:51:01Z", "updatedAt": "2023-11-21T10:51:01Z", "path": "framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc", "diffHunk": "@@ -67,7 +67,7 @@ To provide a different default key generator, you need to implement the\n The default key generation strategy changed with the release of Spring 4.0. Earlier\n versions of Spring used a key generation strategy that, for multiple key parameters,\n considered only the `hashCode()` of parameters and not `equals()`. This could cause\n-unexpected key collisions (see {issues-old}/SPR-10237[SPR-10237]\n+unexpected key collisions (see https://jira.spring.io/browse/SPR-10237[SPR-10237]", "line": null, "startLine": null, "originalLine": 70, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc5TeAsq"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "a4425b2a6cb0c6c149072c94c64b5cb38adb6fd3"}, "originalCommit": {"oid": "366681fc95787637ac509e23e40b4070e4b7767c"}}]}}]}, "reviewThreads": {"totalCount": 5, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQxMDo0MDowN1rONVCbnw=="}, "nodes": [{"id": "PRRT_kwDOABGHUc41TyTd", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "framework-docs/antora.yml", "startLine": null, "originalLine": 28, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "sbrannen"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwODo1Mzo0OVrOU3W7IA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5Tdbsg"}]}}, {"id": "PRRT_kwDOABGHUc41TzgU", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "framework-docs/antora.yml", "startLine": null, "originalLine": 33, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "sbrannen"}, "comments": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTo0MToyNlrOU3a4mw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TddiE"}, {"id": "PRRC_kwDOABGHUc5TdjKi"}, {"id": "PRRC_kwDOABGHUc5Tdrib"}]}}, {"id": "PRRT_kwDOABGHUc41T0Ec", "isResolved": true, "isOutdated": false, "isCollapsed": true, "path": "framework-docs/antora.yml", "startLine": 19, "originalLine": 19, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTo1MDozN1rOU3bugg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TdeaB"}, {"id": "PRRC_kwDOABGHUc5Tdu6C"}]}}, {"id": "PRRT_kwDOABGHUc41T0Yc", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "framework-docs/modules/ROOT/pages/attributes.adoc", "startLine": null, "originalLine": 2, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQwOTowMzoyNlrOU3Xt1w=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5Tde3X"}]}}, {"id": "PRRT_kwDOABGHUc41UJuf", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "framework-docs/modules/ROOT/pages/integration/cache/annotations.adoc", "startLine": null, "originalLine": 70, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0xMS0yMVQxMDo1MTowMVrOU3hGZA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5TeAsq"}, {"id": "PRRC_kwDOABGHUc5TeEZk"}]}}]}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU4Njg0NjgyNjQ=", "number": 26864, "url": "https://github.com/spring-projects/spring-framework/issues/26864", "title": "Use asciidoc attributes in reference documentation", "body": "There are a number of places where links could use an attribute to rationalize what we use and make sure they are consistent.", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "type: documentation"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHObEs1FA=="}, "nodes": [{"id": "IC_kwDOABGHUc5sSzUU", "author": {"login": "jhoeller"}, "body": "Superseded by PR #31619.", "createdAt": "2023-11-17T18:04:42Z", "updatedAt": "2023-11-17T18:04:42Z"}]}}]}} +{"id": "PR_kwDOABGHUc5RMp4Z", "title": "Always fall back to original method if annotation pointcut used", "body": "Prior to this commit, `AspectJExpressionPointcut` didn't fall back to the original method if `!@annotation()` is used, which can result in a false positive.\r\n\r\n- fixes #27119", "number": 30534, "url": "https://github.com/spring-projects/spring-framework/pull/30534", "author": {"login": "quaff"}, "createdAt": "2023-05-24T01:44:04Z", "mergedAt": "2023-11-23T15:01:19Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "ca4d0d784b5dafdcba3a8aa74921193255ed8e3b", "baseRefName": "main", "headRefOid": "ef73ba93c87a83e481a5c9918440c5d162c4cfa9", "headRefName": "patch-22", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "type: bug"}, {"name": "in: core"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "ef73ba93c87a83e481a5c9918440c5d162c4cfa9", "message": "Always fall back to original method if annotation pointcut used\n\nPrior to this commit, AspectJExpressionPointcut doesn't fall back to original method if `!@annotation()` is used, it can cause false positive result.\n\nFix GH-27119", "changedFilesIfAvailable": 2, "authoredDate": "2023-05-24T04:23:32Z", "author": {"user": {"login": "quaff"}}, "committedDate": "2023-05-25T01:34:03Z", "committer": {"user": {"login": "quaff"}}, "parents": {"nodes": [{"oid": "1d6246d700db3d0ae78280f54f7595265845e174"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU5MzUzNzA5NjA=", "number": 27119, "url": "https://github.com/spring-projects/spring-framework/issues/27119", "title": "Not annotation pointcut matches dynamic proxy methods incorrectly", "body": "\"target\" and \"not @annotation\" combination not works as expected, but \"target\" and \"@annotation\" combination works fine.\r\n```java\r\n\t// works as expected\r\n\t@Around(\"execution(public * *(..)) and target(repository) and @annotation(org.springframework.transaction.annotation.Transactional)\")\r\n\tpublic Object interceptPositive(ProceedingJoinPoint pjp, Repository repository) throws Throwable {\r\n\t\tMethod method = ((MethodSignature) pjp.getSignature()).getMethod();\r\n\t\tif (!method.isAnnotationPresent(Transactional.class))\r\n\t\t\tthrow new RuntimeException(\"annotation should present here\");\r\n\t\treturn pjp.proceed();\r\n\t}\r\n\r\n\t// not works as expected\r\n\t@Around(\"execution(public * *(..)) and target(repository) and not @annotation(org.springframework.transaction.annotation.Transactional)\")\r\n\tpublic Object interceptNegative(ProceedingJoinPoint pjp, Repository repository) throws Throwable {\r\n\t\tMethod method = ((MethodSignature) pjp.getSignature()).getMethod();\r\n\t\tif (method.isAnnotationPresent(Transactional.class))\r\n\t\t\tthrow new RuntimeException(\"annotation should not present here\");\r\n\t\treturn pjp.proceed();\r\n\t}\r\n```\r\n[test-pointcut.zip](https://github.com/spring-projects/spring-framework/files/6751811/test-pointcut.zip) is a test project\r\n", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "type: bug"}, {"name": "in: core"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 7, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHObMBPAA=="}, "nodes": [{"id": "MDEyOklzc3VlQ29tbWVudDg3NDc1OTI5MA==", "author": {"login": "sbrannen"}, "body": "@quaff, have you tried the following?\r\n\r\n```java\r\n@Around(\"execution(public * *(..)) and target(repository) and !@annotation(org.springframework.transaction.annotation.Transactional)\")\r\n```", "createdAt": "2021-07-06T13:27:06Z", "updatedAt": "2021-07-06T13:27:06Z"}, {"id": "MDEyOklzc3VlQ29tbWVudDg3NTE5MDM2Mg==", "author": {"login": "quaff"}, "body": "> @quaff, have you tried the following?\r\n> \r\n> ```java\r\n> @Around(\"execution(public * *(..)) and target(repository) and !@annotation(org.springframework.transaction.annotation.Transactional)\")\r\n> ```\r\n\r\nYes, same result.", "createdAt": "2021-07-07T01:07:33Z", "updatedAt": "2021-07-07T01:07:33Z"}, {"id": "IC_kwDOABGHUc5W-9cW", "author": {"login": "quaff"}, "body": "Still not fixed in v6.0.6.", "createdAt": "2023-03-08T03:41:19Z", "updatedAt": "2023-03-08T03:41:19Z"}, {"id": "IC_kwDOABGHUc5XBdYZ", "author": {"login": "sbrannen"}, "body": "> Still not fixed in v6.0.6.\r\n\r\nIndeed.\r\n\r\nI've just assigned to this to the 6.1.x backlog, so that somebody from the team can pick it up.", "createdAt": "2023-03-08T11:10:10Z", "updatedAt": "2023-03-08T11:10:10Z"}, {"id": "IC_kwDOABGHUc5cNPuQ", "author": {"login": "nakulmitra"}, "body": "@sbrannen what if I used && in place of and, will it work?\r\n```java\r\n@Around(\"execution(public * *(..)) && target(repository) && !@annotation(org.springframework.transaction.annotation.Transactional)\")\r\n``` ", "createdAt": "2023-05-14T18:58:39Z", "updatedAt": "2023-05-14T19:00:21Z"}, {"id": "IC_kwDOABGHUc5cNld6", "author": {"login": "quaff"}, "body": "> @sbrannen what if I used && in place of and, will it work?\r\n> \r\n> ```java\r\n> @Around(\"execution(public * *(..)) && target(repository) && !@annotation(org.springframework.transaction.annotation.Transactional)\")\r\n> ```\r\n\r\nI don't think it will works, `&&` is simply substitution of `and`.", "createdAt": "2023-05-15T01:21:59Z", "updatedAt": "2023-05-15T01:21:59Z"}, {"id": "IC_kwDOABGHUc5swE8A", "author": {"login": "jhoeller"}, "body": "Superseded by PR #30534.", "createdAt": "2023-11-23T14:37:46Z", "updatedAt": "2023-11-23T14:37:46Z"}]}}]}} +{"id": "PR_kwDOABGHUc5NQnZk", "title": "Rename MockMVC matcher methods to prevent regression in user tests", "body": "This commit changes the name of two recently introduced methods in the\r\n`MockRestRequestMatchers` class for header and queryParam. These have\r\nbeen found to cause false negatives in user tests, due to the new\r\noverload taking precedence in some cases.\r\n\r\nNamely, using a `Matcher` factory method which can apply to both `List`\r\nand `String` will cause the compiler to select the newest list overload,\r\nby instantiating a `Matcher`.\r\n\r\nThis can cause false negatives in user tests, failing tests that used\r\nto pass because the Matcher previously applied to the first String in\r\nthe header or queryParam value list. For instance, `equalsTo(\"a\")`.\r\n\r\nThe new overloads are recent enough and this has enough potential to\r\ncause an arbitrary number of user tests to fail that we break the API\r\nto eliminate the ambiguity, by renaming the methods with a `*List`\r\nsuffix.\r\n\r\nCloses gh-30220\r\nCloses gh-30238\r\nSee gh-29953\r\nSee gh-28660\r\n", "number": 30238, "url": "https://github.com/spring-projects/spring-framework/pull/30238", "author": {"login": "simonbasle"}, "createdAt": "2023-03-30T13:00:02Z", "mergedAt": "2023-04-04T13:06:15Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "3a36d51473a8f3212601c6550c6ffaa3d7840bb2", "baseRefName": "main", "headRefOid": "596f3559e09a656f75df464bec4166bd91ba84df", "headRefName": "gh30220-headerQueryParamList", "changedFiles": 2, "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: test"}, {"name": "status: backported"}, {"name": "in: web"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "a44bc02ba83a5e71c4b08d20fb00398b36c06620", "message": "Rename MockMVC matcher methods to prevent regression in user tests\n\nThis commit changes the name of two recently introduced methods in the\n`MockRestRequestMatchers` class for header and queryParam. These have\nbeen found to cause false negatives in user tests, due to the new\noverload taking precedence in some cases.\n\nNamely, using a `Matcher` factory method which can apply to both `List`\nand `String` will cause the compiler to select the newest list overload,\nby instantiating a `Matcher`.\n\nThis can cause false negatives in user tests, failing tests that used\nto pass because the Matcher previously applied to the first String in\nthe header or queryParam value list. For instance, `equalsTo(\"a\")`.\n\nThe new overloads are recent enough and this has enough potential to\ncause an arbitrary number of user tests to fail that we break the API\nto eliminate the ambiguity, by renaming the methods with a `*List`\nsuffix.\n\nCloses gh-30220\nClose gh-30238\nSee gh-29953\nSee gh-28660", "changedFilesIfAvailable": 2, "authoredDate": "2023-03-30T12:49:03Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-03-30T13:01:22Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "b3748243199fe809f177bb7922c69f7eb37ab6d2"}]}}}, {"commit": {"oid": "596f3559e09a656f75df464bec4166bd91ba84df", "message": "fix imports", "changedFilesIfAvailable": 1, "authoredDate": "2023-04-04T09:34:42Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-04-04T09:34:42Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "a44bc02ba83a5e71c4b08d20fb00398b36c06620"}]}}}]}, "reviews": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wNC0wNFQxNzo1Njo0MiswODowMLkyMDIzLTA0LTA0VDE3OjU2OjQyKzA4OjAwzlGx_6M="}, "nodes": [{"id": "PRR_kwDOABGHUc5Rsf-j", "author": {"login": "sbrannen"}, "state": "APPROVED", "body": "", "submittedAt": "2023-04-04T09:56:42Z", "updatedAt": "2023-04-04T09:56:42Z", "commit": {"oid": "596f3559e09a656f75df464bec4166bd91ba84df"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5h_cQI", "number": 30220, "url": "https://github.com/spring-projects/spring-framework/issues/30220", "title": "Wrong MockRestRequestMatchers.header() method in spring-test being invoked (JDK issue?)", "body": "**Affects:** 2.7.10\r\n\r\n---\r\n\r\nHello everyone.\r\n\r\nI'm uncertain if this is an issue with spring-test or with Java compiler itself but, from Spring Boot 2.7.10 (which incorporates spring-test 5.3.26), we have been having an odd issue with tests calling the wrong `MockRestRequestMatchers.header()` method.\r\n\r\nIn spring-test 5.3.25 there were a couple of `header()` methods, but the one that interest us is the one with this signature:\r\n\r\n```public static RequestMatcher header(String name, Matcher... matchers)```\r\n\r\nthis was used in testing like this:\r\n\r\n```.andExpect(header(\"X-MY-HEADER\", equalTo(\"myValue\")))```\r\n\r\nwhere `equalTo()` is defined in Hamcrest as\r\n\r\n```public static Matcher equalTo(T operand)```\r\n\r\nthis worked normally.\r\n\r\nFrom Spring Boot 2.7.10 (spring-test 5.3.26) a new `header()` method has been added with this signature:\r\n\r\n```public static RequestMatcher header(String name, Matcher> matcher)```\r\n\r\nand this is where things are breaking: the same call above is now entering this new method, as opposed to the previous. I find this surprising because the signature doesn't match, `equalTo(\"myValue\")` returns `Matcher`, which doesn't align to `Matcher>`, and yet it's coming in. If I change the call to `header()` to explicitly call out the type like this:\r\n\r\n```.andExpect(header(\"X-MY-HEADER\", CoreMatchers.equalTo(\"myValue\")))```\r\n\r\nthen things go back to normal and the call is again directed to the old `header()` method.\r\n\r\nI'm guessing that, via type erasure, the signatures of the two `header()` methods are being simplified to just `header(String, Matcher)` and, there being two possible candidates that can match the call, Java is just picking the first one. I'm not sure what could be done from spring-framework's perspective, though.\r\n\r\nThoughts?", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "status: backported"}, {"name": "type: regression"}]}, "comments": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOWNTKGg=="}, "nodes": [{"id": "IC_kwDOABGHUc5Yz-t9", "author": {"login": "simonbasle"}, "body": "That's a bit unfortunate indeed \ud83d\ude1e \r\nWhen these \"base\" `Matchers` that can conceptually apply to either `String` or `List` will cause the compiler to select the `header(String, Matcher)` signature. I unfortunately didn't realize that `equalTo(T)` would fall in this category.\r\n\r\nTo be precise, this is because the signature is really:\r\n```\r\npublic static RequestMatcher header(String name, Matcher> matcher)\r\n```\r\nSo, to the compiler, `CoreMatchers.equalTo(\"myValue\")` fits that signature as a `Matcher` \ud83d\ude2e\u200d\ud83d\udca8 \r\n\r\n\r\n### Why was the new variant introduced?\r\nSee initial context in #28660.\r\n\r\nNote that the vararg based signature, which takes `Matcher`, has a blind spot: if you provide N matchers, it only validates that the first N values in the header values list do match. This means that in your example the call would match even if the header values was in reality `[ \"myValue\", \"otherValue\" ]`... The intent of introducing a variant which accepts a List-wide `Matcher` was to alleviate this limitation and enable usage of collection matchers like:\r\n - `contains`\r\n - `hasItems`\r\n - `everyItem`\r\n - `hasSize`\r\n - `empty`\r\n\r\nThe signature has to use `? super List` because the Hamcrest collection matchers are inconsistent in the generic wildcards they use \ud83d\ude1e \r\n\r\n### A better workaround\r\nYour workaround of calling `CoreMatchers.equalTo(\"myValue\")` does unambiguously select the aforementioned string-based signature, but a better workaround would be to use:\r\n\r\n```java\r\n.andExpect(header(\"X-MY-HEADER\", \r\n Machers.contains(\"myValue\")\r\n //equivalent to Matchers.contains(CoreMatchers.equalTo(\"myValue\"))\r\n));\r\n```\r\n\r\nThis is unambiguously a `Matcher>` AND it will validate that there are no more than one header value on top of checking for equality.\r\n\r\n### Can this be fixed in Framework?\r\n\r\nI have toyed with modifying the list-based overload implementation to try to detect such \"unexpected\" matchers and apply the passed `Matcher` directly to the first element of the `List` in addition to the whole `List` itself, but I think that is a slippery slope of trying to be too smart.\r\n\r\nThis would result in the following puzzling statements all passing in tests:\r\n```java\r\n\t\trequest.getHeaders().put(\"twoElements\", List.of(\"a\", \"b\"));\r\n\r\n\t\tMockRestRequestMatchers.header(\"twoElements\", Matchers.equalTo(\"a\")).match(this.request);\r\n\t\tMockRestRequestMatchers.header(\"twoElements\", Matchers.equalTo(List.of(\"a\", \"b\"))).match(this.request);\r\n\r\n\t\tMockRestRequestMatchers.header(\"twoElements\", Matchers.hasToString(\"[a, b]\")).match(this.request);\r\n\t\tMockRestRequestMatchers.header(\"twoElements\", Matchers.hasToString(\"a\")).match(this.request);\r\n```\r\n\r\nThis could also short-circuit null checks (although this example is a bit contrived, nonetheless `null` _is_ an acceptable value for a `HttpHeaders`...):\r\n\r\n```java\r\n\t\trequest.getHeaders().add(\"m\", null);\r\n\t\trequest.getHeaders().add(\"m\", \"b\");\r\n\r\n\t\tMockRestRequestMatchers.header(\"m\", Matchers.notNullValue()).match(this.request);\r\n\t\tMockRestRequestMatchers.header(\"m\", Matchers.nullValue()).match(this.request);\r\n```\r\n(it passes because the `List` is not null, even though the first element of the list is `null`) \r\n", "createdAt": "2023-03-30T09:54:48Z", "updatedAt": "2023-03-30T09:54:48Z"}, {"id": "IC_kwDOABGHUc5Y0m-k", "author": {"login": "simonbasle"}, "body": "This can be considered a form of regression and the feature is recent enough that we might consider hot-fixing the API, renaming the list-based variant to something unambiguously different like `headerList`. Note that a similar change is necessary for `queryParam` which had the same new API.", "createdAt": "2023-03-30T12:04:15Z", "updatedAt": "2023-03-30T12:04:15Z"}, {"id": "IC_kwDOABGHUc5Y1Moa", "author": {"login": "quiram"}, "body": "Hi @simonbasle.\r\n\r\nThanks a lot for the detailed explanation, that is very informative: I had missed the possibility that type inference could use `Matcher` as the type for `equalTo(String)`, but now that you mention it it makes perfect sense.\r\n\r\nI can see that you've opted to rename the new methods to add the `*List` suffix, I agree that this can be useful for the wider community (there may be many people scratching their heads right now). On the other hand, I really like your suggestion to use `contains()` as opposed to `equalsTo()`, it is a stricter assertion (in our case our headers usually only have one value but you never know!); I think we will adopt it anyway (using the new `*List()` variant as it becomes available).\r\n\r\nOnce again, thanks for addressing this so quickly.", "createdAt": "2023-03-30T13:49:42Z", "updatedAt": "2023-03-30T13:49:42Z"}]}}]}} +{"id": "PR_kwDOABGHUc5NDDBj", "title": "Use log4j-slf4j2-impl ", "body": "Modified to slf4j2-impl in build.gradle\r\ndue to slf4j-api versions 1.7 x or earlier issue\r\n\r\nCloses #30213 ", "number": 30216, "url": "https://github.com/spring-projects/spring-framework/pull/30216", "author": {"login": "kyuarl21"}, "createdAt": "2023-03-28T09:24:50Z", "mergedAt": "2023-04-12T11:11:48Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "2184d4e80e4d2c6de3488e2203a5c9d98ce305fb", "baseRefName": "main", "headRefOid": "38a31f6dd8b5e2dd15187ef6f2f63c811500555e", "headRefName": "main", "changedFiles": 1, "labels": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"name": "type: task"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "38a31f6dd8b5e2dd15187ef6f2f63c811500555e", "message": "Modified to slf4j2-impl in build.gradle\ndue to slf4j-api versions 1.7 x or earlier issue", "changedFilesIfAvailable": 1, "authoredDate": "2023-03-28T09:18:34Z", "author": {"user": {"login": "kyuarl21"}}, "committedDate": "2023-03-28T09:18:45Z", "committer": {"user": {"login": "kyuarl21"}}, "parents": {"nodes": [{"oid": "0c0cda9815645f0864a87cd854158438e1e78117"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5h9PSv", "number": 30213, "url": "https://github.com/spring-projects/spring-framework/issues/30213", "title": "\"SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.\" issue", "body": "I'm not sure, so I'm raising an issue.\r\nDuring the test, an issue of \"SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.\" occurred.\r\n![\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba 2023-03-28 \u110b\u1169\u1112\u116e 5 06 45](https://user-images.githubusercontent.com/97569663/228172774-096fa2f3-1343-47a9-a909-e5c0b5612230.png)\r\n\r\nAs a result of referring to Stack Overflow, the error phrase simply disappeared.\r\n![\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba 2023-03-28 \u110b\u1169\u1112\u116e 5 07 21](https://user-images.githubusercontent.com/97569663/228174173-73f21b5c-b5cf-456a-ad0b-d6a1a569b2da.png)\r\n\r\n![\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba 2023-03-28 \u110b\u1169\u1112\u116e 5 07 41](https://user-images.githubusercontent.com/97569663/228174284-68c995ec-026e-48dc-9aae-cc93753e500b.png)\r\n\r\nSorry if it's not an issue.", "state": "CLOSED", "labels": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOWZ3VNg=="}, "nodes": [{"id": "IC_kwDOABGHUc5ZndU2", "author": {"login": "rstoyanchev"}, "body": "Superseded by #30216.", "createdAt": "2023-04-11T14:49:26Z", "updatedAt": "2023-04-11T14:49:26Z"}]}}]}} +{"id": "PR_kwDOABGHUc5L13pO", "title": "Documentation for Vavr's Try method to trigger transaction rollbacks", "body": "Updated the Spring Framework documentation to include an example of using Vavr's Try monad to trigger transaction rollbacks when a @Transactional-annotated method returns a Failure. The modified documentation demonstrates how to use Try in a transactional method and how to check if an exception has been wrapped inside a Try.Failure instance. Additionally, a link to the official Vavr documentation was added to provide more information on the Try method.\r\n\r\nCloses #29560", "number": 30108, "url": "https://github.com/spring-projects/spring-framework/pull/30108", "author": {"login": "edyda99"}, "createdAt": "2023-03-12T19:20:07Z", "mergedAt": "2023-03-28T08:38:04Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "9cf7b0e230af83e08efa73a43334c75f6110988f", "baseRefName": "main", "headRefOid": "7027e43cc9d2b195157849a7e2a5afc113b13b27", "headRefName": "issue-29560", "changedFiles": 1, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: data"}, {"name": "type: documentation"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "7027e43cc9d2b195157849a7e2a5afc113b13b27", "message": "feat: Add support for Vavr's Try monad to trigger transaction rollbacks\n\nUpdated the Spring Framework documentation to include an example of using Vavr's Try monad to trigger transaction rollbacks when a @Transactional-annotated method returns a Failure. The modified documentation demonstrates how to use Try in a transactional method and how to check if an exception has been wrapped inside a Try.Failure instance. Additionally, a link to the official Vavr documentation was added to provide more information on the Try method.", "changedFilesIfAvailable": 1, "authoredDate": "2023-03-12T19:17:44Z", "author": {"user": {"login": "edyda99"}}, "committedDate": "2023-03-12T19:17:44Z", "committer": {"user": {"login": "edyda99"}}, "parents": {"nodes": [{"oid": "9cf7b0e230af83e08efa73a43334c75f6110988f"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5XIbZJ", "number": 29560, "url": "https://github.com/spring-projects/spring-framework/issues/29560", "title": "Document support of Vavr's `Try` to potentially roll back declarative transactions", "body": "#20361 introduced support for Vavr's `Try` monad to trigger transaction rollbacks when an `@Transactional`-annotated method returns a `Failure`.\r\n\r\nI would appreciate it if that feature was described in the reference documentation, likely [this section](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction-declarative-rolling-back).", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: data"}, {"name": "type: documentation"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOWA_iCA=="}, "nodes": [{"id": "IC_kwDOABGHUc5YD-II", "author": {"login": "jhoeller"}, "body": "Superseded by PR #30108.", "createdAt": "2023-03-21T08:26:04Z", "updatedAt": "2023-03-21T08:26:04Z"}]}}]}} +{"id": "PR_kwDOABGHUc5K3QKj", "title": "Add SpEL support for registered MethodHandles", "body": "This commit adds support for MethodHandles in SpEL, using the same\r\nsyntax as user-defined functions (which also covers reflective Methods).\r\n\r\nThe most benefit is expected with handles that capture a static method\r\nwith no arguments, or with fully bound handles (where all the arguments\r\nhave been bound, including a target instance as first bound argument\r\nif necessary). Partially bound MethodHandle should also be supported.\r\n\r\nA best effort approach is taken to detect varargs as there is no API\r\nsupport to determine if an argument is a vararg or an explicit array,\r\nunlike with Method. Argument conversions are also applied. Finally,\r\narray repacking is not always necessary with varargs so it is only\r\nperformed when the vararg is the sole argument to the invoked method.\r\n\r\nCloses gh-27099\r\nCloses gh-30045\r\n", "number": 30045, "url": "https://github.com/spring-projects/spring-framework/pull/30045", "author": {"login": "simonbasle"}, "createdAt": "2023-02-27T19:05:37Z", "mergedAt": "2023-05-05T14:18:25Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "f2c0b3064156e0159e8c20d59ea4f654aaaaa7d9", "baseRefName": "main", "headRefOid": "88a5167bf0cd6388310d716f7983ddbbe91156c5", "headRefName": "27099-spelMethodHandle", "changedFiles": 9, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: core"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "88a5167bf0cd6388310d716f7983ddbbe91156c5", "message": "Add SpEL support for registered MethodHandles\n\nThis commit adds support for MethodHandles in SpEL, using the same\nsyntax as user-defined functions (which also covers reflective Methods).\n\nThe most benefit is expected with handles that capture a static method\nwith no arguments, or with fully bound handles (where all the arguments\nhave been bound, including a target instance as first bound argument\nif necessary). Partially bound MethodHandle should also be supported.\n\nA best effort approach is taken to detect varargs as there is no API\nsupport to determine if an argument is a vararg or an explicit array,\nunlike with Method. Argument conversions are also applied. Finally,\narray repacking is not always necessary with varargs so it is only\nperformed when the vararg is the sole argument to the invoked method.\n\nSee gh-27099\nCloses gh-30045", "changedFilesIfAvailable": 9, "authoredDate": "2023-02-27T18:58:05Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-05-05T13:56:40Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "f2c0b3064156e0159e8c20d59ea4f654aaaaa7d9"}]}}}]}, "reviews": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMy0wN1QxNjo1MDo0MyswODowMLkyMDIzLTAzLTA3VDE2OjUwOjQyKzA4OjAwzk8mOUY="}, "nodes": [{"id": "PRR_kwDOABGHUc5PJjlG", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-03-07T08:50:43Z", "updatedAt": "2023-03-07T08:50:43Z", "commit": null, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMy0wN1QwODo1MDo0MlrOQzTcQg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5DNNxC", "author": {"login": "simonbasle"}, "body": "here the subtle difference compared to the older `convertAllMethodArguments` higher in the source file is that we get `TypeDescriptor` out of a raw `Class` only (vs a `MethodParam` obtained via reflection with `MethodParameter.forExecutable`)", "createdAt": "2023-03-07T08:50:42Z", "updatedAt": "2023-03-07T08:50:54Z", "path": "spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java", "diffHunk": "@@ -330,6 +333,90 @@ else if (!sourceType.equals(targetType.getElementTypeDescriptor())) {\n \t\treturn conversionOccurred;\n \t}\n \n+\t/**\n+\t * Takes an input set of argument values and converts them to the types specified as the\n+\t * required parameter types. The arguments are converted 'in-place' in the input array.\n+\t * @param converter the type converter to use for attempting conversions\n+\t * @param arguments the actual arguments that need conversion\n+\t * @param methodHandle the target MethodHandle\n+\t * @param varargsPosition the known position of the varargs argument, if any\n+\t * ({@code null} if not varargs)\n+\t * @return {@code true} if some kind of conversion occurred on an argument\n+\t * @throws EvaluationException if a problem occurs during conversion\n+\t */\n+\tpublic static boolean convertAllMethodHandleArguments(TypeConverter converter, Object[] arguments,\n+\t\t\tMethodHandle methodHandle, @Nullable Integer varargsPosition) throws EvaluationException {\n+\t\tboolean conversionOccurred = false;\n+\t\tfinal MethodType methodHandleArgumentTypes = methodHandle.type();\n+\t\tif (varargsPosition == null) {\n+\t\t\tfor (int i = 0; i < arguments.length; i++) {\n+\t\t\t\tClass argumentClass = methodHandleArgumentTypes.parameterType(i);\n+\t\t\t\tResolvableType resolvableType = ResolvableType.forClass(argumentClass);\n+\t\t\t\tTypeDescriptor targetType = new TypeDescriptor(resolvableType, argumentClass, null);", "line": 356, "startLine": null, "originalLine": 356, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "88a5167bf0cd6388310d716f7983ddbbe91156c5"}, "originalCommit": null}]}}]}, "reviewThreads": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMy0wN1QwODo1MDo0MlrOKvw9YQ=="}, "nodes": [{"id": "PRRT_kwDOABGHUc4q_D1h", "isResolved": false, "isOutdated": false, "isCollapsed": false, "path": "spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java", "startLine": 356, "originalLine": 356, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": null, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMy0wN1QwODo1MDo0MlrOQzTcQg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc5DNNxC"}]}}]}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU5MzAwNzcxOTY=", "number": 27099, "url": "https://github.com/spring-projects/spring-framework/issues/27099", "title": "SpEL FunctionReference could support MethodHandle", "body": "A SpEL `FunctionReference` is currently limited to a **static** `Method` object, limiting what it can do drastically.\r\n\r\nOddly enough, the source code seems to imply that it could reference something else than a static Method, but if I'm not mistaken, there is only one code path, failing early with an exception if the method is not a static method:\r\n\r\nhttps://github.com/spring-projects/spring-framework/blob/a2ef6badc4c76790128910851fdde0df55ec15f9/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java#L73-L77\r\n\r\nthen later:\r\nhttps://github.com/spring-projects/spring-framework/blob/a2ef6badc4c76790128910851fdde0df55ec15f9/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java#L105-L108\r\n\r\n\r\nAnyways, it would be nice if `FunctionReference` could actually reference a `MethodHandle`, thus capturing a receiver (or even more context) that wouldn't have to leak in the signature to the \"function\".\r\n\r\nAre there any show stoppers for this? AFAIU, compilation to bytecode is optional, so even that shouldn't be a problem (but maybe it is actually possible). Happy to work on a PR for this if deemed acceptable.\r\n", "state": "CLOSED", "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: core"}, {"name": "type: enhancement"}]}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOVj3oTA=="}, "nodes": [{"id": "IC_kwDOABGHUc5WAZYu", "author": {"login": "fanthos"}, "body": "I resolved this issue by replace the original `FunctionReference` using my patched version, by replacing the `FunctionReference` AST object. I made parameters optional (default to null) in my implemention, and disable bytecode generation when object instance is not null. The patched version could call instance function.", "createdAt": "2023-02-24T07:32:32Z", "updatedAt": "2023-02-24T07:32:32Z"}, {"id": "IC_kwDOABGHUc5WPehM", "author": {"login": "simonbasle"}, "body": "Superseded by gh-30045\r\nLet's discuss the implementation in the PR \ud83d\udc4d ", "createdAt": "2023-02-27T19:06:30Z", "updatedAt": "2023-02-27T19:06:30Z"}]}}]}} +{"id": "PR_kwDOABGHUc5Kn7wW", "title": "Add test support to record async events, with JUnit Jupiter caveat", "body": "This commit modifies the way the `@RecordApplicationEvents` annotation\nworks in tests, allowing for capture of events from threads other than\nthe main test thread (async events) and for the assertion of captured\nevent from a separate thread (e.g. when using `Awaitility`).\n\nThis is done by switching the `ApplicationEventsHolder` to use an\n`InheritedThreadLocal`.\n\nThere is a mutual exclusion between support of asynchronous events vs\nsupport of JUnit5 parallel tests with the `@TestInstance(PER_CLASS)`\nmode. As a result, we favor the former and now `SpringExtension` will\ninvalidate a test class that is annotated (or meta-annotated, or\nenclosed-annotated) with `@RecordApplicationEvents` AND\n`@TestInstance(PER_CLASS)` AND `@Execution(CONCURRENT)`.\n\nCloses gh-29827\n", "number": 30020, "url": "https://github.com/spring-projects/spring-framework/pull/30020", "author": {"login": "simonbasle"}, "createdAt": "2023-02-23T16:41:43Z", "mergedAt": "2023-05-05T15:10:41Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "906c54faffc75721b98f9b9cf63d35edd81f7b4f", "baseRefName": "main", "headRefOid": "f269a80ef76dcddb1529345b221e9a35ced68e92", "headRefName": "29827-inheritTheadApplicationEvents", "changedFiles": 8, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: test"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "f269a80ef76dcddb1529345b221e9a35ced68e92", "message": "Add test support to record async events, with Junit5 caveat\n\nThis commit modifies the way the `@RecordApplicationEvents` annotation\nworks in tests, allowing for capture of events from threads other than\nthe main test thread (async events) and for the assertion of captured\nevent from a separate thread (e.g. when using `Awaitility`).\n\nThis is done by switching the `ApplicationEventsHolder` to use an\n`InheritedThreadLocal`.\n\nThere is a mutual exclusion between support of asynchronous events vs\nsupport of JUnit5 parallel tests with the `@TestInstance(PER_CLASS)`\nmode. As a result, we favor the former and now `SpringExtension` will\ninvalidate a test class that is annotated (or meta-annotated, or\nenclosed-annotated) with `@RecordApplicationEvents` AND\n`@TestInstance(PER_CLASS)` AND `@Execution(CONCURRENT)`.\n\nSee gh-29827\nCloses gh-30020", "changedFilesIfAvailable": 8, "authoredDate": "2023-02-23T16:33:41Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-05-05T14:21:39Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "906c54faffc75721b98f9b9cf63d35edd81f7b4f"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5bfvsP", "number": 29827, "url": "https://github.com/spring-projects/spring-framework/issues/29827", "title": "`@RecordApplicationEvents` should record events from spawned threads, too", "body": "The infrastructure behind `@RecordApplicationEvents` currently uses a `ThreadLocal` to capture application events published by the current thread. Unfortunately, this rules out events published by asynchronous event listeners in turn. It would be nice if events would be captured that are published on threads spawned by the current execution thread.", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: test"}, {"name": "type: enhancement"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOW5KduA=="}, "nodes": [{"id": "IC_kwDOABGHUc5ShHdQ", "author": {"login": "sbrannen"}, "body": "## Related Issues\r\n\r\n- https://github.com/spring-projects-experimental/spring-modulith/issues/116", "createdAt": "2023-01-16T18:16:01Z", "updatedAt": "2023-01-16T18:16:01Z"}, {"id": "IC_kwDOABGHUc5VIbfv", "author": {"login": "simonbasle"}, "body": "The model falls apart for concurrent tests, and most notably for tests cases that instantiate the _Test Class_ once. Typically, JUnit5 tests with `@TestInstance(Lifecycle.PER_CLASS)` (and TestNG as well if I understand correctly).\r\n\r\nTo be clear, turning the `ApplicationEventsHolder` `ThreadLocal` into an `InheritableThreadLocal` breaks the above case (as demonstrated by `ParallelApplicationEventsIntegrationTests`).\r\n\r\nUnlike in Spring Modulith, we can't really assume that tests are not parallelized (or at least parallelized in a way that events collection won't get polluted), so we have to chose between:\r\n 1. support concurrent tests / `Lifecycle.PER_CLASS`\r\n 2. support asynchronously published events and events assertions performed in a separate thread (like with Awaitility)\r\n\r\nThe `@Autowired` support is also problematic, because for `PER_CLASS` the `ApplicationEvents` is injected once and cannot have a dedicated instance per test method.\r\n\r\nThis can't be solved in time for 6.0.5, and in fact I'm not sure this can be solved at all without some breaking change / behavior (and as such 6.1.0 would potentially be a better candidate). Removing from milestone and marking for further team discussion / design.", "createdAt": "2023-02-13T16:46:39Z", "updatedAt": "2023-02-13T16:46:39Z"}, {"id": "IC_kwDOABGHUc5V9A6g", "author": {"login": "simonbasle"}, "body": "I've made quite the number of local iterations on this one, and I think the minimum viable implementation is one that:\r\n\r\n 1. have `SpringExtension` detect and reject test cases annotated with `@RecordApplicationEvents` and `@TestInstance(Lifecycle.PER_CLASS)` and `@Execution(ExecutionMode.CONCURRENT)`\r\n 2. have `ApplicationEventsHolder` use an `InheritableThreadLocal`\r\n\r\nI've tried various other configurations, none of which really alleviate the PER_CLASS caveat. These other ideas included: storing an `ApplicationEvents` in the `TestContext`, attempting to register one `ApplicationEventApplicationListener` per test and to trigger autowiring again, filtering captured events in the listener if a different `ApplicationEvents` could be found in the holder vs the one with which the event listener was constructed...\r\n\r\nIn the end, the `InheritableThreadLocal` seems to have the same impact with the minimum of code. ", "createdAt": "2023-02-23T16:18:35Z", "updatedAt": "2023-02-23T16:18:35Z"}, {"id": "IC_kwDOABGHUc5bkp24", "author": {"login": "simonbasle"}, "body": "Superseded by gh-30020", "createdAt": "2023-05-05T14:19:56Z", "updatedAt": "2023-05-05T14:19:56Z"}]}}]}} +{"id": "PR_kwDOABGHUc5Joq93", "title": "Allow MockRest to match header/queryParam value list with one Matcher", "body": "This commit adds a `header` variant and a `queryParam` variant to the\n`MockRestRequestMatchers` API which take a single `Matcher` over the\nlist of values.\n\nContrary to the vararg variants, the whole list is evaluated and the\ncaller can choose the desired semantics using readily-available iterable\nmatchers like `everyItem`, `hasItems`, `hasSize`, `contains` or\n`containsInAnyOrder`...\n\nThe fact that the previous variants don't strictly check the size of the\nactual list == the number of provided matchers or expected values is\nnow documented in their respective javadocs.\n\nCloses gh-28660\n", "number": 29953, "url": "https://github.com/spring-projects/spring-framework/pull/29953", "author": {"login": "simonbasle"}, "createdAt": "2023-02-09T16:28:36Z", "mergedAt": "2023-02-13T16:51:01Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "ca9439657e001be5c5bb3460e128ce2f968dfec1", "baseRefName": "main", "headRefOid": "c662b31ec1e615e91b30a25bdf061c625deef29c", "headRefName": "28660-requestMatcherWholeValues", "changedFiles": 2, "labels": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "NA"}, "nodes": [{"name": "in: test"}, {"name": "status: backported"}, {"name": "in: web"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "d9a60b9386861010408762b03fcb3c3059ebeb2e", "message": "Allow MockRest to match header/queryParam value list with one Matcher\n\nThis commit adds a `header` variant and a `queryParam` variant to the\n`MockRestRequestMatchers` API which take a single `Matcher` over the\nlist of values.\n\nContrary to the vararg variants, the whole list is evaluated and the\ncaller can choose the desired semantics using readily-available iterable\nmatchers like `everyItem`, `hasItems`, `hasSize`, `contains` or\n`containsInAnyOrder`...\n\nThe fact that the previous variants don't strictly check the size of the\nactual list == the number of provided matchers or expected values is\nnow documented in their respective javadocs.\n\nCloses gh-28660", "changedFilesIfAvailable": 2, "authoredDate": "2023-02-09T16:18:20Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-02-09T16:18:20Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "ca9439657e001be5c5bb3460e128ce2f968dfec1"}]}}}, {"commit": {"oid": "c662b31ec1e615e91b30a25bdf061c625deef29c", "message": "fix wrapping of javadocs", "changedFilesIfAvailable": 1, "authoredDate": "2023-02-13T08:51:22Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-02-13T08:51:22Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "d9a60b9386861010408762b03fcb3c3059ebeb2e"}]}}}]}, "reviews": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMi0xMFQwMDo0NToxMyswODowMLkyMDIzLTAyLTEwVDAwOjQ1OjEzKzA4OjAwzkz79Os="}, "nodes": [{"id": "PRR_kwDOABGHUc5M-_Tr", "author": {"login": "rstoyanchev"}, "state": "APPROVED", "body": "Looks good, just minor formatting comment. For Javadoc we [wrap around 90](https://github.com/spring-projects/spring-framework/wiki/Code-Style#line-wrapping), or even 80.", "submittedAt": "2023-02-09T16:45:13Z", "updatedAt": "2023-02-09T16:45:13Z", "commit": {"oid": "d9a60b9386861010408762b03fcb3c3059ebeb2e"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5MFg2f", "number": 28660, "url": "https://github.com/spring-projects/spring-framework/issues/28660", "title": "Add support in `MockRestServiceServer` to assert ALL `header` and `queryParam` values with a single `Matcher`", "body": "**Affects:** 5.3.21\r\n\r\n---\r\n\r\nThe current API for `MockRestServiceServer` and `MockRestRequestMatchers` does not allow a test to validate that all values of a certain header key satisfy a matcher. Trying to do\r\n\r\n```java\r\n.andExpect(header(\"Accept\", endsWith(\"json\")))\r\n```\r\n\r\ndoes not work because it passes if the first value for the header ends with `\"json\"`. I would like to be able to do something like this:\r\n\r\n```java\r\n.andExpect(header(\"Accept\", allMatch(endsWith(\"json\"))))\r\n```\r\n\r\nor something to that effect.\r\n", "state": "CLOSED", "labels": {"totalCount": 5, "pageInfo": {"hasNextPage": false, "endCursor": "NQ"}, "nodes": [{"name": "in: test"}, {"name": "status: backported"}, {"name": "in: web"}, {"name": "type: enhancement"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 11, "pageInfo": {"hasNextPage": true, "endCursor": "Y3Vyc29yOnYyOpHOVNHdPw=="}, "nodes": [{"id": "IC_kwDOABGHUc5FLr4X", "author": {"login": "sbrannen"}, "body": "Hi @mspiess,\r\n\r\n> I would like to be able to do something like this:\r\n> \r\n> ```java\r\n> .andExpect(header(\"Accept\", allMatch(endsWith(\"json\"))))\r\n> ```\r\n> \r\n> or something to that effect.\r\n\r\nThat's a good point. In fact, it almost appears that the current API would support that. At least, the current tests in place are based on that assumption.\r\n\r\nhttps://github.com/spring-projects/spring-framework/blob/93b340e5633d623e0899dd296bda7ce86ce02b20/spring-test/src/test/java/org/springframework/test/web/client/match/MockRestRequestMatchersTests.java#L126-L131\r\n\r\nThat `headerContains()` test actually does not assert what it appears to.\r\n\r\nSince `bar` and `baz` both contain `ba`, the test **appears** to assert that both `bar` and `baz` are checked, but in fact -- as you've pointed out -- only `bar` is checked.\r\n\r\nIn other words, rewriting the assertion as follows would also cause the test to pass.\r\n\r\n```java\r\nMockRestRequestMatchers.header(\"foo\", containsString(\"bar\")).match(this.request);\r\n```\r\n\r\nIn order to perform an assertion on each header value, you have to provide a matcher for each value. Thus, the following **fails**:\r\n\r\n```java\r\nMockRestRequestMatchers.header(\"foo\", containsString(\"bar\"), containsString(\"bar\")).match(this.request);\r\n```\r\n\r\nWhereas, the following **pass**:\r\n\r\n```java\r\nMockRestRequestMatchers.header(\"foo\", containsString(\"bar\"), containsString(\"baz\")).match(this.request);\r\n\r\nMockRestRequestMatchers.header(\"foo\", containsString(\"ba\"), containsString(\"ba\")).match(this.request);\r\n```\r\n\r\nThus, there is in fact support for performing assertions against all of the values for a given header, but it is awkward to use and not really documented.\r\n\r\nFurthermore, with the current implementation of this feature you have to know exactly how many values are expected **and** you have to repeat the `Matcher` or expected value.\r\n\r\nFYI: this applies to all variants of `queryParam(...)` and `header(...)`.\r\n\r\n----\r\n\r\nOne way to address this would be to introduce new variants of these methods that accept a single `String` or `Matcher` (instead of var-args) such as the following.\r\n\r\n```java\r\npublic static RequestMatcher header(String name, Matcher matcher) {\r\n\treturn request -> {\r\n\t\tList headerValues = request.getHeaders().get(name);\r\n\t\tassertNotNull(\"No header values\", headerValues);\r\n\t\tString reason = \"Request header [\" + name + \"]\";\r\n\t\theaderValues.forEach(value -> assertThat(reason, value, matcher));\r\n\t};\r\n}\r\n```\r\n\r\nThis would achieve what you are requesting; however, there is a downside: any invocation of `header()` or `queryParam()` with a single argument for the var-args array would now invoke this new method when recompiled, which would be a breaking change. To avoid that, we could come up with a new name for the single-argument variants.", "createdAt": "2022-06-20T17:27:19Z", "updatedAt": "2022-06-20T17:33:31Z"}, {"id": "IC_kwDOABGHUc5FL_x_", "author": {"login": "mspiess"}, "body": "Hi @sbrannen,\r\nthanks for the quick response and the nice summary.\r\n\r\nPerhaps a new overload would be a less of a breaking change:\r\n```Java\r\npublic static RequestMatcher header(String name, Matcher> matcher) {\r\n\treturn request -> {\r\n\t\tList headerValues = request.getHeaders().get(name);\r\n\t\tassertThat(\"Request header [\" + name + \"]\", headerValues, matcher);\r\n\t};\r\n}\r\n```\r\nThis would allow the following:\r\n```Java\r\nMockRestRequestMatchers.header(\"foo\", everyItem(containsString(\"ba\"))).match(this.request);\r\n```\r\nThis brings more control to the call site, as the caller can decide how to match the collection. E.g. one may want to assert that any value matches, which is not possible currently without knowing the amount and order of the header values.\r\nAlthough I have to acknowledge that this is a strong difference in behavior for an overload and may cause some confusion.\r\n\r\n>To avoid that, we could come up with a new name for the single-argument variants.\r\n\r\nI suggest `headerValues`.", "createdAt": "2022-06-20T19:21:45Z", "updatedAt": "2022-06-21T05:59:41Z"}, {"id": "IC_kwDOABGHUc5FO-qo", "author": {"login": "rstoyanchev"}, "body": "When it comes to headers, I don't think the expectation that you would know how many and match each individually is all that unreasonable. I'd expect that matching across all headers in one condition is probably a less common case.\r\n\r\nThe Javadoc on the existing methods could certainly use an improvement, even if it's obvious that a vararg means, one value or Matcher for each value.\r\n\r\nNothing wrong with introducing a variant that accepts a `Matcher>` but I wouldn't call it `headerValues` since the other one is also capable of matching all header values. Perhaps `headerList` would be more explicit about the difference.", "createdAt": "2022-06-21T10:21:55Z", "updatedAt": "2022-06-21T10:21:55Z"}, {"id": "IC_kwDOABGHUc5FQEQS", "author": {"login": "sbrannen"}, "body": "> I'd expect that matching across all headers in one condition is probably a less common case.\r\n\r\nI agree.\r\n\r\n> The Javadoc on the existing methods could certainly use an improvement\r\n\r\nYes, let's improve the documentation for the affected methods.\r\n\r\n> Nothing wrong with introducing a variant that accepts a `Matcher>` \r\n\r\nI did some research on what's available in Hamcrest. Instead of `Collection`, they use `Iterable`. So let's go with `Iterable` for compatibility.\r\n\r\nThe interesting (disappointing?) part is that `everyItem()` and `hasItem()` have different generic signatures. `everyItem()` produces `Matcher>`; whereas, `hasItem()` produces `Matcher>`. \r\n\r\nThis makes `everyItem()` incompatible with the proposed new method in `MockRestRequestMatchers`, but there's nothing we can do about that since it's baked into Hamcrest like that.\r\n\r\nThough you can create a custom `everyItem()` implementation that ignores the generics as follows, and this will work with the new method in `MockRestRequestMatchers`.\r\n\r\n```java\r\n@SuppressWarnings({ \"rawtypes\", \"unchecked\" })\r\npublic static Matcher> everyItem(Matcher itemMatcher) {\r\n return new Every(itemMatcher);\r\n}\r\n```\r\n\r\n> but I wouldn't call it `headerValues` since the other one is also capable of matching all header values. Perhaps `headerList` would be more explicit about the difference.\r\n\r\nWith the proposed signature below, we don't actually run into any issues with the compiler (in terms of source compatibility).\r\n\r\n```java\r\npublic static RequestMatcher header(String name, Matcher> matcher)\r\n```\r\n\r\nSo we could choose to keep the `header` method name, but perhaps a different name would help to highlight the difference in behavior (and avoid binary incompatibility).", "createdAt": "2022-06-21T14:40:33Z", "updatedAt": "2022-06-21T14:40:33Z"}, {"id": "IC_kwDOABGHUc5FQbAC", "author": {"login": "rstoyanchev"}, "body": "Keeping the `header` method name sounds good. ", "createdAt": "2022-06-21T15:42:45Z", "updatedAt": "2022-06-21T15:42:45Z"}, {"id": "IC_kwDOABGHUc5FQvwy", "author": {"login": "sbrannen"}, "body": "> The interesting (disappointing?) part is that `everyItem()` and `hasItem()` have different generic signatures. `everyItem()` produces `Matcher>`; whereas, `hasItem()` produces `Matcher>`.\r\n\r\nIt turns out that there are open issues for Hamcrest on this topic.\r\n\r\nSee https://github.com/hamcrest/JavaHamcrest/issues/289#issuecomment-1162016379 for details.", "createdAt": "2022-06-21T16:59:52Z", "updatedAt": "2022-06-21T16:59:52Z"}, {"id": "IC_kwDOABGHUc5UtyQH", "author": {"login": "rstoyanchev"}, "body": "@sbrannen, do we go with your most recent proposal?\r\n\r\n```java\r\npublic static RequestMatcher header(String name, Matcher> matcher)\r\n```\r\n\r\nIts usefulness is reduced by the Hamcrest issue, however, that doesn't seem to be moving. Perhaps we can just go back to the earlier suggestion with a slightly different name:\r\n\r\n```java\r\npublic static RequestMatcher everyHeader(String name, Matcher matcher);\r\n```\r\n", "createdAt": "2023-02-07T18:55:05Z", "updatedAt": "2023-02-07T18:55:48Z"}, {"id": "IC_kwDOABGHUc5Uyxkd", "author": {"login": "sbrannen"}, "body": "> @sbrannen, do we go with your most recent proposal?\r\n> \r\n> ```java\r\n> public static RequestMatcher header(String name, Matcher> matcher)\r\n> ```\r\n\r\nYes, I believe that's the route we need to go.\r\n\r\n> Its usefulness is reduced by the Hamcrest issue, however, that doesn't seem to be moving. \r\n\r\nIndeed, unfortunately.\r\n\r\n> Perhaps we can just go back to the earlier suggestion with a slightly different name:\r\n> \r\n> ```java\r\n> public static RequestMatcher everyHeader(String name, Matcher matcher);\r\n> ```\r\n\r\nI think this is too limiting. The same matcher would be applied to each queryParam/header value individually instead of acting on the collection as a whole -- effectively the same semantics as `Matchers.everyItem()`.\r\n\r\nIn other words, if we go this route users would not be able to benefit from features like `Matchers.hasItem()`.\r\n\r\nOf course, if we wanted to provide a workaround for the generics issues in Hamcrest... we _could_ introduce both methods. However, I'm not convinced we should do that; as I mentioned in https://github.com/spring-projects/spring-framework/issues/28660#issuecomment-1161839634, users can come up with their own workarounds for the generics issues in Hamcrest.\r\n\r\n----\r\n\r\n@simonbasle has expressed in interest in taking on this issue, so I've assigned it to him for tentative inclusion in 6.0.5.\r\n\r\n----\r\n\r\nPlease note that I changed the title of this issue to reflect a changed focus on both `header()` and `queryParam()` from `MockRestRequestMatchers`.\r\n", "createdAt": "2023-02-08T13:24:25Z", "updatedAt": "2023-02-08T13:24:25Z"}, {"id": "IC_kwDOABGHUc5UzHw1", "author": {"login": "rstoyanchev"}, "body": "> Of course, if we wanted to provide a workaround for the generics issues in Hamcrest... we could introduce both methods. However, I'm not convinced we should do that; as I mentioned in https://github.com/spring-projects/spring-framework/issues/28660#issuecomment-1161839634, users can come up with their own workarounds for the generics issues in Hamcrest.\r\n\r\nVery much worth explaining and illustrating this in the Javadoc of such a new method.", "createdAt": "2023-02-08T14:29:38Z", "updatedAt": "2023-02-08T14:29:38Z"}, {"id": "IC_kwDOABGHUc5U0d0_", "author": {"login": "simonbasle"}, "body": "I'm having a look and I need to better understand why, but it appears that the following signature works both for `hasItem` and `everyItem` (among others):\r\n\r\n```java\r\npublic static RequestMatcher header(String name, Matcher> matcher) {\r\n```\r\n\r\n
\r\nSee test below demonstrating usage with various matchers\r\n\r\n```java\r\n@Test\r\nvoid headerListMatchers() throws IOException {\r\n\tthis.request.getHeaders().put(\"foo\", Arrays.asList(\"bar\", \"baz\"));\r\n\r\n\tMockRestRequestMatchers.header(\"foo\", containsInAnyOrder(endsWith(\"baz\"), endsWith(\"bar\"))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), is(\"baz\"))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", contains(is(\"bar\"), Matchers.anything())).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", hasItem(endsWith(\"baz\"))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", everyItem(startsWith(\"ba\"))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", hasSize(2)).match(this.request);\r\n\r\n\t//these can be a bit ambiguous when reading the test (the compiler selects the list matcher):\r\n\tMockRestRequestMatchers.header(\"foo\", notNullValue()).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", is(anything())).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), notNullValue())).match(this.request);\r\n\r\n\t//these are not as ambiguous thanks to an inner matcher that is either obviously list-oriented,\r\n\t//string-oriented or obviously a vararg of matchers\r\n\t//list matcher version\r\n\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), hasSize(2))).match(this.request);\r\n\t//vararg version\r\n\tMockRestRequestMatchers.header(\"foo\", allOf(notNullValue(), endsWith(\"ar\"))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", is((any(String.class)))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", CoreMatchers.either(is(\"bar\")).or(is(nullValue()))).match(this.request);\r\n\tMockRestRequestMatchers.header(\"foo\", is(notNullValue()), is(notNullValue()));\r\n}\r\n```\r\n\r\n
", "createdAt": "2023-02-08T18:10:28Z", "updatedAt": "2023-02-08T18:13:23Z"}]}}]}} +{"id": "PR_kwDOABGHUc5GoWjs", "title": "Polish #29727: Mention Kotlin andExpectAll in reference manual", "body": "This just adds a Kotlin snippet alongside the Java snippet in the\nreference manual.\n\nRelates to gh-29727\nCloses gh-27317\n", "number": 29766, "url": "https://github.com/spring-projects/spring-framework/pull/29766", "author": {"login": "simonbasle"}, "createdAt": "2023-01-04T14:19:55Z", "mergedAt": "2023-01-04T18:11:54Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "74f58198fd689408973363d00a730b5c2bf4ed14", "baseRefName": "main", "headRefOid": "0b9aef3084ae1491159462a9b53e4e8ee9ca8527", "headRefName": "expectAllDslInRefguide", "changedFiles": 1, "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: test"}, {"name": "type: documentation"}, {"name": "theme: kotlin"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "0b9aef3084ae1491159462a9b53e4e8ee9ca8527", "message": "Polish #29727: Mention Kotlin andExpectAll in reference manual\n\nThis just adds a Kotlin snippet alongside the Java snippet in the\nreference manual.\n\nRelates to gh-29727\nCloses gh-27317", "changedFilesIfAvailable": 1, "authoredDate": "2023-01-04T13:50:28Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-01-04T13:50:28Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "74f58198fd689408973363d00a730b5c2bf4ed14"}]}}}]}, "reviews": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMS0wNVQwMDoxMTozNSswODowMLkyMDIzLTAxLTA1VDAwOjExOjM1KzA4OjAwzkmt2e4="}, "nodes": [{"id": "PRR_kwDOABGHUc5Jrdnu", "author": {"login": "sdeleuze"}, "state": "APPROVED", "body": "", "submittedAt": "2023-01-04T16:11:35Z", "updatedAt": "2023-01-04T16:11:35Z", "commit": {"oid": "0b9aef3084ae1491159462a9b53e4e8ee9ca8527"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU5NzcwNzcyNTQ=", "number": 27317, "url": "https://github.com/spring-projects/spring-framework/issues/27317", "title": "Introduce Kotlin DSL for `ResultActions.andExpectAll()`", "body": "## Overview\r\n\r\nCommit dd9b99e13d6b30462fb168799e6bbca1456123da introduced `ResultActions.andExpectAll()` to support _soft assertions_ in `MockMvc`.\r\n\r\n`ResultActionsDsl.kt` already has support for `andExpect()`.\r\n\r\n\r\n## Related Issues\r\n\r\n- #27318\r\n\r\n## Deliverables\r\n\r\n- [x] Introduce Kotlin support for `ResultActions.andExpectAll()` in `ResultActionsDsl.kt`. => #29727 \r\n- [x] Add a Kotlin example using `andExpectAll()` in the reference manual alongside the Java example introduced in dd9b99e13d6b30462fb168799e6bbca1456123da. => #29766 ", "state": "CLOSED", "labels": {"totalCount": 5, "pageInfo": {"hasNextPage": false, "endCursor": "NQ"}, "nodes": [{"name": "in: test"}, {"name": "in: web"}, {"name": "type: enhancement"}, {"name": "status: superseded"}, {"name": "theme: kotlin"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOU44UFw=="}, "nodes": [{"id": "IC_kwDOABGHUc5TjhQX", "author": {"login": "sbrannen"}, "body": "- Superseded by #29727", "createdAt": "2023-01-24T11:58:26Z", "updatedAt": "2023-01-24T11:58:26Z"}]}}]}} +{"id": "PR_kwDOABGHUc5F-K4E", "title": "Add Kotlin DSL support for MockMVC andExpectAll", "body": "As the DSL internally calls `ResultActions.andExpect`, this is done with a trick where a synthetic `ResultActions` is provided at top level which stores each `ResultMatcher` in a mutable list. Once the DSL usage is done, the top level DSL `andExpectAll` turns that list into a `vararg` passed down to the actual `actions.andExpectAll`.\r\n\r\nCloses gh-27317\r\n", "number": 29727, "url": "https://github.com/spring-projects/spring-framework/pull/29727", "author": {"login": "simonbasle"}, "createdAt": "2022-12-21T16:12:03Z", "mergedAt": "2023-01-03T17:26:26Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "697292ba0ca5aa69454e7a184197be90c75de3ab", "baseRefName": "main", "headRefOid": "16bbf3ed40891259aaa4cde17da700027bb481bc", "headRefName": "27317-kotlinAndExpectAll", "changedFiles": 3, "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: test"}, {"name": "type: enhancement"}, {"name": "theme: kotlin"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b", "message": "Add Kotlin DSL support for MockMVC andExpectAll\n\nAs the DSL internally calls ResultActions.andExpect, this is done with\na trick where a synthetic ResultActions is provided at top level which\nstores each ResultMatcher in a mutable list. Once the DSL usage is done,\n the top level DSL andExpectAll turns that list into a vararg passed\n down to the actual `actions.andExpectAll`.\n\nFixes gh-27317.", "changedFilesIfAvailable": 3, "authoredDate": "2022-12-21T16:07:59Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2022-12-21T16:07:59Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "697292ba0ca5aa69454e7a184197be90c75de3ab"}]}}}, {"commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc", "message": "review: add since, add matchAll test", "changedFilesIfAvailable": 3, "authoredDate": "2023-01-03T16:17:59Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-01-03T16:17:59Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}]}}}]}, "reviews": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMS0wNFQwMDoxOTo1MiswODowMLkyMDIzLTAxLTA0VDAwOjE5OjUxKzA4OjAwzkmZZfs="}, "nodes": [{"id": "PRR_kwDOABGHUc5Jl8Tx", "author": {"login": "sdeleuze"}, "state": "APPROVED", "body": "Looks a fine way to solve this non trivial issue, please just check the few comments I added.", "submittedAt": "2023-01-03T15:07:44Z", "updatedAt": "2023-01-03T15:07:44Z", "commit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}, "comments": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNTowNjoxNVrOPziWoA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OJAG", "author": {"login": "sdeleuze"}, "body": "Maybe add a related usage in tests?", "createdAt": "2023-01-03T15:04:19Z", "updatedAt": "2023-01-03T15:07:44Z", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diffHunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {", "line": 153, "startLine": null, "originalLine": 152, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc"}, "originalCommit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}}, {"id": "PRRC_kwDOABGHUc4_OJK5", "author": {"login": "sdeleuze"}, "body": "Clever trick, seems to provide a desired behavior, so good catch!", "createdAt": "2023-01-03T15:05:05Z", "updatedAt": "2023-01-03T15:07:44Z", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diffHunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll\n+\t */\n+\tfun andExpectAll(dsl: MockMvcResultMatchersDsl.() -> Unit): ResultActionsDsl {", "line": 28, "startLine": null, "originalLine": 27, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc"}, "originalCommit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}}, {"id": "PRRC_kwDOABGHUc4_OJY-", "author": {"login": "sdeleuze"}, "body": "Maybe add `@since 6.0.4`?", "createdAt": "2023-01-03T15:06:06Z", "updatedAt": "2023-01-03T15:07:44Z", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diffHunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll", "line": 151, "startLine": null, "originalLine": 150, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc"}, "originalCommit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}}, {"id": "PRRC_kwDOABGHUc4_OJag", "author": {"login": "sdeleuze"}, "body": "Maybe add `@since 6.0.4`?", "createdAt": "2023-01-03T15:06:15Z", "updatedAt": "2023-01-03T15:07:44Z", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "diffHunk": "@@ -19,6 +19,34 @@ class ResultActionsDsl internal constructor (private val actions: ResultActions,\n \t\treturn this\n \t}\n \n+\n+\t/**\n+\t * Provide access to [MockMvcResultMatchersDsl] Kotlin DSL.\n+\t * @see MockMvcResultMatchersDsl.matchAll", "line": 26, "startLine": null, "originalLine": 25, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc"}, "originalCommit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}}]}}, {"id": "PRR_kwDOABGHUc5JmWX7", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "", "submittedAt": "2023-01-03T16:19:52Z", "updatedAt": "2023-01-03T16:19:52Z", "commit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNjoxOTo1MVrOPzmkYQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OaRh", "author": {"login": "simonbasle"}, "body": "done", "createdAt": "2023-01-03T16:19:51Z", "updatedAt": "2023-01-03T16:19:52Z", "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "diffHunk": "@@ -145,4 +145,11 @@ class MockMvcResultMatchersDsl internal constructor (private val actions: Result\n \tfun match(matcher: ResultMatcher) {\n \t\tactions.andExpect(matcher)\n \t}\n+\n+\t/**\n+\t * @see ResultActions.andExpectAll\n+\t */\n+\tfun matchAll(vararg matchers: ResultMatcher) {", "line": 153, "startLine": null, "originalLine": 152, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4_OJAG"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "16bbf3ed40891259aaa4cde17da700027bb481bc"}, "originalCommit": {"oid": "4fc268959235c12426202938f479ba079a3a3e9b"}}]}}]}, "reviewThreads": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNTowNjoxNVrOKHdk0g=="}, "nodes": [{"id": "PRRT_kwDOABGHUc4od2CR", "isResolved": true, "isOutdated": false, "isCollapsed": true, "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "startLine": 153, "originalLine": 152, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNjoxOTo1MVrOPzmkYQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OJAG"}, {"id": "PRRC_kwDOABGHUc4_OaRh"}]}}, {"id": "PRRT_kwDOABGHUc4od2JE", "isResolved": true, "isOutdated": false, "isCollapsed": true, "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "startLine": 28, "originalLine": 27, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNTowNTowNVrOPziSuQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OJK5"}]}}, {"id": "PRRT_kwDOABGHUc4od2SP", "isResolved": true, "isOutdated": false, "isCollapsed": true, "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/MockMvcResultMatchersDsl.kt", "startLine": 151, "originalLine": 150, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNTowNjowNlrOPziWPg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OJY-"}]}}, {"id": "PRRT_kwDOABGHUc4od2TS", "isResolved": true, "isOutdated": false, "isCollapsed": true, "path": "spring-test/src/main/kotlin/org/springframework/test/web/servlet/ResultActionsDsl.kt", "startLine": 26, "originalLine": 25, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "simonbasle"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMy0wMS0wM1QxNTowNjoxNVrOPziWoA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4_OJag"}]}}]}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU5NzcwNzcyNTQ=", "number": 27317, "url": "https://github.com/spring-projects/spring-framework/issues/27317", "title": "Introduce Kotlin DSL for `ResultActions.andExpectAll()`", "body": "## Overview\r\n\r\nCommit dd9b99e13d6b30462fb168799e6bbca1456123da introduced `ResultActions.andExpectAll()` to support _soft assertions_ in `MockMvc`.\r\n\r\n`ResultActionsDsl.kt` already has support for `andExpect()`.\r\n\r\n\r\n## Related Issues\r\n\r\n- #27318\r\n\r\n## Deliverables\r\n\r\n- [x] Introduce Kotlin support for `ResultActions.andExpectAll()` in `ResultActionsDsl.kt`. => #29727 \r\n- [x] Add a Kotlin example using `andExpectAll()` in the reference manual alongside the Java example introduced in dd9b99e13d6b30462fb168799e6bbca1456123da. => #29766 ", "state": "CLOSED", "labels": {"totalCount": 5, "pageInfo": {"hasNextPage": false, "endCursor": "NQ"}, "nodes": [{"name": "in: test"}, {"name": "in: web"}, {"name": "type: enhancement"}, {"name": "status: superseded"}, {"name": "theme: kotlin"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOU44UFw=="}, "nodes": [{"id": "IC_kwDOABGHUc5TjhQX", "author": {"login": "sbrannen"}, "body": "- Superseded by #29727", "createdAt": "2023-01-24T11:58:26Z", "updatedAt": "2023-01-24T11:58:26Z"}]}}]}} +{"id": "PR_kwDOABGHUc5Dh0s_", "title": "Restrict forwards in MockMvcWebConnection to 100", "body": "When a filter is configured to conditionally forward, and it is configured to handle FORWARD dispatches as well, and it prevents infinite forward loops by either extending OncePerRequestFilter or otherwise using request attributes, this can result in infinite forward loops in WebClient tests using MockMvcWebConnection. This change will restrict the maximum number of forwards in MockMvcWebConnection to 100.\r\n\r\nCloses gh-29483", "number": 29557, "url": "https://github.com/spring-projects/spring-framework/pull/29557", "author": {"login": "manthanb"}, "createdAt": "2022-11-23T06:38:01Z", "mergedAt": "2023-02-07T15:23:56Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "ed5ab77397e773cfce3b17d00ceb8e84b0581aab", "baseRefName": "main", "headRefOid": "56b5ec243063a2cc8acb8ba797b8058b422edab5", "headRefName": "main", "changedFiles": 3, "labels": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "NA"}, "nodes": [{"name": "in: test"}, {"name": "status: backported"}, {"name": "in: web"}, {"name": "type: enhancement"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "19d5c7f44a58c414614ecbae38728aaca02e159f", "message": "Restrict forwards in MockMvcWebConnection to 100\n\nWhen a filter is configured to conditionally forward, and it is\nconfigured to handle FORWARD dispatches as well, and it prevents\ninfinite forward loops by either extending OncePerRequestFilter or\notherwise using request attributes, this can result in infinite\nforward loops in WebClient tests using MockMvcWebConnection. This\nchange will restrict the maximum number of forwards in\nMockMvcWebConnection to 100.\n\nCloses gh-29483", "changedFilesIfAvailable": 3, "authoredDate": "2022-11-23T06:28:08Z", "author": {"user": null}, "committedDate": "2022-11-23T06:35:41Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "ed5ab77397e773cfce3b17d00ceb8e84b0581aab"}]}}}, {"commit": {"oid": "56b5ec243063a2cc8acb8ba797b8058b422edab5", "message": "Polish contribution: throw exception rather than fallback", "changedFilesIfAvailable": 2, "authoredDate": "2023-02-07T14:55:31Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-02-07T14:55:31Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "19d5c7f44a58c414614ecbae38728aaca02e159f"}]}}}]}, "reviews": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMi0wN1QyMzoxOTo0NyswODowMLkyMDIzLTAyLTA3VDIzOjE5OjQ3KzA4OjAwzky69PE="}, "nodes": [{"id": "PRR_kwDOABGHUc5LWYG-", "author": {"login": "simonbasle"}, "state": "CHANGES_REQUESTED", "body": "@manthanb thanks for the contribution. I think that throwing an exception as proposed in the original issue would be better, wdyt? The message can mention that there is a probable infinite loop and that it forwarded 100 times.", "submittedAt": "2023-01-20T18:40:12Z", "updatedAt": "2023-01-20T18:40:13Z", "commit": {"oid": "19d5c7f44a58c414614ecbae38728aaca02e159f"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5MuvTx", "author": {"login": "simonbasle"}, "state": "APPROVED", "body": "I went ahead and made the adjustments to throw rather than ignore", "submittedAt": "2023-02-07T15:19:47Z", "updatedAt": "2023-02-07T15:19:47Z", "commit": {"oid": "56b5ec243063a2cc8acb8ba797b8058b422edab5"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5WViJl", "number": 29483, "url": "https://github.com/spring-projects/spring-framework/issues/29483", "title": "Possible infinite forward loop with MockMvcWebConnection", "body": "When a filter is configured to conditionally forward, and it is configured to handle FORWARD dispatches as well, and it prevents infinite forward loops by either extending `OncePerRequestFilter` or otherwise using request attributes, this can result in infinite forward loops in `WebClient` tests using `MockMvcWebConnection`. Because in this case request attributes are not propagated from the original request to the forwards.\r\n\r\nExample `RequireSettingFilter`:\r\n```java\r\n@Component\r\npublic class RequireSettingFilter extends OncePerRequestFilter {\r\n\r\n\t@Override\r\n\tprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {\r\n\t\tif (System.getProperty(\"mysetting\") == null) {\r\n\t\t\trequest.getRequestDispatcher(\"/error/missingsetting\").forward(request, response);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tfilterChain.doFilter(request, response);\r\n\t}\r\n}\r\n```\r\n\r\n`RedirectTest`:\r\n```java\r\n@WebMvcTest\r\npublic class RedirectTest {\r\n\t@Autowired\r\n\tWebClient webClient;\r\n\r\n\t@Test\r\n\tvoid testForwardToError() throws FailingHttpStatusCodeException, MalformedURLException, IOException {\r\n\t\tHtmlPage page = webClient.getPage(\"/demo.html\");\r\n\t\tassertEquals(\"A demo\", page.asNormalizedText());\r\n\t}\r\n}\r\n```\r\n\r\nSuggested fix: In `org.springframework.test.web.servlet.htmlunit.MockMvcWebConnection.getResponse(WebRequest)` forwards are handled. Limit this to e.g. 100 forwards and afterwards throw an exception that the page is not forwarding properly. Infinite loops are very bad, because they can make the build system hang.\r\n\r\nNote that just copying request attributes from the original request to the new one wouldn't help for the case of `OncePerRequestFilter`, because it clears the attributes when exiting `doFilterInternal(...)`.\r\n\r\n**Affects:** 5.3.23\r\n", "state": "CLOSED", "labels": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "NA"}, "nodes": [{"name": "in: test"}, {"name": "status: backported"}, {"name": "in: web"}, {"name": "type: enhancement"}]}, "comments": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOVCSlMw=="}, "nodes": [{"id": "IC_kwDOABGHUc5TX8Z3", "author": {"login": "simonbasle"}, "body": "Once the forward happens, if the filter also apply to the forward destination it is applied on a distinct request. I'm not entirely sure if this is specific to MockMvc's `MockRequestDispatchHandler` or if it is true of more `RequestDispatcher`s \ud83e\udd14\r\n\r\nUnlike other MockMVC parts, `MockMvcWebConnection` is really trying to get to some HTML for the benefit of `HtmlUnit` and as such does follow these forwards.\r\nSo it can end up in an infinite loop if the forwarding filter applies to both original request and forwarded request. I agree that being defensive there is an enhancement.\r\n\r\nPerhaps there is more area of improvement (`MockRequestDispatcherHandler` not setting the `DispatcherType` to `FORWARD` for instance) , but this is a good first step.", "createdAt": "2023-01-20T18:36:59Z", "updatedAt": "2023-01-20T18:36:59Z"}, {"id": "IC_kwDOABGHUc5Tcuag", "author": {"login": "svschouw-bb"}, "body": "Setting the dispatch type to `FORWARD` might help, but I think you would need to handle all the [forward attributes](https://javaee.github.io/servlet-spec/downloads/servlet-3.1/Final/servlet-3_1-final.pdf#G13.999505) then as well. If you would really like to do it correctly you'd need a `RequestDispatcher` that actually handles the forward instead of setting a `forwardedUrl` parameter. But I think this is where the `MockMvc` case really differs from the `MockMvcWebConnection`. With `MockMvc` you want to do a single request and see that it did a forward. With `MockMvcWebConnection` you want to see the entire result of the request.\r\n\r\nBut in my opinion this ticket is mostly just about avoiding the infinite loop. If you really want to do some advanced integration testing, it's probably better to use Spring Boot's `@SpringBootTest(webEnvironment=RANDOM_PORT)` or something.", "createdAt": "2023-01-23T09:32:48Z", "updatedAt": "2023-01-23T09:32:48Z"}, {"id": "IC_kwDOABGHUc5UJKUz", "author": {"login": "simonbasle"}, "body": "Superseded by gh-29557", "createdAt": "2023-02-01T08:56:27Z", "updatedAt": "2023-02-01T08:56:27Z"}]}}]}} +{"id": "PR_kwDOABGHUc4-qR6t", "title": "Protect JMS connection creation against prepareConnection errors", "body": "The creation of new JMS connection (after reset) is done in local method field (instead of instance field directly) to prevent situation, when connection is not correctly configured/prepared in case when JMSException from prepare() method is thrown.\r\n\r\nSee gh-29115", "number": 29116, "url": "https://github.com/spring-projects/spring-framework/pull/29116", "author": {"login": "lenoch7"}, "createdAt": "2022-09-09T08:28:40Z", "mergedAt": "2023-02-28T15:10:06Z", "mergedBy": {"login": "simonbasle"}, "baseRefOid": "858394b72055018e315599f4292201f9a70c7ec4", "baseRefName": "main", "headRefOid": "991b51e0abdd140786a1e6fcf71f4e6b8af71dbc", "headRefName": "SingleConnectionFactory-Reconnection", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: messaging"}, {"name": "type: bug"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "76f31e8fe3109f726f934d04612cff83c2af252a", "message": "Fix creation of new JMS connection\n\nThe creation of new JMS connection (after reset) is done in local\nmethod field (instead of instance field directly) to prevent\nsituation, when connection is not correctly configured/prepared in\ncase when JMSException from prepare() method is thrown.\n\nSee gh-29115", "changedFilesIfAvailable": 2, "authoredDate": "2022-09-09T08:13:35Z", "author": {"user": {"login": "lenoch7"}}, "committedDate": "2022-12-16T07:51:09Z", "committer": {"user": {"login": "lenoch7"}}, "parents": {"nodes": [{"oid": "858394b72055018e315599f4292201f9a70c7ec4"}]}}}, {"commit": {"oid": "991b51e0abdd140786a1e6fcf71f4e6b8af71dbc", "message": "Polish log level and message", "changedFilesIfAvailable": 1, "authoredDate": "2023-02-28T15:05:09Z", "author": {"user": {"login": "simonbasle"}}, "committedDate": "2023-02-28T15:05:09Z", "committer": {"user": {"login": "simonbasle"}}, "parents": {"nodes": [{"oid": "76f31e8fe3109f726f934d04612cff83c2af252a"}]}}}]}, "reviews": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wMi0yOFQyMjoyMDowMSswODowMLkyMDIzLTAyLTI4VDIyOjIwOjAxKzA4OjAwzk6K3x4="}, "nodes": [{"id": "PRR_kwDOABGHUc5DNKGp", "author": {"login": "valituguran"}, "state": "COMMENTED", "body": "Looks good. ", "submittedAt": "2022-10-01T12:15:25Z", "updatedAt": "2022-10-01T12:15:25Z", "commit": null, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5Ml6wk", "author": {"login": "simonbasle"}, "state": "COMMENTED", "body": "LGTM @jhoeller what do you think?", "submittedAt": "2023-02-06T11:22:42Z", "updatedAt": "2023-02-28T14:19:12Z", "commit": {"oid": "76f31e8fe3109f726f934d04612cff83c2af252a"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5Oit8e", "author": {"login": "simonbasle"}, "state": "APPROVED", "body": "", "submittedAt": "2023-02-28T14:20:01Z", "updatedAt": "2023-02-28T14:20:01Z", "commit": {"oid": "76f31e8fe3109f726f934d04612cff83c2af252a"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5Rgb4o", "number": 29115, "url": "https://github.com/spring-projects/spring-framework/issues/29115", "title": "SingleConnectionFactory - reconnection problem (AMQ Broker)", "body": "I have a problem with reconnection when `SingleConnectionFactory` (`CachingConnectionFactory`) is used.\r\nI think it is a similar (or same?) problem reported in #23058 issue.\r\n\r\nFrom all sources, which I have (logs, heap dump ...), it seems that problem is caused due **missing Exception Listener\r\non connection (`ActiveMQConnection`), which is stored on `SingleConnectionFactory`**.\r\n\r\nI have following environment:\r\n- Apache ActiveMQ Broker 5.16.2\r\n- `failover:(tcp://localhost:61616)?maxReconnectAttempts=5`\r\n- `SingleConnectionFactory` (`CachingConnectionFactory`)\r\n - `setReconnectOnException(true)`\r\n\r\n###### Logs\r\n- it is visible that \"resetting the underlying JMS Connection\" on `CachingConnectionFactory` is invoked\r\n- but suddenly these logs are no longer present and only logs from `DefaultMessageListenerContainer` are present\r\n - I know that it is not recommended to use DMLC with `CachingConnectionFactory`, but please stay with me for a moment (because I think the problem is in `SingleConnectionFactory`)\r\n\r\n```\r\n2022-09-06T05:16:06.024+00:00 {ActiveMQ Connection Executor: unconnected} [CachingConnectionFactory] [INFO] Encountered a JMSException - resetting the underlying JMS Connection\r\n...\r\n2022-09-06T05:18:37.210+00:00 {ActiveMQ Connection Executor: unconnected} [CachingConnectionFactory] [INFO] Encountered a JMSException - resetting the underlying JMS Connection\r\n...\r\n2022-09-06T05:21:08.254+00:00 {ActiveMQ Connection Executor: unconnected} [CachingConnectionFactory] [INFO] Encountered a JMSException - resetting the underlying JMS Connection\r\n...\r\n2022-09-06T05:23:39.319+00:00 {ActiveMQ Connection Executor: unconnected} [CachingConnectionFactory] [INFO] Encountered a JMSException - resetting the underlying JMS Connection\r\n...\r\n2022-09-06T05:26:15.367+00:00 {ActiveMQ Connection Executor: unconnected} [CachingConnectionFactory] [INFO] Encountered a JMSException - resetting the underlying JMS Connection\r\n...\r\n2022-09-06T05:26:25.498+00:00 {taskExecutor-151} [DefaultMessageListenerContainer] [ERROR] Could not refresh JMS Connection for destination '...' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: The JMS connection has failed: ...cluster.local\r\n2022-09-06T05:26:30.499+00:00 {taskExecutor-151} [DefaultMessageListenerContainer] [ERROR] Could not refresh JMS Connection for destination '...' - retrying using FixedBackOff{interval=5000, currentAttempts=2, maxAttempts=unlimited}. Cause: The JMS \r\n...\r\n2022-09-06T05:46:30.559+00:00 {taskExecutor-142} [DefaultMessageListenerContainer] [ERROR] Could not refresh JMS Connection for destination '...' - retrying using FixedBackOff{interval=5000, currentAttempts=242, maxAttempts=unlimited}. Cause: The JMS connection has failed: ...cluster.local\r\n2022-09-06T05:46:35.559+00:00 {taskExecutor-151} [DefaultMessageListenerContainer] [ERROR] Could not refresh JMS Connection for destination '...' - retrying using FixedBackOff{interval=5000, currentAttempts=243, maxAttempts=unlimited}. Cause: The JMS connection has failed: ...cluster.local\r\n...\r\n```\r\n###### HeapDump\r\n- I see only one `CachingConnectionFactory`\r\n - I see `SingleConnectionFactory$AggregatedExceptionListener` in `aggregatedExceptionListener`\r\n - I see `ActiveMQConnection` under `connection` field\r\n - I see that `exceptionListener` (on `ActiveMQConnection`) is `null` (ExceptionListener is missing - but this exception listener must be present to invoke reset of underlying JMS Connection stored on `SingleConnectionFactory`)\r\n - I see that `transportFailed` (on `ActiveMQConnection`) is `true` (it is a probably a reason why ExceptionListener is missing, see bellow)\r\n - I see that `firstFailureError` (on `ActiveMQConnection`) is `java.net.UnknownHostException` (but type of the failure is not too important)\r\n\r\n###### Debugger\r\n- I am able to simulate the problem in debugger\r\n- It is enough to \"delay\" thread, which invokes `SingleConnectionFactory.initConnection()`\r\n - after new connection is created\r\n - but before connection is prepared, where exception listener is established\r\n\r\n###### Code (`SingleConnectionFactory.initConnection()`)\r\n```\r\npublic void initConnection() throws JMSException {\r\n\tif (getTargetConnectionFactory() == null) {\r\n\t\tthrow new IllegalStateException(\r\n\t\t\t\t\"'targetConnectionFactory' is required for lazily initializing a Connection\");\r\n\t}\r\n\tsynchronized (this.connectionMonitor) {\r\n\t\tif (this.connection != null) {\r\n\t\t\tcloseConnection(this.connection);\r\n\t\t}\r\n\t\tthis.connection = doCreateConnection();\r\n\t\tprepareConnection(this.connection);\r\n\t\tif (this.startedCount > 0) {\r\n\t\t\tthis.connection.start();\r\n\t\t}\r\n\t\tif (logger.isDebugEnabled()) {\r\n\t\t\tlogger.debug(\"Established shared JMS Connection: \" + this.connection);\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\n##### Why ExceptionListener on JMS Connection stored on `SingleConnectionFactory` is missing?\r\n- please suppose following situation\r\n - the new connection is created successfully (`this.connection = doCreateConnection();`)\r\n - but some of subsequent methods (in my case `prepareConnection(this.connection)`) throws `JMSException`\r\n - we get new connection (stored on `SingleConnectionFactory`), but without JMS Exception Listener\r\n - this finally caused, that `SingleConnectionFactory.resetConnection()` is never invoked and \"invalid\" connection stays stored on `SingleConnectionFactory` (till restart or \"manual\" invocation of `SingleConnectionFactory.resetConnection()`)\r\n\r\nI know it is (nearly) impossible to get this situation, because setup of exception listener (in `prepareConnection(Connection)`) should be (nearly) always done before invocation of `ActiveMQConnection.onException(IOException)` method, which sets `transportFailed` and `firstFailureError`, which finally caused that `ActiveMQConnection.setExceptionListener(ExceptionListener)` (invoked in `prepareConnection(this.connection)`) throws `ConnectionFailedException`, but I see this state in application heap dump (I am sorry).\r\n\r\nMy proposal is to change `SingleConnectionFactory.initConnection()` in a way, when new connection is created and configured/prepared in method local field and when all is ok, then assign it to instance connection field. Something like this:\r\n```\r\npublic void initConnection() throws JMSException {\r\n\t...\r\n\tsynchronized (this.connectionMonitor) {\r\n\t\tif (this.connection != null) {\r\n\t\t\tcloseConnection(this.connection);\r\n\t\t}\r\n\t\tConnection con = doCreateConnection();\r\n\t\ttry {\r\n\t\t\tprepareConnection(con);\r\n\t\t\tthis.connection = con;\r\n\t\t}\r\n\t\tcatch (JMSException ex) {\r\n\t\t\ttry {\r\n\t\t\t\t con.close();\r\n\t\t\t}\r\n\t\t\tcatch(Throwable th) {\r\n\t\t\t\tlogger.warn(\"Could not close new (but not used as shared) JMS Connection\", th);\r\n\t\t\t}\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t\tif (this.startedCount > 0) {\r\n\t\t\tthis.connection.start();\r\n\t\t}\r\n\t\t...\r\n\t}\r\n}\r\n```\r\n", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: messaging"}, {"name": "status: backported"}, {"name": "type: bug"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOVlMHKg=="}, "nodes": [{"id": "IC_kwDOABGHUc5WUwcq", "author": {"login": "simonbasle"}, "body": "Superseded by gh-29116", "createdAt": "2023-02-28T14:29:03Z", "updatedAt": "2023-02-28T14:29:03Z"}]}}]}} +{"id": "PR_kwDOABGHUc41-xac", "title": "Avoid duplicate `ApplicationListener` firing (proxy vs. target)", "body": "In `AbstractApplicationEventMulticaster.retrieveApplicationListeners`, despite best efforts to avoid it, unwrapped proxies (singleton targets) can end up in the list of programmatically registered listeners. In order to avoid duplicates, we need to find and replace them by their proxy counterparts, because if both a proxy and its target end up in `allListeners`, listeners will fire twice.\r\n\r\nFixes #28283.", "number": 28322, "url": "https://github.com/spring-projects/spring-framework/pull/28322", "author": {"login": "kriegaex"}, "createdAt": "2022-04-11T07:53:12Z", "mergedAt": "2023-10-10T15:01:00Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "efb6abc43f550c2be20f39ad9ce65346ee5ebd65", "baseRefName": "main", "headRefOid": "0dba415171294487b642c84084ef0207cc60988d", "headRefName": "issue-28283", "changedFiles": 7, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "type: bug"}, {"name": "in: core"}]}, "commits": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"commit": {"oid": "5367d96e8dddb5365cb8b0443dace852f0489bed", "message": "Regression test for duplicate firing of proxied application listeners\n\nApplicationContextEventTests.eventForSelfInjectedProxiedListenerFiredOnlyOnce\nrelates to and reproduces #28283.", "changedFilesIfAvailable": 6, "authoredDate": "2023-07-19T01:45:45Z", "author": {"user": {"login": "kriegaex"}}, "committedDate": "2023-07-21T02:46:47Z", "committer": {"user": {"login": "kriegaex"}}, "parents": {"nodes": [{"oid": "0d8a8432d18af8d2a5fcb29f9de40e4cbf0f9016"}]}}}, {"commit": {"oid": "0dba415171294487b642c84084ef0207cc60988d", "message": "Avoid duplicate application listeners (proxy vs. proxy target)\n\nIn AbstractApplicationEventMulticaster.retrieveApplicationListeners,\ndespite best efforts to avoid it, unwrapped proxies (singleton targets)\ncan end up in the list of programmatically registered listeners. In\norder to avoid duplicates, we need to find and replace them by their\nproxy counterparts, because if both a proxy and its target end up in\n'allListeners', listeners will fire twice.\n\nFixes #28283.", "changedFilesIfAvailable": 1, "authoredDate": "2022-04-11T07:51:04Z", "author": {"user": {"login": "kriegaex"}}, "committedDate": "2023-07-21T02:46:47Z", "committer": {"user": {"login": "kriegaex"}}, "parents": {"nodes": [{"oid": "5367d96e8dddb5365cb8b0443dace852f0489bed"}]}}}]}, "reviews": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpO5MjAyMy0wOC0yM1QxNzoyMDozMiswODowMLkyMDIzLTA4LTIzVDE3OjIwOjMyKzA4OjAwzl7W-ZY="}, "nodes": [{"id": "PRR_kwDOABGHUc5atdkq", "author": {"login": "sbrannen"}, "state": "CHANGES_REQUESTED", "body": "Hi @kriegaex,\r\n\r\nApologies for the belated review. This one slipped through the cracks.\r\n\r\nCan you please introduce a test that fails before the change and passes afterwards?\r\n\r\nThanks", "submittedAt": "2023-07-10T11:29:24Z", "updatedAt": "2023-07-10T11:29:24Z", "commit": null, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc5e1vmW", "author": {"login": "sbrannen"}, "state": "APPROVED", "body": "Thanks for adding the failing test. That helps a lot!", "submittedAt": "2023-08-23T09:20:32Z", "updatedAt": "2023-08-23T09:20:32Z", "commit": {"oid": "0dba415171294487b642c84084ef0207cc60988d"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}]}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc5HDETI", "number": 28283, "url": "https://github.com/spring-projects/spring-framework/issues/28283", "title": "Using AOP and DI itself causes Spring ApplicationListener to be fired twice ", "body": "## Software versions\r\n\r\n- Spring Version 5.3.18 and earlier \r\n- JDK Version 1.8.0_202\r\n\r\n## Overview\r\n\r\nWhen I use Spring ApplicationListener, in order to prevent transaction invalidation, my ApplicationListener implementation class writes the following code (of course, the code can be written differently to avoid this problem), which will cause my listener to trigger twice after the event is published. I think it's not normal, but not sure if it's a bug, so I want to ask everyone's opinion.\r\n\r\n```java\r\n@Component\r\npublic class EventDemoListener implements ApplicationListener {\r\n @Autowired\r\n DemoService1 demoService1;\r\n @Autowired\r\n DemoService2 demoService2;\r\n @Autowired\r\n EventDemoListener eventDemoListener;\r\n\r\n @Override\r\n public void onApplicationEvent(EventDemo event) {\r\n eventDemoListener.testTransaction();\r\n System.out.println(\"receiver \" + event.getMessage());\r\n }\r\n\r\n @Transactional(rollbackFor = Exception.class)\r\n public void testTransaction() {\r\n demoService1.doService();\r\n demoService2.doService();\r\n }\r\n}\r\n```\r\nThrough this demo project, this problem can be reproduced. Please read the README.md document before running. \r\n[https://github.com/ZiFeng-Wu/spring-study](https://github.com/ZiFeng-Wu/spring-study)\r\n\r\n## Analysis\r\n\r\n1. After analysis, because here DI itself , When `EventDemoListener` is created, property filling will trigger `DefaultSingletonBeanRegistry#getSingleton(String, boolean)` in advance.\r\n\r\n2. Then `singletonFactory.getObject()` executed in `getSingleton()` will cause the unproxyed `EventDemoListener` object to be put into `AbstractAutoProxyCreator#earlyProxyReferences`.\r\n\r\n3. After the properties are filled, calling `AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)` and executing `ApplicationListenerDetector#postProcessAfterInitialization(Object, String)` will cause the unproxyed `EventDemoListener` object to be put into the `AbstractApplicationEventMulticaster.DefaultListenerRetriever#applicationListeners` container.\r\n\r\n [![enter image description here][1]][1]\r\n\r\n4. Then when the event is published, execute `AbstractApplicationEventMulticaster.DefaultListenerRetriever#getApplicationListeners()` and use `ApplicationListener listener =beanFactory.getBean(listenerBeanName, ApplicationListener.class)` to obtain the listener is the proxied `EventDemoListener` object.\r\n\r\n5. At this time, there are only unproxyed `EventDemoListener` object in the `applicationListeners` container, so the proxied `EventDemoListener` object will be added to the final returned allListeners collection, as shown in the figure below, which will eventually cause the listener to be triggered twice.\r\n\r\n [![enter image description here][2]][2]\r\n\r\n\r\n [1]: https://i.stack.imgur.com/lz51c.png\r\n [2]: https://i.stack.imgur.com/oZ8OA.png\r\n", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "type: bug"}, {"name": "in: core"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 6, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOYRXB-A=="}, "nodes": [{"id": "IC_kwDOABGHUc5BPgnE", "author": {"login": "kriegaex"}, "body": "I looked into this issue too, because the [same question](https://stackoverflow.com/q/71775299/1082681) was asked on Stack Overflow. Only later I found it here, because I also just wanted to raise an issue for it.\r\n\r\nActually, this not only happens for this rather strange scenario using both self-injection and `@Transactional` from within the `ApplicationListener` implementation, but in other cases where listener is being proxied, too, for example if it is the target of a Spring AOP `@Aspect`. This is a fact, not pure speculation. I tried, and the result is the same.\r\n\r\nAs for the root cause: In `AbstractApplicationEventMulticaster.retrieveApplicationListeners`, there are two loops searching for listeners. The first one finds the original listener, the second one finds the bean, which yields a proxy instance.\r\n\r\nhttps://github.com/spring-projects/spring-framework/blob/c9e781676271a980d39063fc1f23a348b0d37be1/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java#L224-L232\r\n\r\nThis would be relatively easy to remedy,\r\n * either by checking `allListeners` for duplicates after both loops have finished\r\n * or by checking for existing non-proxy elements upon inserting in the loop checking registered beans.\r\n\r\nDuplicates in this context could be identified by `AopProxyUtils.getSingletonTarget(listener)`.\r\n\r\nHow about this?\r\n\r\n```patch\r\n--- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java\t(revision Staged)\r\n+++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java\t(date 1649655053343)\r\n@@ -260,8 +260,9 @@\r\n \t\t\tfor (String listenerBeanName : listenerBeans) {\r\n \t\t\t\ttry {\r\n \t\t\t\t\tif (supportsEvent(beanFactory, listenerBeanName, eventType)) {\r\n-\t\t\t\t\t\tApplicationListener listener =\r\n-\t\t\t\t\t\t\t\tbeanFactory.getBean(listenerBeanName, ApplicationListener.class);\r\n+\t\t\t\t\t\tApplicationListener listener = (ApplicationListener) AopProxyUtils.getSingletonTarget(\r\n+\t\t\t\t\t\t\tbeanFactory.getBean(listenerBeanName, ApplicationListener.class)\r\n+\t\t\t\t\t\t);\r\n \t\t\t\t\t\tif (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {\r\n \t\t\t\t\t\t\tif (retriever != null) {\r\n \t\t\t\t\t\t\t\tif (beanFactory.isSingleton(listenerBeanName)) {\r\n```\r\n\r\nThis fixes the problem, at least in this context. It might cause problems elsewhere, please verify. If this is OK, would you like to have a PR? If so, for which branch? _5.3.x_ or _main_? Maybe I could create a PR for _main_ and a committer could back-port it to all relevant versions which still get updates.\r\n\r\nActually, in the same class there is some proxy unwrapping going on in another place already, seemingly in order to **avoid** getting unwrapped objects into the list of listeners, which is the opposite of what my patch does. Hmm...\r\n\r\nhttps://github.com/spring-projects/spring-framework/blob/c9e781676271a980d39063fc1f23a348b0d37be1/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java#L106-L111\r\n\r\n**Edit:** I just debugged into that code, and it is called indirectly via `AbstractBeanFactory.getBean(String)` and `AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])`, as you can see here:\r\n\r\n![image](https://user-images.githubusercontent.com/1537384/162677617-ef2336be-16c1-4313-866e-fa8a6678c2ab.png)\r\n\r\nIf you look at the variables in the top stack frame, you see that in `AbstractApplicationEventMulticaster.addApplicationListener(ApplicationListener)` the method parameter `listener` is an unwrapped bean, but at the same time the proxy exists already, as can be seen when inspecting the value of `listener.eventDemoListener` (the auto-wired self-reference). So along the way, somehow the proxy gets lost or is never retrieved. I.e., the logic in `addApplicationListener` cannot avoid the unwrapped listener to be added to the list, because what it sees is unwrapped already. I.e., my workaround in the patch above to also unwrap the bean is something that might cause duplicate calls in other situations when `addApplicationListener` really does get called with a proxy instance. Then it would not unwrap it, but in the beans list we would have an unwrapped object due to my patch. \r\n\r\nIn which way ever this problem is going to be solved, it would be important to either never or always unwrap proxies in order to avoid effective duplicates. To always unwrap would be safe, because unwrapping is always possible, but determining if there is a proxy for the method parameter in `addApplicationListener` elsewhere is not easily possible. Another workaround would be to make sure that `addApplicationListener` is never called with an unwrapped object in the first place, if a proxy exists. But how to ensure that, is beyond my knowledge.", "createdAt": "2022-04-11T06:03:32Z", "updatedAt": "2022-04-11T06:38:23Z"}, {"id": "IC_kwDOABGHUc5BPzqa", "author": {"login": "kriegaex"}, "body": "I think I found a better, more universal solution and created a PR:\r\n\r\nhttps://github.com/spring-projects/spring-framework/blob/1da3022c27a928988758a5f6bc43913f19eccccf/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java#L266-L281\r\n\r\nI am confident that this is going to work. There might be a way to avoid the proxy targets (unwrapped objects) in the listeners list in the first place, but this method cannot rely on it, as we can see in this issue. So this more defensively implemented solution should be OK.", "createdAt": "2022-04-11T07:46:01Z", "updatedAt": "2022-04-11T08:20:13Z"}, {"id": "IC_kwDOABGHUc5hFTc7", "author": {"login": "sbrannen"}, "body": "- superseded by PR #28322", "createdAt": "2023-07-10T11:30:55Z", "updatedAt": "2023-07-10T11:30:55Z"}, {"id": "IC_kwDOABGHUc5hFXo8", "author": {"login": "kriegaex"}, "body": "@sbrannen: How can a bug be superseded by a PR? After the PR will eventually get merged, it ought to close the bug. I think it is bad practice to close a bug before a fix is in place. Maybe you want to reopen for the time being?", "createdAt": "2023-07-10T11:42:46Z", "updatedAt": "2023-07-10T11:42:46Z"}, {"id": "IC_kwDOABGHUc5hFYrQ", "author": {"login": "sbrannen"}, "body": "> @sbrannen: How can a bug be superseded by a PR? After the PR will eventually get merged, it ought to close the bug. I think it is bad practice to close a bug before a fix is in place. \r\n\r\nThat's our policy: in order to keep the number of open \"issues\" to a minimum, we close an issue as superseded by a PR that addresses the topic.\r\n\r\n> Maybe you want to reopen for the time being?\r\n\r\nIf the PR turns out not to address the issue, the original issue can be reopened after the PR is closed.", "createdAt": "2023-07-10T11:45:34Z", "updatedAt": "2023-07-10T11:45:34Z"}, {"id": "IC_kwDOABGHUc5hFcH4", "author": {"login": "kriegaex"}, "body": "Oh, OK. Thanks for the explanation. Most OSS projects always have pairs of issues and PRs addressing them. Some, like Apache, even enforce it. Spring's policy is rather exotic and kind of counter-intuitive, especially given the fact that my PR contains a comment \"fixes [issue id]\", which would have closed this issue automatically after a merge. This GitHub feature is also rendered useless by the policy currently in place. But of course, strange as it might seem to me, I am going to stick to it.\r\n\r\n> If the PR turns out not to address the issue, the original issue can be reopened after the PR is closed.\r\n\r\nThat is kind of an extra effort, is it not? Anyway, if you prefer it this way, I can live with it.", "createdAt": "2023-07-10T11:55:43Z", "updatedAt": "2023-07-10T11:56:48Z"}]}}]}} +{"id": "PR_kwDOABGHUc4vCfDx", "title": "DataAccessUtils result accessors with Optional return value", "body": "Closes #27728\r\n(https://github.com/spring-projects/spring-framework/issues/27728)\r\n\r\nHi everyone, this is my first PR in any project here on github with the goal of improving my understanding of java. Hope i understood the enhancement request correctly.", "number": 27735, "url": "https://github.com/spring-projects/spring-framework/pull/27735", "author": {"login": "KaidosGH"}, "createdAt": "2021-11-26T00:46:59Z", "mergedAt": "2023-07-14T09:37:09Z", "mergedBy": {"login": "jhoeller"}, "baseRefOid": "2f32806bcb6cefa6479074d5fb66cb68043cedc9", "baseRefName": "main", "headRefOid": "1891fa45b5d43a3741905531f8b84944a7c820e0", "headRefName": "feature/extendDataAccessUtils", "changedFiles": 2, "labels": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Mg"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}]}, "commits": {"nodes": [{"commit": {"oid": "f86cf085cd38933189a5d126a6bd6db3966da515", "message": "extend DataAccessUtils", "changedFilesIfAvailable": 2, "authoredDate": "2021-11-26T00:02:33Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-26T00:02:33Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "2f32806bcb6cefa6479074d5fb66cb68043cedc9"}]}}}, {"commit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d", "message": "cleanup", "changedFilesIfAvailable": 2, "authoredDate": "2021-11-26T00:26:21Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-26T00:26:21Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "f86cf085cd38933189a5d126a6bd6db3966da515"}]}}}, {"commit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123", "message": "optimize imports, refactor iterator usage", "changedFilesIfAvailable": 2, "authoredDate": "2021-11-26T19:19:55Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-26T19:19:55Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}]}}}, {"commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43", "message": "close streams properly with try-with-resource", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-27T13:48:41Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-27T13:48:41Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}]}}}, {"commit": {"oid": "1e7d103ef28d2d71953b538b1af3d695b0333f6f", "message": "Update spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\r\n\r\nre-use newly added singleResult methods\n\nCo-authored-by: Vigneswaran ", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T03:02:07Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T03:02:07Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}]}}}, {"commit": {"oid": "6522003c31a7217a57f7072157c005633c09829b", "message": "Update spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\r\n\r\nre-use newly added singleResult methods\n\nCo-authored-by: Vigneswaran ", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T03:02:16Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T03:02:16Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "1e7d103ef28d2d71953b538b1af3d695b0333f6f"}]}}}, {"commit": {"oid": "4ee08be619d964efaac39345699aa97fdeadf5f5", "message": "Update spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\r\n\r\nre-use newly added singleResult methods\n\nCo-authored-by: Vigneswaran ", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T03:02:24Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T03:02:24Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "6522003c31a7217a57f7072157c005633c09829b"}]}}}, {"commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f", "message": "fix closing bracket", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T03:03:17Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T03:03:17Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "4ee08be619d964efaac39345699aa97fdeadf5f5"}]}}}, {"commit": {"oid": "9206303d453566cd040d1014aad8cbdc78e56387", "message": "Update spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\r\n\r\nuse \"public IncorrectResultSizeDataAccessException(int expectedSize)\" in stream and iterator method\n\nCo-authored-by: Kwangyong Kim ", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T14:10:48Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T14:10:48Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}]}}}, {"commit": {"oid": "7c096e0683570f8fd99da129de25a80be5bf3e59", "message": "Update spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java\r\n\r\nuse \"public IncorrectResultSizeDataAccessException(int expectedSize)\" in stream and iterator method\n\nCo-authored-by: Vigneswaran ", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T14:10:56Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T14:10:56Z", "committer": {"user": null}, "parents": {"nodes": [{"oid": "9206303d453566cd040d1014aad8cbdc78e56387"}]}}}, {"commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0", "message": "update tests to correctly assert the thrown exception", "changedFilesIfAvailable": 1, "authoredDate": "2021-11-28T14:25:33Z", "author": {"user": {"login": "KaidosGH"}}, "committedDate": "2021-11-28T14:25:33Z", "committer": {"user": {"login": "KaidosGH"}}, "parents": {"nodes": [{"oid": "7c096e0683570f8fd99da129de25a80be5bf3e59"}]}}}], "totalCount": 11, "pageInfo": {"hasNextPage": false, "endCursor": null}}, "reviews": {"nodes": [{"id": "PRR_kwDOABGHUc4wr-Qy", "author": {"login": "marschall"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-26T14:10:06Z", "updatedAt": "2021-11-26T14:10:06Z", "commit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yNlQxNDoxMDowNVrOLSbvHA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tJu8c", "author": {"login": "marschall"}, "body": "Wouldn't it be better to do a\r\n\r\n .limit(2).toList()\r\n\r\nand then avoid opening the second stream and instead do\r\n\r\n resultList.get(0)", "createdAt": "2021-11-26T14:10:05Z", "updatedAt": "2021-11-26T14:10:06Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();", "line": null, "startLine": null, "originalLine": 78, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}}]}}, {"id": "PRR_kwDOABGHUc4wr-gv", "author": {"login": "marschall"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-26T14:11:12Z", "updatedAt": "2021-11-26T14:11:12Z", "commit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yNlQxNDoxMToxMlrOLSbyuw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tJvK7", "author": {"login": "marschall"}, "body": "Why a stream instead of just\r\n\r\n results.next()", "createdAt": "2021-11-26T14:11:12Z", "updatedAt": "2021-11-26T14:11:12Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();\n+\t\tif (resultList.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t}\n+\t\treturn resultList.stream().findFirst().orElse(null);\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tIterable iterable = () -> results;\n+\t\tList resultList = StreamSupport.stream(iterable.spliterator(), false).toList();", "line": null, "startLine": null, "originalLine": 100, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}}]}}, {"id": "PRR_kwDOABGHUc4wssv0", "author": {"login": "KaidosGH"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-26T19:27:57Z", "updatedAt": "2021-11-26T19:27:57Z", "commit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yNlQxOToyNzo1N1rOLSknLw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tKScv", "author": {"login": "KaidosGH"}, "body": "Hi @marschall,\r\n\r\nthanks for reviewing, sounds good, i refactored this. Does it make more sense now?\r\n\r\n`throw new IncorrectResultSizeDataAccessException(1, resultList.size());`\r\nas we limited the resultList size with .limit, this would not report the original passed Stream results size though but instead a maximum of 2... is that an issue?", "createdAt": "2021-11-26T19:27:57Z", "updatedAt": "2021-11-26T19:27:57Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();", "line": null, "startLine": null, "originalLine": 78, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tJu8c"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}}]}}, {"id": "PRR_kwDOABGHUc4wtGLF", "author": {"login": "marschall"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-27T12:03:41Z", "updatedAt": "2021-11-27T12:03:41Z", "commit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yN1QxMjowMzo0MVrOLSq4Pw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tKrg_", "author": {"login": "marschall"}, "body": "Yes, looks better to me.", "createdAt": "2021-11-27T12:03:41Z", "updatedAt": "2021-11-27T12:03:41Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +61,109 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.toList();", "line": null, "startLine": null, "originalLine": 78, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tJu8c"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "ff503c7f74eb26d0ee7383ca53856ec03467d10d"}}]}}, {"id": "PRR_kwDOABGHUc4wtGRd", "author": {"login": "marschall"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-27T12:09:49Z", "updatedAt": "2021-11-27T12:09:49Z", "commit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yN1QxMjowOTo0OVrOLSq6Ug=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tKrpS", "author": {"login": "marschall"}, "body": "There is a trade off here and in `#optionalResult` whether we should call `#close` on the stream:\r\n\r\nOn one hand Java convention is the code who creates a \"resource\" is responsible for disposing it, in this case the caller of this method would be responsible to call `#close` on the streams where required.\r\nOn the other hand failing to call `#close` on some streams, like the ones returned by `JdbcOperations#queryForStream`, can lead to resource leaks. Having the caller put streams in a try-with-resources block is both cumbersome and error prone.", "createdAt": "2021-11-27T12:09:49Z", "updatedAt": "2021-11-27T12:09:49Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,107 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.limit(2).toList();", "line": null, "startLine": null, "originalLine": 77, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}}]}}, {"id": "PRR_kwDOABGHUc4wtH0B", "author": {"login": "KaidosGH"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-27T13:56:23Z", "updatedAt": "2021-11-27T13:56:23Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yN1QxMzo1NjoyM1rOLSrezA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tKt7M", "author": {"login": "KaidosGH"}, "body": "Makes sense. The passed stream is now closed in both methods. Also e.g. hibernate's Query.stream() documentation suggests the stream should be closed afterwards, so not so far fetched \ud83d\udc4d ", "createdAt": "2021-11-27T13:56:23Z", "updatedAt": "2021-11-27T13:56:23Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,107 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tList resultList = results.limit(2).toList();", "line": null, "startLine": null, "originalLine": 77, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tKrpS"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "b98e7ad15d573bfa846d38b41b0661ae39c7f123"}}]}}, {"id": "PRR_kwDOABGHUc4wtQbp", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T02:37:54Z", "updatedAt": "2021-11-28T02:37:54Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMjozNzo1NFrOLSuiVg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6JW", "author": {"login": "rkvigneswaran"}, "body": "Would it be better if we delegate this to original `singleResult(Collection)` method?\r\n\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```", "createdAt": "2021-11-28T02:37:54Z", "updatedAt": "2021-11-28T02:39:00Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();", "line": null, "startLine": null, "originalLine": 123, "originalStartLine": 117, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}}]}}, {"id": "PRR_kwDOABGHUc4wtQeN", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T02:42:16Z", "updatedAt": "2021-11-28T02:42:16Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMjo0MjoxNVrOLSujhw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6OH", "author": {"login": "rkvigneswaran"}, "body": "Would it be better if we delegate this to newly added `singleResult(Stream)` method?\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```\r\n\r\n", "createdAt": "2021-11-28T02:42:15Z", "updatedAt": "2021-11-28T02:43:10Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));", "line": null, "startLine": null, "originalLine": 144, "originalStartLine": 136, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}}]}}, {"id": "PRR_kwDOABGHUc4wtQef", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T02:42:58Z", "updatedAt": "2021-11-28T02:42:58Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMjo0Mjo1OFrOLSujpQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6Ol", "author": {"login": "rkvigneswaran"}, "body": "Would it be better if we delegate this to newly added `singleResult(Iterator)` method?\r\n```suggestion\r\n\t\treturn Optional.ofNullable(singleResult(results));\r\n```\r\n\r\n", "createdAt": "2021-11-28T02:42:58Z", "updatedAt": "2021-11-28T02:42:58Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? Optional.empty() : Optional.of(resultList.get(0));\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn Optional.ofNullable(result);", "line": null, "startLine": null, "originalLine": 165, "originalStartLine": 158, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}}]}}, {"id": "PRR_kwDOABGHUc4wtQgc", "author": {"login": "rkvigneswaran"}, "state": "CHANGES_REQUESTED", "body": "Hi,\r\n\r\nThis is my first review comments in any open source project. Kindly let me know if my comments are invalid.", "submittedAt": "2021-11-28T02:45:38Z", "updatedAt": "2021-11-28T02:45:38Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc4wtQqW", "author": {"login": "KaidosGH"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T03:01:29Z", "updatedAt": "2021-11-28T03:01:29Z", "commit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMzowMToyOFrOLSuotw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6i3", "author": {"login": "KaidosGH"}, "body": "Hi @rkvigneswaran,\r\n\r\nthat is actually pretty smart. Cuts out a lot of redundant code! \ud83d\udc4d \r\n\r\nedit: i commited all 3 enhancements", "createdAt": "2021-11-28T03:01:28Z", "updatedAt": "2021-11-28T03:04:28Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,111 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);\n+\t\t}\n+\t\treturn result;\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Collection.\n+\t *

Returns {@code Optional.empty()} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Collection (can be {@code null})\n+\t * @return the single optional result object, or {@code Optional.empty()} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Collection\n+\t */\n+\tpublic static Optional optionalResult(@Nullable Collection results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (CollectionUtils.isEmpty(results)) {\n+\t\t\treturn Optional.empty();\n+\t\t}\n+\t\tif (results.size() > 1) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, results.size());\n+\t\t}\n+\t\treturn results.stream().findFirst();", "line": null, "startLine": null, "originalLine": 123, "originalStartLine": 117, "replyTo": {"id": "PRRC_kwDOABGHUc4tK6JW"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "8a5fc7d42bfef5a4c51e1adfe2392e10065f0c43"}}]}}, {"id": "PRR_kwDOABGHUc4wtSnN", "author": {"login": "bananayong"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T06:21:53Z", "updatedAt": "2021-11-28T06:21:53Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwNjoyMTo1M1rOLSvb4Q=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK9vh", "author": {"login": "bananayong"}, "body": "I think IncorrectResultSizeDataAccessException should contain the size of the results stream.\r\nif `resultList.size()` will be used, actual size of IncorrectResultSizeDataAccessException is `<=2` always unlike actual size of results.\r\n\r\nIf prefer stream way, How about utilze `teeing`?\r\n```java\r\n\t\tresults.collect(teeing(counting(), reducing((first, second) -> first), (count, result) -> {\r\n\t\t\tif (count > 1) {\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, count.intValue());\r\n\t\t\t}\r\n\t\t\treturn result.orElse(null);\r\n\t\t}))\r\n```", "createdAt": "2021-11-28T06:21:53Z", "updatedAt": "2021-11-28T06:21:53Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "startLine": null, "originalLine": 80, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}, {"id": "PRR_kwDOABGHUc4wtU0h", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T08:28:16Z", "updatedAt": "2021-11-28T08:28:16Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwODoyODoxNVrOLSwKVA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLApU", "author": {"login": "rkvigneswaran"}, "body": "Just a suggestion. There are multiple constructors provided by `IncorrectResultSizeDataAccessException` class. \r\n\r\n* One of the constructors doesn't take `actualSize` argument and assigns the value `-1` if the size if unknown. You can consider using it\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-)\r\n* Another constructor explicitly suggests setting the value of `actualSize` to `-1` if size is unknown\r\n * `public IncorrectResultSizeDataAccessException(int expectedSize, int actualSize)` - [Javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/IncorrectResultSizeDataAccessException.html#IncorrectResultSizeDataAccessException-int-int-)\r\n\r\nBoth of them would be suitable for this scenario since size is unknown", "createdAt": "2021-11-28T08:28:15Z", "updatedAt": "2021-11-28T08:30:33Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "startLine": null, "originalLine": 80, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tK9vh"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}, {"id": "PRR_kwDOABGHUc4wtVvK", "author": {"login": "bananayong"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T09:08:45Z", "updatedAt": "2021-11-28T09:08:45Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwOTowODo0NFrOLSwcNg=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLBw2", "author": {"login": "bananayong"}, "body": "It makes sense.", "createdAt": "2021-11-28T09:08:44Z", "updatedAt": "2021-11-28T09:08:45Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "startLine": null, "originalLine": 80, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tK9vh"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}, {"id": "PRR_kwDOABGHUc4wtV8o", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T09:18:00Z", "updatedAt": "2021-11-28T09:18:00Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwOToxNzo1OVrOLSwgpQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLCCl", "author": {"login": "rkvigneswaran"}, "body": "```suggestion\r\n\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour", "createdAt": "2021-11-28T09:17:59Z", "updatedAt": "2021-11-28T09:25:26Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "startLine": null, "originalLine": 80, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tK9vh"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}, {"id": "PRR_kwDOABGHUc4wtWEV", "author": {"login": "rkvigneswaran"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T09:22:51Z", "updatedAt": "2021-11-28T09:22:51Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwOToyMjo1MFrOLSwi2w=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLCLb", "author": {"login": "rkvigneswaran"}, "body": "Same suggestion as above - [Link](https://github.com/spring-projects/spring-framework/pull/27735/files#r757849057). Since `actualSize` of the iterator isn't known beforehand, we can use `public IncorrectResultSizeDataAccessException(int expectedSize)` constructor and set the `actualSize` as `-1`\r\n```suggestion\r\n\t\t\tthrow new IncorrectResultSizeDataAccessException(1);\r\n```\r\n\r\nUTs might need to be updated to reflect this behaviour", "createdAt": "2021-11-28T09:22:50Z", "updatedAt": "2021-11-28T09:25:12Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());\n+\t\t\t}\n+\t\t\treturn CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Return a single result object from the given Iterator.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Iterator (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Iterator\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Iterator results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tT result = results.hasNext() ? results.next() : null;\n+\t\tif (results.hasNext()) {\n+\t\t\tthrow new IncorrectResultSizeDataAccessException(1, 2);", "line": null, "startLine": null, "originalLine": 102, "originalStartLine": null, "replyTo": null, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}, {"id": "PRR_kwDOABGHUc4wtWLa", "author": {"login": "rkvigneswaran"}, "state": "CHANGES_REQUESTED", "body": "Modifying the exception to make it clear that size of the underlying Stream/Iterator is not known", "submittedAt": "2021-11-28T09:27:14Z", "updatedAt": "2021-11-28T09:27:14Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}}, {"id": "PRR_kwDOABGHUc4wtc_j", "author": {"login": "KaidosGH"}, "state": "COMMENTED", "body": "", "submittedAt": "2021-11-28T14:09:23Z", "updatedAt": "2021-11-28T14:09:23Z", "commit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQxNDowOToyM1rOLSysbQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLKxt", "author": {"login": "KaidosGH"}, "body": "yeah let's use the `public IncorrectResultSizeDataAccessException(int expectedSize)` for the iterator and stream method. \r\nWhat do you mean by \"UT\"?\r\n\r\nEdit: nevermind, figured it out \ud83d\ude04", "createdAt": "2021-11-28T14:09:23Z", "updatedAt": "2021-11-28T14:14:52Z", "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "diffHunk": "@@ -56,6 +60,89 @@\n \t\treturn results.iterator().next();\n \t}\n \n+\t/**\n+\t * Return a single result object from the given Stream.\n+\t *

Returns {@code null} if 0 result objects found;\n+\t * throws an exception if more than 1 element found.\n+\t * @param results the result Stream (can be {@code null})\n+\t * @return the single result object, or {@code null} if none\n+\t * @throws IncorrectResultSizeDataAccessException if more than one\n+\t * element has been found in the given Stream\n+\t */\n+\t@Nullable\n+\tpublic static T singleResult(@Nullable Stream results) throws IncorrectResultSizeDataAccessException {\n+\t\tif (results == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\ttry (results) {\n+\t\t\tList resultList = results.limit(2).toList();\n+\t\t\tif (resultList.size() > 1) {\n+\t\t\t\tthrow new IncorrectResultSizeDataAccessException(1, resultList.size());", "line": null, "startLine": null, "originalLine": 80, "originalStartLine": null, "replyTo": {"id": "PRRC_kwDOABGHUc4tK9vh"}, "isMinimized": false, "minimizedReason": null, "commit": {"oid": "1891fa45b5d43a3741905531f8b84944a7c820e0"}, "originalCommit": {"oid": "3017bebc5bf1dfc7e779706c87ff1fb6b767eb7f"}}]}}], "totalCount": 18, "pageInfo": {"hasNextPage": false, "endCursor": null}}, "reviewThreads": {"totalCount": 8, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwOToyMjo1MFrOHNtGVg=="}, "nodes": [{"id": "PRRT_kwDOABGHUc4c12KA", "isResolved": false, "isOutdated": true, "isCollapsed": false, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 78, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": null, "comments": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yN1QxMjowMzo0MVrOLSq4Pw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tJu8c"}, {"id": "PRRC_kwDOABGHUc4tKScv"}, {"id": "PRRC_kwDOABGHUc4tKrg_"}]}}, {"id": "PRRT_kwDOABGHUc4c12Ta", "isResolved": false, "isOutdated": true, "isCollapsed": false, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 100, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": null, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yNlQxNDoxMToxMlrOLSbyuw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tJvK7"}]}}, {"id": "PRRT_kwDOABGHUc4c2hh3", "isResolved": false, "isOutdated": true, "isCollapsed": false, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 77, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": null, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yN1QxMzo1NjoyM1rOLSrezA=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tKrpS"}, {"id": "PRRC_kwDOABGHUc4tKt7M"}]}}, {"id": "PRRT_kwDOABGHUc4c2tq2", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 123, "diffSide": "RIGHT", "startDiffSide": "RIGHT", "resolvedBy": {"login": "KaidosGH"}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMzowMToyOFrOLSuotw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6JW"}, {"id": "PRRC_kwDOABGHUc4tK6i3"}]}}, {"id": "PRRT_kwDOABGHUc4c2tvE", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 144, "diffSide": "RIGHT", "startDiffSide": "RIGHT", "resolvedBy": {"login": "KaidosGH"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMjo0MjoxNVrOLSujhw=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6OH"}]}}, {"id": "PRRT_kwDOABGHUc4c2tvf", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 165, "diffSide": "RIGHT", "startDiffSide": "RIGHT", "resolvedBy": {"login": "KaidosGH"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwMjo0Mjo1OFrOLSujpQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK6Ol"}]}}, {"id": "PRRT_kwDOABGHUc4c2w0c", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 80, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "KaidosGH"}, "comments": {"totalCount": 5, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQxNDowOToyM1rOLSysbQ=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tK9vh"}, {"id": "PRRC_kwDOABGHUc4tLApU"}, {"id": "PRRC_kwDOABGHUc4tLBw2"}, {"id": "PRRC_kwDOABGHUc4tLCCl"}, {"id": "PRRC_kwDOABGHUc4tLKxt"}]}}, {"id": "PRRT_kwDOABGHUc4c20ZW", "isResolved": true, "isOutdated": true, "isCollapsed": true, "path": "spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java", "startLine": null, "originalLine": 102, "diffSide": "RIGHT", "startDiffSide": null, "resolvedBy": {"login": "KaidosGH"}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpK0MjAyMS0xMS0yOFQwOToyMjo1MFrOLSwi2w=="}, "nodes": [{"id": "PRRC_kwDOABGHUc4tLCLb"}]}}]}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "I_kwDOABGHUc4_U9mZ", "number": 27728, "url": "https://github.com/spring-projects/spring-framework/issues/27728", "title": "DataAccessUtils result accessors with Optional return value", "body": "Related to #724, `DataAccessUtils` should provide an `optionalResult` method for `Collection` as well as `Stream` arguments (and also for `Iterator` because we need that internally anyway), returning a corresponding `Optional` wrapper or `Optional.empty()`.\r\n\r\nIn addition, a `singleResult` overload for a `Stream` argument (and for `Iterator`) would complete the overall arrangement in `DataAccessUtils`.", "state": "CLOSED", "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "in: data"}, {"name": "type: enhancement"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHOOmfCCg=="}, "nodes": [{"id": "IC_kwDOABGHUc46Z8IK", "author": {"login": "rstoyanchev"}, "body": "Superseded by #27735.", "createdAt": "2021-11-26T10:53:50Z", "updatedAt": "2021-11-26T10:53:50Z"}]}}]}} +{"id": "MDExOlB1bGxSZXF1ZXN0NzE2ODE1ODg5", "title": "Fix UrlPathHelper#shouldRemoveSemicolonContent()", "body": "Fixes #27256\r\n\r\nThis PR fixes a bug that renders read-only `UrlPathHelper`s unusable, because `shouldRemoveSemicolonContent()` throws an exception. For example, when using `UrlPathHelper#rawPathInstance`, which is read-only.\r\n\r\nThe `checkReadOnly()` method should only be called from methods that modify properties to prevent modification of read-only instances.", "number": 27303, "url": "https://github.com/spring-projects/spring-framework/pull/27303", "author": {"login": "evpaassen"}, "createdAt": "2021-08-20T15:16:19Z", "mergedAt": "2021-08-22T12:10:25Z", "mergedBy": {"login": "sbrannen"}, "baseRefOid": "9f7a94058a4bbc967fe47bfe6a82d88cb3feddfb", "baseRefName": "main", "headRefOid": "51a17316ff5d464400ffc9f7a42b34ba0c0eea69", "headRefName": "fix-27256", "changedFiles": 2, "labels": {"totalCount": 3, "pageInfo": {"hasNextPage": false, "endCursor": "Mw"}, "nodes": [{"name": "status: backported"}, {"name": "in: web"}, {"name": "type: bug"}]}, "commits": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"commit": {"oid": "51a17316ff5d464400ffc9f7a42b34ba0c0eea69", "message": "Fix UrlPathHelper#shouldRemoveSemicolonContent()\n\nThe checkReadOnly() method should only be called from\nmethods that modify properties to prevent modification\nof read-only instances.\n\nFixes #27256", "changedFilesIfAvailable": 2, "authoredDate": "2021-08-20T15:09:57Z", "author": {"user": {"login": "evpaassen"}}, "committedDate": "2021-08-20T18:33:04Z", "committer": {"user": {"login": "evpaassen"}}, "parents": {"nodes": [{"oid": "9f7a94058a4bbc967fe47bfe6a82d88cb3feddfb"}]}}}]}, "reviews": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "reviewThreads": {"totalCount": 0, "pageInfo": {"hasNextPage": false, "endCursor": null}, "nodes": []}, "closingIssuesReferences": {"totalCount": 1, "pageInfo": {"hasNextPage": false, "endCursor": "MQ"}, "nodes": [{"id": "MDU6SXNzdWU5NjUwMTkzNjc=", "number": 27256, "url": "https://github.com/spring-projects/spring-framework/issues/27256", "title": "UrlPathHelper: checkReadOnly() called in read method shouldRemoveSemicolonContent()", "body": "\r\n**Affects:** 5.3.8\r\n\r\n---\r\n\r\nMethod `checkReadOnly` is called in read method UrlPathHelper#shouldRemoveSemicolonContent, line 149. If we want to know whether we should `removeSemicolonContent` when `this.readOnly` is true, an error will be thrown.\r\n```\r\npublic boolean shouldRemoveSemicolonContent() {\r\n checkReadOnly();\r\n return this.removeSemicolonContent;\r\n}\r\n```", "state": "CLOSED", "labels": {"totalCount": 4, "pageInfo": {"hasNextPage": false, "endCursor": "NA"}, "nodes": [{"name": "status: backported"}, {"name": "in: web"}, {"name": "type: bug"}, {"name": "status: superseded"}]}, "comments": {"totalCount": 2, "pageInfo": {"hasNextPage": false, "endCursor": "Y3Vyc29yOnYyOpHONc-vSQ=="}, "nodes": [{"id": "IC_kwDOABGHUc41zyX8", "author": {"login": "evpaassen"}, "body": "Today I encountered this bug too. I created PR #27303 to fix it.", "createdAt": "2021-08-20T15:17:46Z", "updatedAt": "2021-08-20T15:17:46Z"}, {"id": "IC_kwDOABGHUc41z69J", "author": {"login": "sbrannen"}, "body": "Superseded by #27303.", "createdAt": "2021-08-20T16:13:31Z", "updatedAt": "2021-08-20T16:13:31Z"}]}}]}}