21
21
import java .beans .Introspector ;
22
22
import java .beans .PropertyDescriptor ;
23
23
import java .lang .reflect .Constructor ;
24
- import java .lang .reflect .Field ;
25
24
import java .lang .reflect .Method ;
26
25
import java .util .Arrays ;
27
26
import java .util .Collection ;
35
34
import org .springframework .beans .ExtendedBeanInfoFactory ;
36
35
import org .springframework .boot .context .properties .bind .Bindable ;
37
36
import org .springframework .core .ResolvableType ;
38
- import org .springframework .core .annotation .MergedAnnotations ;
39
- import org .springframework .util .ReflectionUtils ;
40
37
41
38
/**
42
39
* Registers a given type on {@link ReflectionHints} for binding purposes, discovering any
43
- * nested type it may expose via a property.
40
+ * referenced types it may expose via a property.
44
41
*
45
42
* @author Andy Wilkinson
46
43
* @author Moritz Halbritter
@@ -77,12 +74,22 @@ public static void processConfigurationProperties(Class<?> type, ReflectionHints
77
74
.process (reflectionHints );
78
75
}
79
76
80
- private void processNestedType (Class <?> type , ReflectionHints reflectionHints ) {
81
- processNestedType (type , getBindConstructor (type , true ), reflectionHints );
77
+ private void processType (Class <?> type , ReflectionHints reflectionHints ) {
78
+ if (isTypeIgnored (type )) {
79
+ return ;
80
+ }
81
+ new ConfigurationPropertiesReflectionHintsProcessor (type , getBindConstructor (type , true ), this .seen )
82
+ .process (reflectionHints );
82
83
}
83
84
84
- private void processNestedType (Class <?> type , Constructor <?> bindConstructor , ReflectionHints reflectionHints ) {
85
- new ConfigurationPropertiesReflectionHintsProcessor (type , bindConstructor , this .seen ).process (reflectionHints );
85
+ private boolean isTypeIgnored (Class <?> type ) {
86
+ if (type .getPackageName ().startsWith ("java." )) {
87
+ return true ;
88
+ }
89
+ if (type .isInterface ()) {
90
+ return true ;
91
+ }
92
+ return false ;
86
93
}
87
94
88
95
private static Constructor <?> getBindConstructor (Class <?> type , boolean nestedType ) {
@@ -118,9 +125,8 @@ private void handleConstructor(ReflectionHints reflectionHints) {
118
125
119
126
private void handleValueObjectProperties (ReflectionHints reflectionHints ) {
120
127
for (int i = 0 ; i < this .bindConstructor .getParameterCount (); i ++) {
121
- String propertyName = this .bindConstructor .getParameters ()[i ].getName ();
122
128
ResolvableType propertyType = ResolvableType .forConstructorParameter (this .bindConstructor , i );
123
- handleProperty (reflectionHints , propertyName , propertyType );
129
+ registerType (reflectionHints , propertyType );
124
130
}
125
131
}
126
132
@@ -129,16 +135,12 @@ private void handleJavaBeanProperties(ReflectionHints reflectionHints) {
129
135
Method readMethod = propertyDescriptor .getReadMethod ();
130
136
if (readMethod != null ) {
131
137
ResolvableType propertyType = ResolvableType .forMethodReturnType (readMethod , this .type );
132
- String propertyName = propertyDescriptor .getName ();
133
- if (isSetterMandatory (propertyName , propertyType ) && propertyDescriptor .getWriteMethod () == null ) {
134
- continue ;
135
- }
136
- handleProperty (reflectionHints , propertyName , propertyType );
138
+ registerType (reflectionHints , propertyType );
137
139
}
138
140
}
139
141
}
140
142
141
- private void handleProperty (ReflectionHints reflectionHints , String propertyName , ResolvableType propertyType ) {
143
+ private void registerType (ReflectionHints reflectionHints , ResolvableType propertyType ) {
142
144
Class <?> propertyClass = propertyType .resolve ();
143
145
if (propertyClass == null ) {
144
146
return ;
@@ -148,25 +150,11 @@ private void handleProperty(ReflectionHints reflectionHints, String propertyName
148
150
}
149
151
Class <?> componentType = getComponentType (propertyType );
150
152
if (componentType != null ) {
151
- // Can be a list of simple types
152
- if (!isJavaType (componentType )) {
153
- processNestedType (componentType , reflectionHints );
154
- }
155
- }
156
- else if (isNestedType (propertyName , propertyClass )) {
157
- processNestedType (propertyClass , reflectionHints );
158
- }
159
- }
160
-
161
- private boolean isSetterMandatory (String propertyName , ResolvableType propertyType ) {
162
- Class <?> propertyClass = propertyType .resolve ();
163
- if (propertyClass == null ) {
164
- return true ;
153
+ processType (componentType , reflectionHints );
165
154
}
166
- if ( getComponentType ( propertyType ) != null ) {
167
- return false ;
155
+ else {
156
+ processType ( propertyClass , reflectionHints ) ;
168
157
}
169
- return !isNestedType (propertyName , propertyClass );
170
158
}
171
159
172
160
private Class <?> getComponentType (ResolvableType propertyType ) {
@@ -183,27 +171,6 @@ else if (Map.class.isAssignableFrom(propertyClass)) {
183
171
return null ;
184
172
}
185
173
186
- /**
187
- * Specify whether the specified property refer to a nested type. A nested type
188
- * represents a sub-namespace that need to be fully resolved.
189
- * @param propertyName the name of the property
190
- * @param propertyType the type of the property
191
- * @return whether the specified {@code propertyType} is a nested type
192
- */
193
- private boolean isNestedType (String propertyName , Class <?> propertyType ) {
194
- if (this .type .equals (propertyType .getDeclaringClass ())) {
195
- return true ;
196
- }
197
- else {
198
- Field field = ReflectionUtils .findField (this .type , propertyName );
199
- return field != null && MergedAnnotations .from (field ).isPresent (NestedConfigurationProperty .class );
200
- }
201
- }
202
-
203
- private boolean isJavaType (Class <?> candidate ) {
204
- return candidate .getPackageName ().startsWith ("java." );
205
- }
206
-
207
174
private static BeanInfo getBeanInfo (Class <?> beanType ) {
208
175
try {
209
176
BeanInfo beanInfo = beanInfoFactory .getBeanInfo (beanType );
0 commit comments