diff --git a/README.md b/README.md index d8e0e3a2..c8f10ef5 100644 --- a/README.md +++ b/README.md @@ -110,8 +110,8 @@ Choose the version that matches your Spring Boot generation: | Branch | Spring Boot Compatibility | Latest Version | |--------|---------------------------|----------------| -| `main` | 3.0.x – 3.5.x, 4.1.x | `0.2.27` | -| `1.x` | 2.0.x – 2.7.x | `0.1.27` | +| `main` | 3.0.x – 3.5.x, 4.1.x | `0.2.28` | +| `1.x` | 2.0.x – 2.7.x | `0.1.28` | ### Add Module Dependencies diff --git a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContext.java b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContext.java index 4c91ea34..fe982be0 100644 --- a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContext.java +++ b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContext.java @@ -176,7 +176,7 @@ String getPrefix() { */ @Nonnull Class getBeanClass() { - return getBeanType().getRawClass(); + return getBeanType().resolve(); } void initializeBean(Object bean) { @@ -209,7 +209,7 @@ private void initBeanProperties() { } private void initBeanProperties(ResolvableType beanType, ConfigurationPropertyName prefixName, String nestedPath) { - Class beanClass = beanType.getRawClass(); + Class beanClass = beanType.resolve(); if (isCandidateClass(beanClass)) { Constructor bindConstructor = this.bindConstructor; if (bindConstructor == null) { @@ -544,8 +544,14 @@ static String buildPropertyPath(String propertyName, @Nullable String nestedPath * @return {@code true} if the property is a binding candidate, {@code false} otherwise */ static boolean isCandidateProperty(PropertyDescriptor descriptor) { + if (descriptor == null) { + return false; + } Method readMethod = descriptor.getReadMethod(); - return readMethod == null || !Object.class.equals(readMethod.getDeclaringClass()); + if (readMethod == null) { + return false; + } + return !Object.class.equals(readMethod.getDeclaringClass()); } /** @@ -563,6 +569,9 @@ static boolean isCandidateProperty(PropertyDescriptor descriptor) { * @return {@code true} if the class is a binding candidate, {@code false} otherwise */ static boolean isCandidateClass(Class beanClass) { + if (beanClass == null) { + return false; + } if (isPrimitiveOrWrapper(beanClass) || beanClass.isEnum()) { return false; } diff --git a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/EventPublishingConfigurationPropertiesBeanPropertyChangedListener.java b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/EventPublishingConfigurationPropertiesBeanPropertyChangedListener.java index 82982aa4..f1bcd925 100644 --- a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/EventPublishingConfigurationPropertiesBeanPropertyChangedListener.java +++ b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/properties/bind/EventPublishingConfigurationPropertiesBeanPropertyChangedListener.java @@ -50,8 +50,7 @@ * @see ConfigurationPropertiesBeanPropertyChangedEvent * @since 1.0.0 */ -public class EventPublishingConfigurationPropertiesBeanPropertyChangedListener implements BindListener, - ApplicationContextAware, InitializingBean, SmartInitializingSingleton { +public class EventPublishingConfigurationPropertiesBeanPropertyChangedListener implements BindListener, ApplicationContextAware, InitializingBean, SmartInitializingSingleton { private static final Logger logger = getLogger(EventPublishingConfigurationPropertiesBeanPropertyChangedListener.class); @@ -190,4 +189,4 @@ public void afterSingletonsInstantiated() { public boolean isBound() { return bound; } -} \ No newline at end of file +} diff --git a/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContextTest.java b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContextTest.java index 75b8b1af..c5ebf669 100644 --- a/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContextTest.java +++ b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/context/properties/bind/ConfigurationPropertiesBeanContextTest.java @@ -31,8 +31,10 @@ import org.springframework.core.annotation.AnnotationAttributes; import java.beans.PropertyDescriptor; +import java.util.concurrent.TimeUnit; import static io.microsphere.spring.boot.context.properties.bind.ConfigurationPropertiesBeanContext.getInstance; +import static io.microsphere.spring.boot.context.properties.bind.ConfigurationPropertiesBeanContext.isCandidateClass; import static io.microsphere.spring.boot.context.properties.bind.ConfigurationPropertiesBeanContext.isCandidateProperty; import static io.microsphere.spring.core.annotation.AnnotationUtils.getAnnotationAttributes; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -144,11 +146,33 @@ void testGetInstance() { @Test void testIsCandidateProperty() { + assertFalse(isCandidateProperty(null)); PropertyDescriptor descriptor = getPropertyDescriptor(ConfigurationPropertiesBeanContextTest.class, "name"); - assertTrue(isCandidateProperty(descriptor)); + assertFalse(isCandidateProperty(descriptor)); + + descriptor = getPropertyDescriptor(ConfigurationPropertiesBeanContextTest.class, "not-found"); + assertFalse(isCandidateProperty(descriptor)); descriptor = getPropertyDescriptor(ConfigurationPropertiesBeanContextTest.class, "class"); assertFalse(isCandidateProperty(descriptor)); + + descriptor = getPropertyDescriptor(ServerProperties.class, "port"); + assertTrue(isCandidateProperty(descriptor)); + } + + @Test + void testIsCandidateClass() { + // null + assertFalse(isCandidateClass(null)); + // primitive type and wrapper type are not candidate class + assertFalse(isCandidateClass(int.class)); + assertFalse(isCandidateClass(Integer.class)); + // enumeration type + assertFalse(isCandidateClass(TimeUnit.class)); + // String is candidate class,but is under java.lang package. + assertFalse(isCandidateClass(String.class)); + // current class + assertTrue(isCandidateClass(getClass())); } public void setName(String name) {