From c11abf48d9744e9af48417fe41a5459af955c3fd Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sat, 6 Jun 2020 11:59:36 -0700 Subject: [PATCH] Polish 'Allow beans without public constructors to load' See gh-20929 --- .../boot/BeanDefinitionLoader.java | 17 ++++++++++++++--- .../boot/BeanDefinitionLoaderTests.java | 1 + .../boot/sampleconfig/MyNamedComponent.java | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java index 97a6752dcdf..4627965ee64 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java @@ -17,6 +17,7 @@ package org.springframework.boot; import java.io.IOException; +import java.lang.reflect.Constructor; import java.util.HashSet; import java.util.Set; @@ -41,6 +42,7 @@ import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilte import org.springframework.core.type.filter.TypeFilter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -151,7 +153,7 @@ class BeanDefinitionLoader { GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class); load(loader); } - if (isComponent(source)) { + if (isEligible(source)) { this.annotatedReader.register(source); return 1; } @@ -277,8 +279,17 @@ class BeanDefinitionLoader { * @return true if the given bean type is eligible for registration, i.e. not a groovy * closure nor an anonymous class */ - private boolean isComponent(Class type) { - return !type.getName().matches(".*\\$_.*closure.*") && !type.isAnonymousClass(); + private boolean isEligible(Class type) { + return !(type.isAnonymousClass() || isGroovyClosure(type) || hasNoConstructors(type)); + } + + private boolean isGroovyClosure(Class type) { + return type.getName().matches(".*\\$_.*closure.*"); + } + + private boolean hasNoConstructors(Class type) { + Constructor[] constructors = type.getDeclaredConstructors(); + return ObjectUtils.isEmpty(constructors); } /** diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/BeanDefinitionLoaderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/BeanDefinitionLoaderTests.java index 6d1f0f28143..7ddf590749b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/BeanDefinitionLoaderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/BeanDefinitionLoaderTests.java @@ -58,6 +58,7 @@ class BeanDefinitionLoaderTests { @Test void anonymousClassNotLoaded() { MyComponent myComponent = new MyComponent() { + }; BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry, myComponent.getClass()); assertThat(loader.load()).isEqualTo(0); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sampleconfig/MyNamedComponent.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sampleconfig/MyNamedComponent.java index f04a455db7c..662c3869ec9 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sampleconfig/MyNamedComponent.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sampleconfig/MyNamedComponent.java @@ -22,7 +22,6 @@ import javax.inject.Named; public class MyNamedComponent { MyNamedComponent() { - } }