11/*
2- * Copyright 2002-2017 the original author or authors.
2+ * Copyright 2002-2018 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
@@ -244,6 +244,27 @@ private static boolean isUnderneathClassLoader(@Nullable ClassLoader candidate,
244244 return false ;
245245 }
246246
247+ /**
248+ * Retrieve a {@link BeanInfo} descriptor for the given target class.
249+ * @param beanClass the target class to introspect
250+ * @param ignoreBeaninfoClasses whether to apply {@link Introspector#IGNORE_ALL_BEANINFO} mode
251+ * @return the resulting {@code BeanInfo} descriptor (never {@code null})
252+ * @throws IntrospectionException from the underlying {@link Introspector}
253+ */
254+ private static BeanInfo getBeanInfo (Class <?> beanClass , boolean ignoreBeaninfoClasses )
255+ throws IntrospectionException {
256+
257+ for (BeanInfoFactory beanInfoFactory : beanInfoFactories ) {
258+ BeanInfo beanInfo = beanInfoFactory .getBeanInfo (beanClass );
259+ if (beanInfo != null ) {
260+ return beanInfo ;
261+ }
262+ }
263+ return (ignoreBeaninfoClasses ?
264+ Introspector .getBeanInfo (beanClass , Introspector .IGNORE_ALL_BEANINFO ) :
265+ Introspector .getBeanInfo (beanClass ));
266+ }
267+
247268
248269 /** The BeanInfo object for the introspected bean class */
249270 private final BeanInfo beanInfo ;
@@ -265,21 +286,7 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
265286 if (logger .isTraceEnabled ()) {
266287 logger .trace ("Getting BeanInfo for class [" + beanClass .getName () + "]" );
267288 }
268-
269- BeanInfo beanInfo = null ;
270- for (BeanInfoFactory beanInfoFactory : beanInfoFactories ) {
271- beanInfo = beanInfoFactory .getBeanInfo (beanClass );
272- if (beanInfo != null ) {
273- break ;
274- }
275- }
276- if (beanInfo == null ) {
277- // If none of the factories supported the class, fall back to the default
278- beanInfo = (shouldIntrospectorIgnoreBeaninfoClasses ?
279- Introspector .getBeanInfo (beanClass , Introspector .IGNORE_ALL_BEANINFO ) :
280- Introspector .getBeanInfo (beanClass ));
281- }
282- this .beanInfo = beanInfo ;
289+ this .beanInfo = getBeanInfo (beanClass , shouldIntrospectorIgnoreBeaninfoClasses );
283290
284291 if (logger .isTraceEnabled ()) {
285292 logger .trace ("Caching PropertyDescriptors for class [" + beanClass .getName () + "]" );
@@ -307,15 +314,17 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
307314 // Explicitly check implemented interfaces for setter/getter methods as well,
308315 // in particular for Java 8 default methods...
309316 Class <?> clazz = beanClass ;
310- while (clazz != null ) {
317+ while (clazz != null && clazz != Object . class ) {
311318 Class <?>[] ifcs = clazz .getInterfaces ();
312319 for (Class <?> ifc : ifcs ) {
313- BeanInfo ifcInfo = Introspector .getBeanInfo (ifc , Introspector .IGNORE_ALL_BEANINFO );
314- PropertyDescriptor [] ifcPds = ifcInfo .getPropertyDescriptors ();
315- for (PropertyDescriptor pd : ifcPds ) {
316- if (!this .propertyDescriptorCache .containsKey (pd .getName ())) {
317- pd = buildGenericTypeAwarePropertyDescriptor (beanClass , pd );
318- this .propertyDescriptorCache .put (pd .getName (), pd );
320+ if (!ClassUtils .isJavaLanguageInterface (ifc )) {
321+ BeanInfo ifcInfo = getBeanInfo (ifc , true );
322+ PropertyDescriptor [] ifcPds = ifcInfo .getPropertyDescriptors ();
323+ for (PropertyDescriptor pd : ifcPds ) {
324+ if (!this .propertyDescriptorCache .containsKey (pd .getName ())) {
325+ pd = buildGenericTypeAwarePropertyDescriptor (beanClass , pd );
326+ this .propertyDescriptorCache .put (pd .getName (), pd );
327+ }
319328 }
320329 }
321330 }
@@ -329,6 +338,7 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
329338 }
330339 }
331340
341+
332342 BeanInfo getBeanInfo () {
333343 return this .beanInfo ;
334344 }
0 commit comments