Detect nested configuration classes even for empty outer classes

Issue: SPR-16839
This commit is contained in:
Juergen Hoeller
2018-05-29 21:47:53 +02:00
parent 69f14a2038
commit 5bbeadec0c
2 changed files with 118 additions and 3 deletions

View File

@@ -78,7 +78,9 @@ abstract class ConfigurationClassUtils {
* @param metadataReaderFactory the current factory in use by the caller
* @return whether the candidate qualifies as (any kind of) configuration class
*/
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
@@ -103,7 +105,8 @@ abstract class ConfigurationClassUtils {
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
@@ -116,7 +119,7 @@ abstract class ConfigurationClassUtils {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
return hasNestedConfigurationClass(metadata, metadataReaderFactory);
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
@@ -128,6 +131,40 @@ abstract class ConfigurationClassUtils {
return true;
}
/**
* Check whether the specified class declares a nested configuration class.
*/
private static boolean hasNestedConfigurationClass(
AnnotationMetadata metadata, MetadataReaderFactory metadataReaderFactory) {
// Potentially nested configuration classes...
if (metadata instanceof StandardAnnotationMetadata) {
Class<?> beanClass = ((StandardAnnotationMetadata) metadata).getIntrospectedClass();
for (Class<?> memberClass : beanClass.getDeclaredClasses()) {
if (isConfigurationCandidate(new StandardAnnotationMetadata(memberClass))) {
return true;
}
}
}
else {
for (String memberName : metadata.getMemberClassNames()) {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(memberName);
if (isConfigurationCandidate(metadataReader.getAnnotationMetadata())) {
return true;
}
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
memberName, ex);
}
}
}
}
return false;
}
/**
* Check the given metadata for a configuration class candidate
* (or nested component class declared within a configuration/component class).