diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java
index 4a9c98f4dac9..728e663546c0 100644
--- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java
+++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java
@@ -233,7 +233,7 @@ private class CreateJmxConnector implements Callable<@Nullable JMXConnector> {
}
private boolean hasCauseWithType(Throwable t, Class extends Exception> type) {
- return type.isAssignableFrom(t.getClass()) || t.getCause() != null && hasCauseWithType(t.getCause(), type);
+ return type.isInstance(t) || t.getCause() != null && hasCauseWithType(t.getCause(), type);
}
}
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 1f2778c9e920..84dda76682a6 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -88,6 +88,18 @@
value="Please use static AssertJ imports." />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/fieldvalues/javac/ExpressionTree.java b/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/fieldvalues/javac/ExpressionTree.java
index 9eb0caba5138..1b154d92bd6e 100644
--- a/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/fieldvalues/javac/ExpressionTree.java
+++ b/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/fieldvalues/javac/ExpressionTree.java
@@ -55,14 +55,14 @@ String getKind() throws Exception {
}
Object getLiteralValue() throws Exception {
- if (this.literalTreeType.isAssignableFrom(getInstance().getClass())) {
+ if (this.literalTreeType.isInstance(getInstance())) {
return this.literalValueMethod.invoke(getInstance());
}
return null;
}
Object getFactoryValue() throws Exception {
- if (this.methodInvocationTreeType.isAssignableFrom(getInstance().getClass())) {
+ if (this.methodInvocationTreeType.isInstance(getInstance())) {
List> arguments = (List>) this.methodInvocationArgumentsMethod.invoke(getInstance());
if (arguments.size() == 1) {
return new ExpressionTree(arguments.get(0)).getLiteralValue();
@@ -72,7 +72,7 @@ Object getFactoryValue() throws Exception {
}
Member getSelectedMember() throws Exception {
- if (this.memberSelectTreeType.isAssignableFrom(getInstance().getClass())) {
+ if (this.memberSelectTreeType.isInstance(getInstance())) {
String expression = this.memberSelectTreeExpressionMethod.invoke(getInstance()).toString();
String identifier = this.memberSelectTreeIdentifierMethod.invoke(getInstance()).toString();
if (expression != null && identifier != null) {
@@ -83,7 +83,7 @@ Member getSelectedMember() throws Exception {
}
List extends ExpressionTree> getArrayExpression() throws Exception {
- if (this.newArrayTreeType.isAssignableFrom(getInstance().getClass())) {
+ if (this.newArrayTreeType.isInstance(getInstance())) {
List> elements = (List>) this.arrayValueMethod.invoke(getInstance());
List result = new ArrayList<>();
if (elements == null) {
diff --git a/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestImportTests.java b/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestImportTests.java
index 549dc58e2374..d485f14dba16 100644
--- a/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestImportTests.java
+++ b/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestImportTests.java
@@ -24,6 +24,8 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
+import org.springframework.test.context.NestedTestConfiguration;
+import org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -68,6 +70,38 @@ void containingClassTestPropertySourceIsHonored() {
}
+ @Nested
+ @SpringBootTest(classes = Config.class)
+ @Import(ImportedByNestedTests.class)
+ @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE)
+ class OverrideNestedTests {
+
+ @Autowired(required = false)
+ private ImportedByContainingTests importedByContainingTests;
+
+ @Autowired(required = false)
+ private ImportedByNestedTests importedByNestedTests;
+
+ @Autowired
+ private Environment environment;
+
+ @Test
+ void sameClassImportIsHonored() {
+ assertThat(this.importedByNestedTests).isNotNull();
+ }
+
+ @Test
+ void containingClassImportIsNotInherited() {
+ assertThat(this.importedByContainingTests).isNull();
+ }
+
+ @Test
+ void containingClassTestPropertySourceIsNotInherited() {
+ assertThat(this.environment.getProperty("a")).isNull();
+ }
+
+ }
+
@Configuration(proxyBeanMethods = false)
static class Config {
diff --git a/core/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandler.java b/core/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandler.java
index 06e4708019cb..bfd8340c0410 100644
--- a/core/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandler.java
+++ b/core/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandler.java
@@ -34,7 +34,6 @@
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form;
import org.springframework.core.ResolvableType;
-import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.AbstractBindingResult;
import org.springframework.validation.BeanPropertyBindingResult;
@@ -115,8 +114,7 @@ private void validate(ConfigurationPropertyName name, Bindable> target, BindCo
if (this.exception == null) {
Object validationTarget = getValidationTarget(target, context, result);
Class> validationType = target.getBoxedType().resolve();
- if (validationTarget != null) {
- Assert.state(validationType != null, "'validationType' must not be null");
+ if (validationTarget != null && validationType != null) {
validateAndPush(name, validationTarget, validationType);
}
}
diff --git a/core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/AbstractInjectionFailureAnalyzer.java b/core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/AbstractInjectionFailureAnalyzer.java
index 6e357c13edc4..8107c1059edd 100644
--- a/core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/AbstractInjectionFailureAnalyzer.java
+++ b/core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/AbstractInjectionFailureAnalyzer.java
@@ -64,7 +64,7 @@ public abstract class AbstractInjectionFailureAnalyzer exte
Throwable candidate = root;
C result = null;
while (candidate != null) {
- if (type.isAssignableFrom(candidate.getClass())) {
+ if (type.isInstance(candidate)) {
result = (C) candidate;
}
candidate = candidate.getCause();
diff --git a/core/spring-boot/src/main/java/org/springframework/boot/json/AbstractJsonParser.java b/core/spring-boot/src/main/java/org/springframework/boot/json/AbstractJsonParser.java
index 78e9a0000b8a..56591ea5ee36 100644
--- a/core/spring-boot/src/main/java/org/springframework/boot/json/AbstractJsonParser.java
+++ b/core/spring-boot/src/main/java/org/springframework/boot/json/AbstractJsonParser.java
@@ -55,7 +55,7 @@ protected final T tryParse(Callable parser, Class extends Exception> ch
return parser.call();
}
catch (Exception ex) {
- if (check.isAssignableFrom(ex.getClass())) {
+ if (check.isInstance(ex)) {
throw new JsonParseException(ex);
}
ReflectionUtils.rethrowRuntimeException(ex);
diff --git a/core/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandlerTests.java b/core/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandlerTests.java
index c9ac953d5539..d8f645541e9b 100644
--- a/core/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandlerTests.java
+++ b/core/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandlerTests.java
@@ -238,6 +238,15 @@ void validateMapValuesWithNonUniformSource() {
this.binder.bind(ConfigurationPropertyName.of("test"), Bindable.of(ExampleWithMap.class), this.handler);
}
+ @Test
+ void bindShouldValidateMapWithWildcardValue() {
+ this.sources.add(new MockConfigurationPropertySource("test.params.toto", "titi"));
+ ExampleWithWildcardMap result = this.binder
+ .bind(ConfigurationPropertyName.of("test"), Bindable.of(ExampleWithWildcardMap.class), this.handler)
+ .get();
+ assertThat(result.getParams().get("toto")).isEqualTo("titi");
+ }
+
private Validator getMapValidator() {
return new Validator() {
@@ -425,6 +434,21 @@ Map getItems() {
}
+ @Validated
+ static class ExampleWithWildcardMap {
+
+ private Map params = new LinkedHashMap<>();
+
+ Map getParams() {
+ return this.params;
+ }
+
+ void setParams(Map params) {
+ this.params = params;
+ }
+
+ }
+
static class ExampleMapValue {
private @Nullable String number;
diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/appendix/pages/application-properties/index.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/appendix/pages/application-properties/index.adoc
index 21cc3c5acb76..0d24c72a759d 100644
--- a/documentation/spring-boot-docs/src/docs/antora/modules/appendix/pages/application-properties/index.adoc
+++ b/documentation/spring-boot-docs/src/docs/antora/modules/appendix/pages/application-properties/index.adoc
@@ -25,6 +25,8 @@ include::partial$configuration-properties/devtools.adoc[]
include::partial$configuration-properties/docker-compose.adoc[]
+include::partial$configuration-properties/grpc.adoc[]
+
include::partial$configuration-properties/integration.adoc[]
include::partial$configuration-properties/json.adoc[]
diff --git a/integration-test/spring-boot-loader-integration-tests/build.gradle b/integration-test/spring-boot-loader-integration-tests/build.gradle
index 1a2eea9cf62d..fd63ebb620bd 100644
--- a/integration-test/spring-boot-loader-integration-tests/build.gradle
+++ b/integration-test/spring-boot-loader-integration-tests/build.gradle
@@ -82,6 +82,17 @@ tasks.register("buildSignedJarRsaApp", GradleBuild) {
tasks = ["build"]
}
+tasks.register("syncWarAppSource", org.springframework.boot.build.SyncAppSource) {
+ sourceDirectory = file("spring-boot-loader-tests-war")
+ destinationDirectory = file(layout.buildDirectory.dir("spring-boot-loader-tests-war"))
+}
+
+tasks.register("buildWarApp", GradleBuild) {
+ dependsOn syncWarAppSource, syncMavenRepository
+ dir = layout.buildDirectory.dir("spring-boot-loader-tests-war")
+ startParameter.buildCacheEnabled = false
+ tasks = ["build"]
+}
tasks.register("downloadJdk", Download) {
def destFolder = new File(project.gradle.gradleUserHomeDir, "caches/springboot/downloads/jdk/oracle")
@@ -105,5 +116,5 @@ tasks.named("processDockerTestResources").configure {
}
tasks.named("dockerTest").configure {
- dependsOn buildApp, buildSignedJarApp, buildSignedJarRsaApp
+ dependsOn buildApp, buildWarApp, buildSignedJarApp, buildSignedJarRsaApp
}
diff --git a/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/build.gradle b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/build.gradle
new file mode 100644
index 000000000000..a3e0b11f58e6
--- /dev/null
+++ b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/build.gradle
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+ id "war"
+ id "org.springframework.boot"
+}
+
+java {
+ sourceCompatibility = '17'
+ targetCompatibility = '17'
+}
+
+repositories {
+ maven { url = layout.projectDirectory.dir("../docker-test-maven-repository") }
+ mavenCentral()
+ spring.mavenRepositories()
+}
+
+dependencies {
+ implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
+ implementation("org.springframework.boot:spring-boot-starter-webmvc")
+
+ providedRuntime(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
+ providedRuntime("org.springframework.boot:spring-boot-starter-tomcat-runtime")
+ providedRuntime("org.glassfish.web:jakarta.servlet.jsp.jstl")
+ providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
+}
diff --git a/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/settings.gradle b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/settings.gradle
new file mode 100644
index 000000000000..d5cca12cf132
--- /dev/null
+++ b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/settings.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pluginManagement {
+ evaluate(new File("${gradle.parent.rootProject.rootDir}/buildSrc/SpringRepositorySupport.groovy")).apply(this)
+ repositories {
+ maven { url = layout.settingsDirectory.dir("../docker-test-maven-repository") }
+ mavenCentral()
+ spring.mavenRepositories()
+ }
+ resolutionStrategy {
+ eachPlugin {
+ if (requested.id.id == "org.springframework.boot") {
+ useModule "org.springframework.boot:spring-boot-gradle-plugin:${requested.version}"
+ }
+ }
+ }
+}
diff --git a/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/java/org/springframework/boot/loaderwarapp/LoaderWarTestApplication.java b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/java/org/springframework/boot/loaderwarapp/LoaderWarTestApplication.java
new file mode 100644
index 000000000000..6d9e218ccf5a
--- /dev/null
+++ b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/java/org/springframework/boot/loaderwarapp/LoaderWarTestApplication.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.loaderwarapp;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class LoaderWarTestApplication extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(LoaderWarTestApplication.class);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(LoaderWarTestApplication.class, args).close();
+ }
+
+}
diff --git a/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/webapp/WEB-INF/jsp/welcome.jsp b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/webapp/WEB-INF/jsp/welcome.jsp
new file mode 100644
index 000000000000..811f3e7d00f2
--- /dev/null
+++ b/integration-test/spring-boot-loader-integration-tests/spring-boot-loader-tests-war/src/main/webapp/WEB-INF/jsp/welcome.jsp
@@ -0,0 +1,13 @@
+
+
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+
+
+
+
+
+ Spring URL: ${springUrl}
+ JSTL URL: ${url}
+
+
diff --git a/integration-test/spring-boot-loader-integration-tests/src/dockerTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java b/integration-test/spring-boot-loader-integration-tests/src/dockerTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java
index 54d662e738ab..56c1fecd4e29 100644
--- a/integration-test/spring-boot-loader-integration-tests/src/dockerTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java
+++ b/integration-test/spring-boot-loader-integration-tests/src/dockerTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java
@@ -63,6 +63,21 @@ void runJar(JavaRuntime javaRuntime) {
}
}
+ @ParameterizedTest
+ @MethodSource("javaRuntimes")
+ void runWarWithTldScanning(JavaRuntime javaRuntime) {
+ try (GenericContainer> container = createContainer(javaRuntime, "spring-boot-loader-tests-war", null,
+ "war")) {
+ container.start();
+ System.out.println(this.output.toUtf8String());
+ assertThat(this.output.toUtf8String()).contains("Started LoaderWarTestApplication")
+ .doesNotContain("no entry name specified")
+ .doesNotContain("Failed to scan")
+ .doesNotContain("ZipException")
+ .doesNotContain("WARNING:");
+ }
+ }
+
@ParameterizedTest
@MethodSource("javaRuntimes")
void runSignedJar(JavaRuntime javaRuntime) {
@@ -97,31 +112,37 @@ void runSignedJarWhenRsa(JavaRuntime javaRuntime) {
}
private GenericContainer> createContainer(JavaRuntime javaRuntime, String name, String classifier) {
+ return createContainer(javaRuntime, name, classifier, "jar");
+ }
+
+ private GenericContainer> createContainer(JavaRuntime javaRuntime, String name, String classifier,
+ String extension) {
+ String application = "app." + extension;
return javaRuntime.getContainer()
.withLogConsumer(this.output)
- .withCopyFileToContainer(findApplication(name, classifier), "/app.jar")
+ .withCopyFileToContainer(findApplication(name, classifier, extension), "/" + application)
.withStartupCheckStrategy(new OneShotStartupCheckStrategy().withTimeout(Duration.ofMinutes(5)))
- .withCommand(command());
+ .withCommand(command(application));
}
- private String[] command() {
+ private String[] command(String application) {
List command = new ArrayList<>();
command.add("java");
command.add("-jar");
- command.add("app.jar");
+ command.add(application);
return command.toArray(new String[0]);
}
- private MountableFile findApplication(String name, String classifier) {
- return MountableFile.forHostPath(findJarFile(name, classifier).toPath());
+ private MountableFile findApplication(String name, String classifier, String extension) {
+ return MountableFile.forHostPath(findArchiveFile(name, classifier, extension).toPath());
}
- private File findJarFile(String name, String classifier) {
+ private File findArchiveFile(String name, String classifier, String extension) {
classifier = (classifier != null) ? "-" + classifier : "";
- String path = String.format("build/%1$s/build/libs/%1$s%2$s.jar", name, classifier);
- File jar = new File(path);
- Assert.state(jar.isFile(), () -> "Could not find " + path + ". Have you built it?");
- return jar;
+ String path = String.format("build/%1$s/build/libs/%1$s%2$s.%3$s", name, classifier, extension);
+ File archive = new File(path);
+ Assert.state(archive.isFile(), () -> "Could not find " + path + ". Have you built it?");
+ return archive;
}
static Stream javaRuntimes() {
diff --git a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
index 7de31c52698c..51a390501a88 100644
--- a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
+++ b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
@@ -337,7 +337,7 @@ else if (item instanceof List) {
if (value == null || ClassUtils.isPrimitiveOrWrapper(value.getClass()) || value instanceof String) {
return value;
}
- if (CharSequence.class.isAssignableFrom(value.getClass())) {
+ if (value instanceof CharSequence) {
return value.toString();
}
return "Complex property value " + value.getClass().getName();
diff --git a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java
index 4b979f5c573e..807ceb0761b6 100644
--- a/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java
+++ b/module/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/env/EnvironmentEndpoint.java
@@ -208,11 +208,10 @@ private void extract(String root, Map> map, PropertySo
}
protected @Nullable Object stringifyIfNecessary(@Nullable Object value) {
- if (value == null || ClassUtils.isPrimitiveOrWrapper(value.getClass())
- || Number.class.isAssignableFrom(value.getClass())) {
+ if (value == null || ClassUtils.isPrimitiveOrWrapper(value.getClass()) || value instanceof Number) {
return value;
}
- if (CharSequence.class.isAssignableFrom(value.getClass())) {
+ if (value instanceof CharSequence) {
return value.toString();
}
return "Complex property type " + value.getClass().getName();
diff --git a/module/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java b/module/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java
index 6c221bcbd685..1bdcd559c2cb 100644
--- a/module/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java
+++ b/module/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java
@@ -169,7 +169,7 @@ private T findEncoder(AssertableApplicationContext context, Class encoder
.filter((writer) -> writer instanceof EncoderHttpMessageWriter>)
.map((writer) -> (EncoderHttpMessageWriter>) writer)
.map(EncoderHttpMessageWriter::getEncoder)
- .filter((encoder) -> encoderClass.isAssignableFrom(encoder.getClass()))
+ .filter(encoderClass::isInstance)
.findFirst()
.orElseThrow();
}
diff --git a/module/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java b/module/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java
index 4e7177dc03a5..ec35b5e71df8 100644
--- a/module/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java
+++ b/module/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java
@@ -465,18 +465,14 @@ private ApplicationContextRunner allOptionsRunner() {
private void assertConverterIsRegistered(AssertableApplicationContext context,
Class extends HttpMessageConverter>> converterType) {
- assertThat(getClientConverters(context)).filteredOn((c) -> converterType.isAssignableFrom(c.getClass()))
- .hasSize(1);
- assertThat(getServerConverters(context)).filteredOn((c) -> converterType.isAssignableFrom(c.getClass()))
- .hasSize(1);
+ assertThat(getClientConverters(context)).filteredOn(converterType::isInstance).hasSize(1);
+ assertThat(getServerConverters(context)).filteredOn(converterType::isInstance).hasSize(1);
}
private void assertConverterIsNotRegistered(AssertableApplicationContext context,
Class extends HttpMessageConverter>> converterType) {
- assertThat(getClientConverters(context)).filteredOn((c) -> converterType.isAssignableFrom(c.getClass()))
- .isEmpty();
- assertThat(getServerConverters(context)).filteredOn((c) -> converterType.isAssignableFrom(c.getClass()))
- .isEmpty();
+ assertThat(getClientConverters(context)).filteredOn(converterType::isInstance).isEmpty();
+ assertThat(getServerConverters(context)).filteredOn(converterType::isInstance).isEmpty();
}
private void assertBeanExists(AssertableApplicationContext context, Class> type, String beanName) {
@@ -504,7 +500,7 @@ private HttpMessageConverters getServerConverters(ApplicationContext context) {
private > T findConverter(HttpMessageConverters converters,
Class extends HttpMessageConverter>> type) {
for (HttpMessageConverter> converter : converters) {
- if (type.isAssignableFrom(converter.getClass())) {
+ if (type.isInstance(converter)) {
return (T) converter;
}
}
@@ -589,8 +585,7 @@ static class JacksonConverterConfig {
@Bean
JacksonJsonHttpMessageConverter customJacksonMessageConverter(JsonMapper jsonMapperMapper) {
- JacksonJsonHttpMessageConverter converter = new JacksonJsonHttpMessageConverter(jsonMapperMapper);
- return converter;
+ return new JacksonJsonHttpMessageConverter(jsonMapperMapper);
}
}
diff --git a/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java b/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java
index 23d1f7378246..cb7989d775ce 100644
--- a/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java
+++ b/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java
@@ -49,7 +49,7 @@ abstract class JdbcConnectionDetailsBeanPostProcessor implements BeanPostProc
@Override
@SuppressWarnings("unchecked")
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (this.dataSourceClass.isAssignableFrom(bean.getClass()) && "dataSource".equals(beanName)) {
+ if (this.dataSourceClass.isInstance(bean) && "dataSource".equals(beanName)) {
JdbcConnectionDetails connectionDetails = this.connectionDetailsProvider.getObject();
if (!(connectionDetails instanceof PropertiesJdbcConnectionDetails)) {
return processDataSource((T) bean, connectionDetails);
diff --git a/module/spring-boot-micrometer-tracing/src/main/java/org/springframework/boot/micrometer/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java b/module/spring-boot-micrometer-tracing/src/main/java/org/springframework/boot/micrometer/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java
index 35872707f621..0c0e11e76ed0 100644
--- a/module/spring-boot-micrometer-tracing/src/main/java/org/springframework/boot/micrometer/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java
+++ b/module/spring-boot-micrometer-tracing/src/main/java/org/springframework/boot/micrometer/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java
@@ -47,7 +47,7 @@ class TracingAndMeterObservationHandlerGroup implements ObservationHandlerGroup
@Override
public boolean isMember(ObservationHandler> handler) {
- return MeterObservationHandler.class.isInstance(handler) || TracingObservationHandler.class.isInstance(handler);
+ return handler instanceof MeterObservationHandler || handler instanceof TracingObservationHandler;
}
@Override
diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoHealthIndicator.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoHealthIndicator.java
index 541a9a996f56..afb9e07db211 100644
--- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoHealthIndicator.java
+++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoHealthIndicator.java
@@ -17,9 +17,7 @@
package org.springframework.boot.mongodb.health;
import java.util.ArrayList;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import com.mongodb.client.MongoClient;
import org.bson.Document;
@@ -34,10 +32,13 @@
* MongoDB.
*
* @author Christian Dupuis
+ * @author Seonwoo Jung
* @since 4.0.0
*/
public class MongoHealthIndicator extends AbstractHealthIndicator {
+ private static final String ADMIN_DATABASE = "admin";
+
private static final Document HELLO_COMMAND = Document.parse("{ hello: 1 }");
private final MongoClient mongoClient;
@@ -50,15 +51,19 @@ public MongoHealthIndicator(MongoClient mongoClient) {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
- Map details = new LinkedHashMap<>();
List databases = new ArrayList<>();
- details.put("databases", databases);
- this.mongoClient.listDatabaseNames().forEach((database) -> {
- Document result = this.mongoClient.getDatabase(database).runCommand(HELLO_COMMAND);
- databases.add(database);
- details.putIfAbsent("maxWireVersion", result.getInteger("maxWireVersion"));
- });
- builder.up().withDetails(details);
+ this.mongoClient.listDatabaseNames().forEach(databases::add);
+ Document result = this.mongoClient.getDatabase(getDatabaseName(databases)).runCommand(HELLO_COMMAND);
+ builder.up()
+ .withDetail("databases", databases)
+ .withDetail("maxWireVersion", result.getInteger("maxWireVersion"));
+ }
+
+ private static String getDatabaseName(List databases) {
+ if (databases.contains(ADMIN_DATABASE)) {
+ return ADMIN_DATABASE;
+ }
+ return (!databases.isEmpty()) ? databases.get(0) : ADMIN_DATABASE;
}
}
diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoReactiveHealthIndicator.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoReactiveHealthIndicator.java
index c73cdd50e6f6..cc4e60356bb5 100644
--- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoReactiveHealthIndicator.java
+++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoReactiveHealthIndicator.java
@@ -16,10 +16,7 @@
package org.springframework.boot.mongodb.health;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import com.mongodb.reactivestreams.client.MongoClient;
import org.bson.Document;
@@ -35,10 +32,13 @@
* A {@link ReactiveHealthIndicator} for Mongo.
*
* @author Yulin Qin
+ * @author Seonwoo Jung
* @since 4.0.0
*/
public class MongoReactiveHealthIndicator extends AbstractReactiveHealthIndicator {
+ private static final String ADMIN_DATABASE = "admin";
+
private static final Document HELLO_COMMAND = Document.parse("{ hello: 1 }");
private final MongoClient mongoClient;
@@ -51,24 +51,20 @@ public MongoReactiveHealthIndicator(MongoClient mongoClient) {
@Override
protected Mono doHealthCheck(Health.Builder builder) {
- Mono