37
37
import org .springframework .javapoet .CodeBlock ;
38
38
import org .springframework .javapoet .CodeBlock .Builder ;
39
39
import org .springframework .javapoet .MethodSpec ;
40
+ import org .springframework .javapoet .ParameterizedTypeName ;
40
41
import org .springframework .util .ClassUtils ;
41
42
import org .springframework .util .function .ThrowingSupplier ;
42
43
@@ -108,21 +109,22 @@ CodeBlock generateCode(RegisteredBean registeredBean,
108
109
private CodeBlock generateCodeForConstructor (RegisteredBean registeredBean ,
109
110
Constructor <?> constructor ) {
110
111
111
- String name = registeredBean .getBeanName ();
112
+ String beanName = registeredBean .getBeanName ();
113
+ Class <?> beanClass = registeredBean .getBeanClass ();
112
114
Class <?> declaringClass = ClassUtils
113
115
.getUserClass (constructor .getDeclaringClass ());
114
116
boolean dependsOnBean = ClassUtils .isInnerClass (declaringClass );
115
117
AccessVisibility accessVisibility = getAccessVisibility (registeredBean ,
116
118
constructor );
117
119
if (accessVisibility == AccessVisibility .PUBLIC
118
120
|| accessVisibility == AccessVisibility .PACKAGE_PRIVATE ) {
119
- return generateCodeForAccessibleConstructor (name , constructor , dependsOnBean ,
120
- declaringClass );
121
+ return generateCodeForAccessibleConstructor (beanName , beanClass , constructor ,
122
+ dependsOnBean , declaringClass );
121
123
}
122
- return generateCodeForInaccessibleConstructor (name , constructor , dependsOnBean );
124
+ return generateCodeForInaccessibleConstructor (beanName , beanClass , constructor , dependsOnBean );
123
125
}
124
126
125
- private CodeBlock generateCodeForAccessibleConstructor (String name ,
127
+ private CodeBlock generateCodeForAccessibleConstructor (String beanName , Class <?> beanClass ,
126
128
Constructor <?> constructor , boolean dependsOnBean , Class <?> declaringClass ) {
127
129
128
130
this .generationContext .getRuntimeHints ().reflection ()
@@ -139,37 +141,36 @@ private CodeBlock generateCodeForAccessibleConstructor(String name,
139
141
declaringClass );
140
142
}
141
143
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod (method ->
142
- buildGetInstanceMethodForConstructor (method , name , constructor ,
144
+ buildGetInstanceMethodForConstructor (method , beanName , beanClass , constructor ,
143
145
declaringClass , dependsOnBean , PRIVATE_STATIC ));
144
146
return generateReturnStatement (generatedMethod );
145
147
}
146
148
147
- private CodeBlock generateCodeForInaccessibleConstructor (String name ,
148
- Constructor <?> constructor , boolean dependsOnBean ) {
149
+ private CodeBlock generateCodeForInaccessibleConstructor (String beanName ,
150
+ Class <?> beanClass , Constructor <?> constructor , boolean dependsOnBean ) {
149
151
150
152
this .generationContext .getRuntimeHints ().reflection ()
151
153
.registerConstructor (constructor );
152
154
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod (method -> {
153
- method .addJavadoc ("Get the bean instance supplier for '$L'." , name );
155
+ method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
154
156
method .addModifiers (PRIVATE_STATIC );
155
- method .returns (BeanInstanceSupplier .class );
157
+ method .returns (ParameterizedTypeName . get ( BeanInstanceSupplier .class , beanClass ) );
156
158
int parameterOffset = (!dependsOnBean ) ? 0 : 1 ;
157
- method .addStatement (
158
- generateResolverForConstructor (constructor , parameterOffset ));
159
+ method .addStatement (generateResolverForConstructor (beanClass , constructor , parameterOffset ));
159
160
});
160
161
return generateReturnStatement (generatedMethod );
161
162
}
162
163
163
164
private void buildGetInstanceMethodForConstructor (MethodSpec .Builder method ,
164
- String name , Constructor <?> constructor , Class <?> declaringClass ,
165
+ String beanName , Class <?> beanClass , Constructor <?> constructor , Class <?> declaringClass ,
165
166
boolean dependsOnBean , javax .lang .model .element .Modifier ... modifiers ) {
166
167
167
- method .addJavadoc ("Get the bean instance supplier for '$L'." , name );
168
+ method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
168
169
method .addModifiers (modifiers );
169
- method .returns (BeanInstanceSupplier .class );
170
+ method .returns (ParameterizedTypeName . get ( BeanInstanceSupplier .class , beanClass ) );
170
171
int parameterOffset = (!dependsOnBean ) ? 0 : 1 ;
171
172
CodeBlock .Builder code = CodeBlock .builder ();
172
- code .add (generateResolverForConstructor (constructor , parameterOffset ));
173
+ code .add (generateResolverForConstructor (beanClass , constructor , parameterOffset ));
173
174
boolean hasArguments = constructor .getParameterCount () > 0 ;
174
175
CodeBlock arguments = hasArguments
175
176
? new AutowiredArgumentsCodeGenerator (declaringClass , constructor )
@@ -181,13 +182,13 @@ private void buildGetInstanceMethodForConstructor(MethodSpec.Builder method,
181
182
method .addStatement (code .build ());
182
183
}
183
184
184
- private CodeBlock generateResolverForConstructor (Constructor <?> constructor ,
185
- int parameterOffset ) {
185
+ private CodeBlock generateResolverForConstructor (Class <?> beanClass ,
186
+ Constructor <?> constructor , int parameterOffset ) {
186
187
187
188
CodeBlock parameterTypes = generateParameterTypesCode (
188
189
constructor .getParameterTypes (), parameterOffset );
189
- return CodeBlock .of ("return $T.forConstructor($L)" ,
190
- BeanInstanceSupplier .class , parameterTypes );
190
+ return CodeBlock .of ("return $T.<$T> forConstructor($L)" ,
191
+ BeanInstanceSupplier .class , beanClass , parameterTypes );
191
192
}
192
193
193
194
private CodeBlock generateNewInstanceCodeForConstructor (boolean dependsOnBean ,
@@ -204,63 +205,65 @@ private CodeBlock generateNewInstanceCodeForConstructor(boolean dependsOnBean,
204
205
private CodeBlock generateCodeForFactoryMethod (RegisteredBean registeredBean ,
205
206
Method factoryMethod ) {
206
207
207
- String name = registeredBean .getBeanName ();
208
+ String beanName = registeredBean .getBeanName ();
209
+ Class <?> beanClass = registeredBean .getBeanClass ();
208
210
Class <?> declaringClass = ClassUtils
209
211
.getUserClass (factoryMethod .getDeclaringClass ());
210
212
boolean dependsOnBean = !Modifier .isStatic (factoryMethod .getModifiers ());
211
213
AccessVisibility accessVisibility = getAccessVisibility (registeredBean ,
212
214
factoryMethod );
213
215
if (accessVisibility == AccessVisibility .PUBLIC
214
216
|| accessVisibility == AccessVisibility .PACKAGE_PRIVATE ) {
215
- return generateCodeForAccessibleFactoryMethod (name , factoryMethod ,
217
+ return generateCodeForAccessibleFactoryMethod (beanName , beanClass , factoryMethod ,
216
218
declaringClass , dependsOnBean );
217
219
}
218
- return generateCodeForInaccessibleFactoryMethod (name , factoryMethod ,
220
+ return generateCodeForInaccessibleFactoryMethod (beanName , beanClass , factoryMethod ,
219
221
declaringClass );
220
222
}
221
223
222
- private CodeBlock generateCodeForAccessibleFactoryMethod (String name ,
223
- Method factoryMethod , Class <?> declaringClass , boolean dependsOnBean ) {
224
+ private CodeBlock generateCodeForAccessibleFactoryMethod (String beanName ,
225
+ Class <?> beanClass , Method factoryMethod , Class <?> declaringClass , boolean dependsOnBean ) {
226
+
224
227
this .generationContext .getRuntimeHints ().reflection ()
225
228
.registerMethod (factoryMethod , INTROSPECT );
226
229
if (!dependsOnBean && factoryMethod .getParameterCount () == 0 ) {
227
230
CodeBlock .Builder code = CodeBlock .builder ();
228
- code .add ("$T.forFactoryMethod($T.class, $S)" , BeanInstanceSupplier .class ,
229
- declaringClass , factoryMethod .getName ());
231
+ code .add ("$T.<$T> forFactoryMethod($T.class, $S)" , BeanInstanceSupplier .class ,
232
+ beanClass , declaringClass , factoryMethod .getName ());
230
233
code .add (".withGenerator($T::$L)" , declaringClass , factoryMethod .getName ());
231
234
return code .build ();
232
235
}
233
236
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod (method ->
234
- buildGetInstanceMethodForFactoryMethod (method , name , factoryMethod ,
237
+ buildGetInstanceMethodForFactoryMethod (method , beanName , beanClass , factoryMethod ,
235
238
declaringClass , dependsOnBean , PRIVATE_STATIC ));
236
239
return generateReturnStatement (getInstanceMethod );
237
240
}
238
241
239
- private CodeBlock generateCodeForInaccessibleFactoryMethod (String name ,
242
+ private CodeBlock generateCodeForInaccessibleFactoryMethod (String beanName , Class <?> beanClass ,
240
243
Method factoryMethod , Class <?> declaringClass ) {
241
244
242
245
this .generationContext .getRuntimeHints ().reflection ()
243
246
.registerMethod (factoryMethod );
244
247
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod (method -> {
245
- method .addJavadoc ("Get the bean instance supplier for '$L'." , name );
248
+ method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
246
249
method .addModifiers (PRIVATE_STATIC );
247
- method .returns (BeanInstanceSupplier .class );
248
- method .addStatement (generateInstanceSupplierForFactoryMethod (factoryMethod ,
250
+ method .returns (ParameterizedTypeName . get ( BeanInstanceSupplier .class , beanClass ) );
251
+ method .addStatement (generateInstanceSupplierForFactoryMethod (beanClass , factoryMethod ,
249
252
declaringClass , factoryMethod .getName ()));
250
253
});
251
254
return generateReturnStatement (getInstanceMethod );
252
255
}
253
256
254
257
private void buildGetInstanceMethodForFactoryMethod (MethodSpec .Builder method ,
255
- String name , Method factoryMethod , Class <?> declaringClass ,
258
+ String beanName , Class <?> beanClass , Method factoryMethod , Class <?> declaringClass ,
256
259
boolean dependsOnBean , javax .lang .model .element .Modifier ... modifiers ) {
257
260
258
261
String factoryMethodName = factoryMethod .getName ();
259
- method .addJavadoc ("Get the bean instance supplier for '$L'." , name );
262
+ method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
260
263
method .addModifiers (modifiers );
261
- method .returns (BeanInstanceSupplier .class );
264
+ method .returns (ParameterizedTypeName . get ( BeanInstanceSupplier .class , beanClass ) );
262
265
CodeBlock .Builder code = CodeBlock .builder ();
263
- code .add (generateInstanceSupplierForFactoryMethod (factoryMethod , declaringClass , factoryMethodName ));
266
+ code .add (generateInstanceSupplierForFactoryMethod (beanClass , factoryMethod , declaringClass , factoryMethodName ));
264
267
boolean hasArguments = factoryMethod .getParameterCount () > 0 ;
265
268
CodeBlock arguments = hasArguments
266
269
? new AutowiredArgumentsCodeGenerator (declaringClass , factoryMethod )
@@ -272,18 +275,18 @@ private void buildGetInstanceMethodForFactoryMethod(MethodSpec.Builder method,
272
275
method .addStatement (code .build ());
273
276
}
274
277
275
- private CodeBlock generateInstanceSupplierForFactoryMethod (Method factoryMethod ,
276
- Class <?> declaringClass , String factoryMethodName ) {
278
+ private CodeBlock generateInstanceSupplierForFactoryMethod (Class <?> beanClass ,
279
+ Method factoryMethod , Class <?> declaringClass , String factoryMethodName ) {
277
280
278
281
if (factoryMethod .getParameterCount () == 0 ) {
279
- return CodeBlock .of ("return $T.forFactoryMethod($T.class, $S)" ,
280
- BeanInstanceSupplier .class , declaringClass ,
282
+ return CodeBlock .of ("return $T.<$T> forFactoryMethod($T.class, $S)" ,
283
+ BeanInstanceSupplier .class , beanClass , declaringClass ,
281
284
factoryMethodName );
282
285
}
283
286
CodeBlock parameterTypes = generateParameterTypesCode (
284
287
factoryMethod .getParameterTypes (), 0 );
285
- return CodeBlock .of ("return $T.forFactoryMethod($T.class, $S, $L)" ,
286
- BeanInstanceSupplier .class , declaringClass ,
288
+ return CodeBlock .of ("return $T.<$T> forFactoryMethod($T.class, $S, $L)" ,
289
+ BeanInstanceSupplier .class , beanClass , declaringClass ,
287
290
factoryMethodName , parameterTypes );
288
291
}
289
292
0 commit comments