diff --git a/spring-boot/src/main/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializer.java b/spring-boot/src/main/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializer.java index a977cb5172..e48e32d08c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializer.java @@ -16,6 +16,13 @@ package org.springframework.boot.context; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -33,7 +40,6 @@ import org.springframework.core.PriorityOrdered; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -60,7 +66,7 @@ public class ConfigurationWarningsApplicationContextInitializer * @return the checks to apply */ protected Check[] getChecks() { - return new Check[] { new ComponentScanDefaultPackageCheck() }; + return new Check[] { new ComponentScanPackageCheck() }; } /** @@ -120,62 +126,101 @@ public class ConfigurationWarningsApplicationContextInitializer } /** - * {@link Check} for {@code @ComponentScan} on the default package. + * {@link Check} for {@code @ComponentScan} on problematic package. */ - protected static class ComponentScanDefaultPackageCheck implements Check { + protected static class ComponentScanPackageCheck implements Check { + + private static final Set PROBLEM_PACKAGES; + + static { + Set pacakges = new HashSet(); + pacakges.add("org.springframework"); + pacakges.add("org"); + PROBLEM_PACKAGES = Collections.unmodifiableSet(pacakges); + } @Override public String getWarning(BeanDefinitionRegistry registry) { - if (isComponentScanningDefaultPackage(registry)) { - return "Your ApplicationContext is unlikely to start due to a " - + "@ComponentScan of the default package."; + Set scannedPackages = getComponentScanningPackages(registry); + List problematicPackages = getProblematicPackages(scannedPackages); + if (problematicPackages.isEmpty()) { + return null; } - return null; + return "Your ApplicationContext is unlikely to " + + "start due to a @ComponentScan of " + + StringUtils.collectionToDelimitedString(problematicPackages, ", ") + + "."; } - private boolean isComponentScanningDefaultPackage( + protected Set getComponentScanningPackages( BeanDefinitionRegistry registry) { + Set packages = new LinkedHashSet(); String[] names = registry.getBeanDefinitionNames(); for (String name : names) { BeanDefinition definition = registry.getBeanDefinition(name); if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annotatedDefinition = (AnnotatedBeanDefinition) definition; - if (isScanningDefaultPackage(annotatedDefinition.getMetadata())) { - return true; - } + addComponentScanningPackages(packages, + annotatedDefinition.getMetadata()); } } - return false; + return packages; } - private boolean isScanningDefaultPackage(AnnotationMetadata metadata) { + private void addComponentScanningPackages(Set packages, + AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata .getAnnotationAttributes(ComponentScan.class.getName(), true)); - if (attributes != null && hasNoScanPackageSpecified(attributes)) { - if (isInDefaultPackage(metadata.getClassName())) { - return true; + if (attributes != null) { + addPackages(packages, attributes.getStringArray("value")); + addPackages(packages, attributes.getStringArray("basePackages")); + addClasses(packages, attributes.getStringArray("basePackageClasses")); + if (packages.isEmpty()) { + packages.add(ClassUtils.getPackageName(metadata.getClassName())); } } - return false; } - private boolean hasNoScanPackageSpecified(AnnotationAttributes attributes) { - return isAllEmpty(attributes, "value", "basePackages", "basePackageClasses"); + private void addPackages(Set packages, String[] values) { + if (values != null) { + for (String value : values) { + packages.add(value); + } + } } - private boolean isAllEmpty(AnnotationAttributes attributes, String... names) { - for (String name : names) { - if (!ObjectUtils.isEmpty(attributes.getStringArray(name))) { - return false; + private void addClasses(Set packages, String[] values) { + if (values != null) { + for (String value : values) { + packages.add(ClassUtils.getPackageName(value)); + } + } + } + + private List getProblematicPackages(Set scannedPackages) { + List problematicPackages = new ArrayList(); + for (String scannedPackage : scannedPackages) { + if (isProblematicPackage(scannedPackage)) { + problematicPackages.add(getDisplayName(scannedPackage)); } } - return true; + return problematicPackages; + } + + private boolean isProblematicPackage(String scannedPackage) { + if (scannedPackage == null || scannedPackage.length() == 0) { + return true; + } + return PROBLEM_PACKAGES.contains(scannedPackage); } - protected boolean isInDefaultPackage(String className) { - String packageName = ClassUtils.getPackageName(className); - return StringUtils.isEmpty(packageName); + private String getDisplayName(String scannedPackage) { + if (scannedPackage == null || scannedPackage.length() == 0) { + return "the default package"; + } + return "'" + scannedPackage + "'"; } + } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializerTests.java b/spring-boot/src/test/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializerTests.java index 6a80801b79..32d8a02e60 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/ConfigurationWarningsApplicationContextInitializerTests.java @@ -16,17 +16,23 @@ package org.springframework.boot.context; +import java.util.LinkedHashSet; +import java.util.Set; + import org.junit.Rule; import org.junit.Test; -import org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer.ComponentScanDefaultPackageCheck; -import org.springframework.boot.context.configwarnings.InDefaultPackageConfiguration; -import org.springframework.boot.context.configwarnings.InDefaultPackageWithBasePackageClassesConfiguration; -import org.springframework.boot.context.configwarnings.InDefaultPackageWithBasePackagesConfiguration; -import org.springframework.boot.context.configwarnings.InDefaultPackageWithMetaAnnotationConfiguration; -import org.springframework.boot.context.configwarnings.InDefaultPackageWithValueConfiguration; -import org.springframework.boot.context.configwarnings.InDefaultPackageWithoutScanConfiguration; -import org.springframework.boot.context.configwarnings.InRealPackageConfiguration; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer.ComponentScanPackageCheck; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageConfiguration; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageWithBasePackageClassesConfiguration; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageWithBasePackagesConfiguration; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageWithMetaAnnotationConfiguration; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageWithValueConfiguration; +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageWithoutScanConfiguration; +import org.springframework.boot.context.configwarnings.orgspring.InOrgSpringPackageConfiguration; +import org.springframework.boot.context.configwarnings.real.InRealButScanningProblemPackages; +import org.springframework.boot.context.configwarnings.real.InRealPackageConfiguration; import org.springframework.boot.test.OutputCapture; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -41,8 +47,11 @@ import static org.junit.Assert.assertThat; */ public class ConfigurationWarningsApplicationContextInitializerTests { - private static final String SCAN_WARNING = "Your ApplicationContext is unlikely to " - + "start due to a @ComponentScan of the default package"; + private static final String DEFAULT_SCAN_WARNING = "Your ApplicationContext is unlikely to " + + "start due to a @ComponentScan of the default package."; + + private static final String ORGSPRING_SCAN_WARNING = "Your ApplicationContext is unlikely to " + + "start due to a @ComponentScan of 'org.springframework'."; @Rule public OutputCapture output = new OutputCapture(); @@ -50,43 +59,58 @@ public class ConfigurationWarningsApplicationContextInitializerTests { @Test public void logWarningInDefaultPackage() { load(InDefaultPackageConfiguration.class); - assertThat(this.output.toString(), containsString(SCAN_WARNING)); + assertThat(this.output.toString(), containsString(DEFAULT_SCAN_WARNING)); } @Test public void logWarningInDefaultPackageAndMetaAnnotation() { load(InDefaultPackageWithMetaAnnotationConfiguration.class); - assertThat(this.output.toString(), containsString(SCAN_WARNING)); + assertThat(this.output.toString(), containsString(DEFAULT_SCAN_WARNING)); } @Test public void noLogIfInRealPackage() throws Exception { load(InRealPackageConfiguration.class); - assertThat(this.output.toString(), not(containsString(SCAN_WARNING))); + assertThat(this.output.toString(), not(containsString(DEFAULT_SCAN_WARNING))); } @Test public void noLogWithoutComponentScanAnnotation() throws Exception { load(InDefaultPackageWithoutScanConfiguration.class); - assertThat(this.output.toString(), not(containsString(SCAN_WARNING))); + assertThat(this.output.toString(), not(containsString(DEFAULT_SCAN_WARNING))); } @Test public void noLogIfHasValue() throws Exception { load(InDefaultPackageWithValueConfiguration.class); - assertThat(this.output.toString(), not(containsString(SCAN_WARNING))); + assertThat(this.output.toString(), not(containsString(DEFAULT_SCAN_WARNING))); } @Test public void noLogIfHasBasePackages() throws Exception { load(InDefaultPackageWithBasePackagesConfiguration.class); - assertThat(this.output.toString(), not(containsString(SCAN_WARNING))); + assertThat(this.output.toString(), not(containsString(DEFAULT_SCAN_WARNING))); } @Test public void noLogIfHasBasePackageClasses() throws Exception { load(InDefaultPackageWithBasePackageClassesConfiguration.class); - assertThat(this.output.toString(), not(containsString(SCAN_WARNING))); + assertThat(this.output.toString(), not(containsString(DEFAULT_SCAN_WARNING))); + } + + @Test + public void logWarningInOrgSpringPackage() { + load(InOrgSpringPackageConfiguration.class); + assertThat(this.output.toString(), containsString(ORGSPRING_SCAN_WARNING)); + } + + @Test + public void logWarningIfScanningProblemPackages() throws Exception { + load(InRealButScanningProblemPackages.class); + assertThat(this.output.toString(), + containsString("Your ApplicationContext is unlikely to start due to a " + + "@ComponentScan of the default package, 'org.springframework'.")); + } private void load(Class configClass) { @@ -121,12 +145,25 @@ public class ConfigurationWarningsApplicationContextInitializerTests { * Testable ComponentScanDefaultPackageCheck that doesn't need to use the default * package. */ - static class TestComponentScanDefaultPackageCheck - extends ComponentScanDefaultPackageCheck { + static class TestComponentScanDefaultPackageCheck extends ComponentScanPackageCheck { @Override - protected boolean isInDefaultPackage(String className) { - return className.contains("InDefault"); + protected Set getComponentScanningPackages( + BeanDefinitionRegistry registry) { + Set scannedPackages = super.getComponentScanningPackages(registry); + Set result = new LinkedHashSet(); + for (String scannedPackage : scannedPackages) { + if (scannedPackage.endsWith("dflt")) { + result.add(""); + } + if (scannedPackage.endsWith("orgspring")) { + result.add("org.springframework"); + } + else { + result.add(scannedPackage); + } + } + return result; } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/MetaComponentScan.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/annotation/MetaComponentScan.java similarity index 93% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/MetaComponentScan.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/annotation/MetaComponentScan.java index f48a73bded..ace8606621 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/MetaComponentScan.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/annotation/MetaComponentScan.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageConfiguration.java similarity index 92% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageConfiguration.java index d7f3f213a1..9f3ed92e84 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackageClassesConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackageClassesConfiguration.java similarity index 86% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackageClassesConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackageClassesConfiguration.java index 212974fd8a..517fc19d16 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackageClassesConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackageClassesConfiguration.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; -import org.springframework.boot.context.configwarnings.nested.ExampleBean; +import org.springframework.boot.context.configwarnings.real.nested.ExampleBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackagesConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackagesConfiguration.java similarity index 93% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackagesConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackagesConfiguration.java index e4224b4da2..ec69a08f48 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithBasePackagesConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithBasePackagesConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithMetaAnnotationConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithMetaAnnotationConfiguration.java similarity index 84% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithMetaAnnotationConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithMetaAnnotationConfiguration.java index 6e71bbc7eb..986541024c 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithMetaAnnotationConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithMetaAnnotationConfiguration.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; +import org.springframework.boot.context.configwarnings.annotation.MetaComponentScan; import org.springframework.context.annotation.Configuration; @Configuration diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithValueConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithValueConfiguration.java similarity index 93% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithValueConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithValueConfiguration.java index fcee1813fe..49f9db9088 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithValueConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithValueConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithoutScanConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithoutScanConfiguration.java similarity index 92% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithoutScanConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithoutScanConfiguration.java index 8cebbc17a9..637a37f91a 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InDefaultPackageWithoutScanConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/dflt/InDefaultPackageWithoutScanConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.dflt; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/orgspring/InOrgSpringPackageConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/orgspring/InOrgSpringPackageConfiguration.java new file mode 100644 index 0000000000..2c5ece9f4b --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/orgspring/InOrgSpringPackageConfiguration.java @@ -0,0 +1,25 @@ +/* + * Copyright 2012-2014 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.context.configwarnings.orgspring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +public class InOrgSpringPackageConfiguration { +} diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealButScanningProblemPackages.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealButScanningProblemPackages.java new file mode 100644 index 0000000000..e6c0f96272 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealButScanningProblemPackages.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.context.configwarnings.real; + +import org.springframework.boot.context.configwarnings.dflt.InDefaultPackageConfiguration; +import org.springframework.boot.context.configwarnings.orgspring.InOrgSpringPackageConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackageClasses = { InDefaultPackageConfiguration.class, + InOrgSpringPackageConfiguration.class }) +public class InRealButScanningProblemPackages { + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InRealPackageConfiguration.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealPackageConfiguration.java similarity index 92% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InRealPackageConfiguration.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealPackageConfiguration.java index 9a575421b4..8f6664b6d5 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/InRealPackageConfiguration.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/InRealPackageConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings; +package org.springframework.boot.context.configwarnings.real; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/nested/ExampleBean.java b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/nested/ExampleBean.java similarity index 91% rename from spring-boot/src/test/java/org/springframework/boot/context/configwarnings/nested/ExampleBean.java rename to spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/nested/ExampleBean.java index abce686f2b..52006c7e2b 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/nested/ExampleBean.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/configwarnings/real/nested/ExampleBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.context.configwarnings.nested; +package org.springframework.boot.context.configwarnings.real.nested; import org.springframework.stereotype.Component;