1
1
/*
2
- * Copyright 2002-2023 the original author or authors.
2
+ * Copyright 2002-2024 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
46
46
import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
47
47
import org .springframework .beans .factory .support .InstanceSupplier ;
48
48
import org .springframework .beans .factory .support .RegisteredBean ;
49
+ import org .springframework .beans .factory .support .RegisteredBean .InstantiationDescriptor ;
49
50
import org .springframework .core .KotlinDetector ;
50
51
import org .springframework .core .MethodParameter ;
51
52
import org .springframework .core .ResolvableType ;
@@ -120,14 +121,29 @@ public InstanceSupplierCodeGenerator(GenerationContext generationContext,
120
121
* @param registeredBean the bean to handle
121
122
* @param constructorOrFactoryMethod the executable to use to create the bean
122
123
* @return the generated code
124
+ * @deprecated in favor of {@link #generateCode(RegisteredBean, InstantiationDescriptor)}
123
125
*/
126
+ @ Deprecated (since = "6.1.7" )
124
127
public CodeBlock generateCode (RegisteredBean registeredBean , Executable constructorOrFactoryMethod ) {
128
+ return generateCode (registeredBean , new InstantiationDescriptor (
129
+ constructorOrFactoryMethod , constructorOrFactoryMethod .getDeclaringClass ()));
130
+ }
131
+
132
+ /**
133
+ * Generate the instance supplier code.
134
+ * @param registeredBean the bean to handle
135
+ * @param instantiationDescriptor the executable to use to create the bean
136
+ * @return the generated code
137
+ * @since 6.1.7
138
+ */
139
+ public CodeBlock generateCode (RegisteredBean registeredBean , InstantiationDescriptor instantiationDescriptor ) {
140
+ Executable constructorOrFactoryMethod = instantiationDescriptor .executable ();
125
141
registerRuntimeHintsIfNecessary (registeredBean , constructorOrFactoryMethod );
126
142
if (constructorOrFactoryMethod instanceof Constructor <?> constructor ) {
127
143
return generateCodeForConstructor (registeredBean , constructor );
128
144
}
129
145
if (constructorOrFactoryMethod instanceof Method method ) {
130
- return generateCodeForFactoryMethod (registeredBean , method );
146
+ return generateCodeForFactoryMethod (registeredBean , method , instantiationDescriptor . targetClass () );
131
147
}
132
148
throw new IllegalStateException (
133
149
"No suitable executor found for " + registeredBean .getBeanName ());
@@ -253,21 +269,21 @@ private CodeBlock generateNewInstanceCodeForConstructor(boolean dependsOnBean,
253
269
declaringClass .getSimpleName (), args );
254
270
}
255
271
256
- private CodeBlock generateCodeForFactoryMethod (RegisteredBean registeredBean , Method factoryMethod ) {
272
+ private CodeBlock generateCodeForFactoryMethod (RegisteredBean registeredBean , Method factoryMethod , Class <?> targetClass ) {
257
273
String beanName = registeredBean .getBeanName ();
258
- Class <?> declaringClass = ClassUtils .getUserClass (factoryMethod . getDeclaringClass () );
274
+ Class <?> targetClassToUse = ClassUtils .getUserClass (targetClass );
259
275
boolean dependsOnBean = !Modifier .isStatic (factoryMethod .getModifiers ());
260
276
261
277
Visibility accessVisibility = getAccessVisibility (registeredBean , factoryMethod );
262
278
if (accessVisibility != Visibility .PRIVATE ) {
263
279
return generateCodeForAccessibleFactoryMethod (
264
- beanName , factoryMethod , declaringClass , dependsOnBean );
280
+ beanName , factoryMethod , targetClassToUse , dependsOnBean );
265
281
}
266
- return generateCodeForInaccessibleFactoryMethod (beanName , factoryMethod , declaringClass );
282
+ return generateCodeForInaccessibleFactoryMethod (beanName , factoryMethod , targetClassToUse );
267
283
}
268
284
269
285
private CodeBlock generateCodeForAccessibleFactoryMethod (String beanName ,
270
- Method factoryMethod , Class <?> declaringClass , boolean dependsOnBean ) {
286
+ Method factoryMethod , Class <?> targetClass , boolean dependsOnBean ) {
271
287
272
288
this .generationContext .getRuntimeHints ().reflection ().registerMethod (
273
289
factoryMethod , ExecutableMode .INTROSPECT );
@@ -276,20 +292,20 @@ private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName,
276
292
Class <?> suppliedType = ClassUtils .resolvePrimitiveIfNecessary (factoryMethod .getReturnType ());
277
293
CodeBlock .Builder code = CodeBlock .builder ();
278
294
code .add ("$T.<$T>forFactoryMethod($T.class, $S)" , BeanInstanceSupplier .class ,
279
- suppliedType , declaringClass , factoryMethod .getName ());
295
+ suppliedType , targetClass , factoryMethod .getName ());
280
296
code .add (".withGenerator(($L) -> $T.$L())" , REGISTERED_BEAN_PARAMETER_NAME ,
281
- declaringClass , factoryMethod .getName ());
297
+ targetClass , factoryMethod .getName ());
282
298
return code .build ();
283
299
}
284
300
285
301
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod (method ->
286
302
buildGetInstanceMethodForFactoryMethod (method , beanName , factoryMethod ,
287
- declaringClass , dependsOnBean , PRIVATE_STATIC ));
303
+ targetClass , dependsOnBean , PRIVATE_STATIC ));
288
304
return generateReturnStatement (getInstanceMethod );
289
305
}
290
306
291
307
private CodeBlock generateCodeForInaccessibleFactoryMethod (
292
- String beanName , Method factoryMethod , Class <?> declaringClass ) {
308
+ String beanName , Method factoryMethod , Class <?> targetClass ) {
293
309
294
310
this .generationContext .getRuntimeHints ().reflection ().registerMethod (factoryMethod , ExecutableMode .INVOKE );
295
311
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod (method -> {
@@ -298,19 +314,19 @@ private CodeBlock generateCodeForInaccessibleFactoryMethod(
298
314
method .addModifiers (PRIVATE_STATIC );
299
315
method .returns (ParameterizedTypeName .get (BeanInstanceSupplier .class , suppliedType ));
300
316
method .addStatement (generateInstanceSupplierForFactoryMethod (
301
- factoryMethod , suppliedType , declaringClass , factoryMethod .getName ()));
317
+ factoryMethod , suppliedType , targetClass , factoryMethod .getName ()));
302
318
});
303
319
return generateReturnStatement (getInstanceMethod );
304
320
}
305
321
306
322
private void buildGetInstanceMethodForFactoryMethod (MethodSpec .Builder method ,
307
- String beanName , Method factoryMethod , Class <?> declaringClass ,
323
+ String beanName , Method factoryMethod , Class <?> targetClass ,
308
324
boolean dependsOnBean , javax .lang .model .element .Modifier ... modifiers ) {
309
325
310
326
String factoryMethodName = factoryMethod .getName ();
311
327
Class <?> suppliedType = ClassUtils .resolvePrimitiveIfNecessary (factoryMethod .getReturnType ());
312
328
CodeWarnings codeWarnings = new CodeWarnings ();
313
- codeWarnings .detectDeprecation (declaringClass , factoryMethod , suppliedType )
329
+ codeWarnings .detectDeprecation (targetClass , factoryMethod , suppliedType )
314
330
.detectDeprecation (Arrays .stream (factoryMethod .getParameters ()).map (Parameter ::getType ));
315
331
316
332
method .addJavadoc ("Get the bean instance supplier for '$L'." , beanName );
@@ -320,41 +336,41 @@ private void buildGetInstanceMethodForFactoryMethod(MethodSpec.Builder method,
320
336
321
337
CodeBlock .Builder code = CodeBlock .builder ();
322
338
code .add (generateInstanceSupplierForFactoryMethod (
323
- factoryMethod , suppliedType , declaringClass , factoryMethodName ));
339
+ factoryMethod , suppliedType , targetClass , factoryMethodName ));
324
340
325
341
boolean hasArguments = factoryMethod .getParameterCount () > 0 ;
326
342
CodeBlock arguments = hasArguments ?
327
- new AutowiredArgumentsCodeGenerator (declaringClass , factoryMethod )
343
+ new AutowiredArgumentsCodeGenerator (targetClass , factoryMethod )
328
344
.generateCode (factoryMethod .getParameterTypes ())
329
345
: NO_ARGS ;
330
346
331
347
CodeBlock newInstance = generateNewInstanceCodeForMethod (
332
- dependsOnBean , declaringClass , factoryMethodName , arguments );
348
+ dependsOnBean , targetClass , factoryMethodName , arguments );
333
349
code .add (generateWithGeneratorCode (hasArguments , newInstance ));
334
350
method .addStatement (code .build ());
335
351
}
336
352
337
353
private CodeBlock generateInstanceSupplierForFactoryMethod (Method factoryMethod ,
338
- Class <?> suppliedType , Class <?> declaringClass , String factoryMethodName ) {
354
+ Class <?> suppliedType , Class <?> targetClass , String factoryMethodName ) {
339
355
340
356
if (factoryMethod .getParameterCount () == 0 ) {
341
357
return CodeBlock .of ("return $T.<$T>forFactoryMethod($T.class, $S)" ,
342
- BeanInstanceSupplier .class , suppliedType , declaringClass , factoryMethodName );
358
+ BeanInstanceSupplier .class , suppliedType , targetClass , factoryMethodName );
343
359
}
344
360
345
361
CodeBlock parameterTypes = generateParameterTypesCode (factoryMethod .getParameterTypes (), 0 );
346
362
return CodeBlock .of ("return $T.<$T>forFactoryMethod($T.class, $S, $L)" ,
347
- BeanInstanceSupplier .class , suppliedType , declaringClass , factoryMethodName , parameterTypes );
363
+ BeanInstanceSupplier .class , suppliedType , targetClass , factoryMethodName , parameterTypes );
348
364
}
349
365
350
366
private CodeBlock generateNewInstanceCodeForMethod (boolean dependsOnBean ,
351
- Class <?> declaringClass , String factoryMethodName , CodeBlock args ) {
367
+ Class <?> targetClass , String factoryMethodName , CodeBlock args ) {
352
368
353
369
if (!dependsOnBean ) {
354
- return CodeBlock .of ("$T.$L($L)" , declaringClass , factoryMethodName , args );
370
+ return CodeBlock .of ("$T.$L($L)" , targetClass , factoryMethodName , args );
355
371
}
356
372
return CodeBlock .of ("$L.getBeanFactory().getBean($T.class).$L($L)" ,
357
- REGISTERED_BEAN_PARAMETER_NAME , declaringClass , factoryMethodName , args );
373
+ REGISTERED_BEAN_PARAMETER_NAME , targetClass , factoryMethodName , args );
358
374
}
359
375
360
376
private CodeBlock generateReturnStatement (GeneratedMethod generatedMethod ) {
0 commit comments