diff --git a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java index 02f4ec7200..04df5ad2cf 100644 --- a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java +++ b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java @@ -19,12 +19,10 @@ package org.springframework.beans; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; -import java.beans.SimpleBeanInfo; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; import java.security.ProtectionDomain; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; @@ -79,12 +77,11 @@ import org.springframework.util.StringUtils; */ public final class CachedIntrospectionResults { - private static final PropertyDescriptor[] EMPTY_PROPERTY_DESCRIPTOR_ARRAY = {}; - - private static final List beanInfoFactories = SpringFactoriesLoader.loadFactories( BeanInfoFactory.class, CachedIntrospectionResults.class.getClassLoader()); + private static final SimpleBeanInfoFactory simpleBeanInfoFactory = new SimpleBeanInfoFactory(); + private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class); /** @@ -228,14 +225,7 @@ public final class CachedIntrospectionResults { return beanInfo; } } - - Collection pds = PropertyDescriptorUtils.determineBasicProperties(beanClass); - return new SimpleBeanInfo() { - @Override - public PropertyDescriptor[] getPropertyDescriptors() { - return pds.toArray(EMPTY_PROPERTY_DESCRIPTOR_ARRAY); - } - }; + return simpleBeanInfoFactory.getBeanInfo(beanClass); } @@ -405,7 +395,7 @@ public final class CachedIntrospectionResults { } PropertyDescriptor[] getPropertyDescriptors() { - return this.propertyDescriptors.values().toArray(EMPTY_PROPERTY_DESCRIPTOR_ARRAY); + return this.propertyDescriptors.values().toArray(PropertyDescriptorUtils.EMPTY_PROPERTY_DESCRIPTOR_ARRAY); } private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class beanClass, PropertyDescriptor pd) { diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java index a5d760380b..32d9d93f5d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java @@ -36,6 +36,9 @@ import org.springframework.util.StringUtils; */ abstract class PropertyDescriptorUtils { + public static final PropertyDescriptor[] EMPTY_PROPERTY_DESCRIPTOR_ARRAY = {}; + + /** * Simple introspection algorithm for basic set/get/is accessor methods, * building corresponding JavaBeans property descriptors for them. @@ -46,6 +49,7 @@ abstract class PropertyDescriptorUtils { * @return a collection of property descriptors * @throws IntrospectionException from introspecting the given bean class * @since 6.0 + * @see SimpleBeanInfoFactory * @see java.beans.Introspector#getBeanInfo(Class) */ public static Collection determineBasicProperties(Class beanClass) throws IntrospectionException { diff --git a/spring-beans/src/main/java/org/springframework/beans/SimpleBeanInfoFactory.java b/spring-beans/src/main/java/org/springframework/beans/SimpleBeanInfoFactory.java new file mode 100644 index 0000000000..c2835bc797 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/SimpleBeanInfoFactory.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2022 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.beans; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.beans.SimpleBeanInfo; +import java.util.Collection; + +import org.springframework.core.Ordered; +import org.springframework.lang.NonNull; + +/** + * {@link BeanInfoFactory} implementation that bypasses the standard {@link java.beans.Introspector} + * for faster introspection, reduced to basic property determination (as commonly needed in Spring). + * + *

Used by default in 6.0 through direct invocation from {@link CachedIntrospectionResults}. + * Potentially configured via a {@code META-INF/spring.factories} file with the following content, + * overriding other custom {@code org.springframework.beans.BeanInfoFactory} declarations: + * {@code org.springframework.beans.BeanInfoFactory=org.springframework.beans.SimpleBeanInfoFactory} + * + *

Ordered at {@code Ordered.LOWEST_PRECEDENCE - 1} to override {@link ExtendedBeanInfoFactory} + * (registered by default in 5.3) if necessary while still allowing other user-defined + * {@link BeanInfoFactory} types to take precedence. + * + * @author Juergen Hoeller + * @since 6.0 + * @see ExtendedBeanInfoFactory + * @see CachedIntrospectionResults + */ +class SimpleBeanInfoFactory implements BeanInfoFactory, Ordered { + + @Override + @NonNull + public BeanInfo getBeanInfo(Class beanClass) throws IntrospectionException { + Collection pds = PropertyDescriptorUtils.determineBasicProperties(beanClass); + return new SimpleBeanInfo() { + @Override + public PropertyDescriptor[] getPropertyDescriptors() { + return pds.toArray(PropertyDescriptorUtils.EMPTY_PROPERTY_DESCRIPTOR_ARRAY); + } + }; + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE - 1; + } + +}