2929import java .beans .SimpleBeanInfo ;
3030import java .lang .reflect .Method ;
3131import java .lang .reflect .Modifier ;
32- import java .util . Arrays ;
32+ import java .lang . reflect . Type ;
3333import java .util .Collection ;
34- import java .util .LinkedHashSet ;
35- import java .util .Set ;
34+ import java .util .LinkedHashMap ;
35+ import java .util .Map ;
3636
3737import org .springframework .beans .BeanInfoFactory ;
3838import org .springframework .beans .BeanUtils ;
3939import org .springframework .core .KotlinDetector ;
4040import org .springframework .core .Ordered ;
41+ import org .springframework .lang .Nullable ;
42+ import org .springframework .util .ClassUtils ;
43+ import org .springframework .util .ReflectionUtils ;
44+ import org .springframework .util .StringUtils ;
4145
4246/**
4347 * {@link BeanInfoFactory} specific to Kotlin types using Kotlin reflection to determine bean properties.
@@ -62,7 +66,7 @@ public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
6266
6367 KClass <?> kotlinClass = JvmClassMappingKt .getKotlinClass (beanClass );
6468 Collection <KCallable <?>> members = kotlinClass .getMembers ();
65- Set < PropertyDescriptor > pds = new LinkedHashSet <>(members .size ());
69+ Map < String , PropertyDescriptor > descriptors = new LinkedHashMap <>(members .size (), 1.f );
6670
6771 for (KCallable <?> member : members ) {
6872
@@ -71,6 +75,16 @@ public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
7175 Method getter = ReflectJvmMapping .getJavaGetter (property );
7276 Method setter = property instanceof KMutableProperty <?> kmp ? ReflectJvmMapping .getJavaSetter (kmp ) : null ;
7377
78+ if (getter == null ) {
79+ Type javaType = ReflectJvmMapping .getJavaType (property .getReturnType ());
80+ getter = ReflectionUtils .findMethod (beanClass ,
81+ javaType == Boolean .TYPE ? "is" : "get" + StringUtils .capitalize (property .getName ()));
82+ }
83+
84+ if (getter != null ) {
85+ getter = ClassUtils .getMostSpecificMethod (getter , beanClass );
86+ }
87+
7488 if (getter != null && (Modifier .isStatic (getter .getModifiers ()) || getter .getParameterCount () != 0 )) {
7589 continue ;
7690 }
@@ -82,7 +96,7 @@ public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
8296 }
8397 }
8498
85- pds . add ( new PropertyDescriptor (property .getName (), getter , setter ));
99+ descriptors . put ( property . getName (), new PropertyDescriptor (property .getName (), getter , setter ));
86100 }
87101 }
88102
@@ -95,9 +109,17 @@ public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
95109 if (javaClass != Object .class ) {
96110
97111 PropertyDescriptor [] javaPropertyDescriptors = BeanUtils .getPropertyDescriptors (javaClass );
98- pds .addAll (Arrays .asList (javaPropertyDescriptors ));
112+
113+ for (PropertyDescriptor descriptor : javaPropertyDescriptors ) {
114+
115+ descriptor = new PropertyDescriptor (descriptor .getName (), specialize (beanClass , descriptor .getReadMethod ()),
116+ specialize (beanClass , descriptor .getWriteMethod ()));
117+ descriptors .put (descriptor .getName (), descriptor );
118+ }
99119 }
100120
121+ PropertyDescriptor [] propertyDescriptors = descriptors .values ().toArray (new PropertyDescriptor [0 ]);
122+
101123 return new SimpleBeanInfo () {
102124 @ Override
103125 public BeanDescriptor getBeanDescriptor () {
@@ -106,11 +128,21 @@ public BeanDescriptor getBeanDescriptor() {
106128
107129 @ Override
108130 public PropertyDescriptor [] getPropertyDescriptors () {
109- return pds . toArray ( new PropertyDescriptor [ 0 ]) ;
131+ return propertyDescriptors ;
110132 }
111133 };
112134 }
113135
136+ @ Nullable
137+ private static Method specialize (Class <?> beanClass , @ Nullable Method method ) {
138+
139+ if (method == null ) {
140+ return method ;
141+ }
142+
143+ return ClassUtils .getMostSpecificMethod (method , beanClass );
144+ }
145+
114146 @ Override
115147 public int getOrder () {
116148 return LOWEST_PRECEDENCE - 10 ; // leave some space for customizations.
0 commit comments