1
1
/*
2
- * Copyright 2002-2017 the original author or authors.
2
+ * Copyright 2002-2018 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.
17
17
package org .springframework .context .support ;
18
18
19
19
import java .io .IOException ;
20
+ import java .lang .reflect .Constructor ;
20
21
import java .util .concurrent .atomic .AtomicBoolean ;
21
22
import java .util .function .Supplier ;
22
23
24
+ import org .springframework .beans .BeanUtils ;
23
25
import org .springframework .beans .BeansException ;
24
26
import org .springframework .beans .factory .BeanDefinitionStoreException ;
25
27
import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
26
28
import org .springframework .beans .factory .config .AutowireCapableBeanFactory ;
27
29
import org .springframework .beans .factory .config .BeanDefinition ;
28
30
import org .springframework .beans .factory .config .BeanDefinitionCustomizer ;
29
31
import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
30
- import org .springframework .beans .factory .support .BeanDefinitionBuilder ;
31
32
import org .springframework .beans .factory .support .BeanDefinitionRegistry ;
32
33
import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
34
+ import org .springframework .beans .factory .support .RootBeanDefinition ;
33
35
import org .springframework .context .ApplicationContext ;
34
36
import org .springframework .core .io .Resource ;
35
37
import org .springframework .core .io .ResourceLoader ;
@@ -360,9 +362,10 @@ public boolean isAlias(String beanName) {
360
362
* Register a bean from the given bean class, optionally customizing its
361
363
* bean definition metadata (typically declared as a lambda expression
362
364
* or method reference).
363
- * @param beanClass the class of the bean
364
- * @param customizers one or more callbacks for customizing the
365
- * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
365
+ * @param beanClass the class of the bean (resolving a public constructor
366
+ * to be autowired, possibly simply the default constructor)
367
+ * @param customizers one or more callbacks for customizing the factory's
368
+ * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
366
369
* @since 5.0
367
370
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
368
371
*/
@@ -376,13 +379,16 @@ public final <T> void registerBean(Class<T> beanClass, BeanDefinitionCustomizer.
376
379
* method reference), optionally customizing its bean definition metadata
377
380
* (again typically declared as a lambda expression or method reference).
378
381
* @param beanName the name of the bean (may be {@code null})
379
- * @param beanClass the class of the bean
382
+ * @param beanClass the class of the bean (resolving a public constructor
383
+ * to be autowired, possibly simply the default constructor)
380
384
* @param customizers one or more callbacks for customizing the
381
385
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
382
386
* @since 5.0
383
387
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
384
388
*/
385
- public final <T > void registerBean (@ Nullable String beanName , Class <T > beanClass , BeanDefinitionCustomizer ... customizers ) {
389
+ public final <T > void registerBean (
390
+ @ Nullable String beanName , Class <T > beanClass , BeanDefinitionCustomizer ... customizers ) {
391
+
386
392
registerBean (beanName , beanClass , null , customizers );
387
393
}
388
394
@@ -393,12 +399,14 @@ public final <T> void registerBean(@Nullable String beanName, Class<T> beanClass
393
399
* (again typically declared as a lambda expression or method reference).
394
400
* @param beanClass the class of the bean
395
401
* @param supplier a callback for creating an instance of the bean
396
- * @param customizers one or more callbacks for customizing the
397
- * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
402
+ * @param customizers one or more callbacks for customizing the factory's
403
+ * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
398
404
* @since 5.0
399
405
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
400
406
*/
401
- public final <T > void registerBean (Class <T > beanClass , Supplier <T > supplier , BeanDefinitionCustomizer ... customizers ) {
407
+ public final <T > void registerBean (
408
+ Class <T > beanClass , Supplier <T > supplier , BeanDefinitionCustomizer ... customizers ) {
409
+
402
410
registerBean (null , beanClass , supplier , customizers );
403
411
}
404
412
@@ -410,22 +418,63 @@ public final <T> void registerBean(Class<T> beanClass, Supplier<T> supplier, Bea
410
418
* <p>This method can be overridden to adapt the registration mechanism for
411
419
* all {@code registerBean} methods (since they all delegate to this one).
412
420
* @param beanName the name of the bean (may be {@code null})
413
- * @param beanClass the class of the bean (may be {@code null} if a name is given)
414
- * @param supplier a callback for creating an instance of the bean
415
- * @param customizers one or more callbacks for customizing the
416
- * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
421
+ * @param beanClass the class of the bean
422
+ * @param supplier a callback for creating an instance of the bean (in case
423
+ * of {@code null}, resolving a public constructor to be autowired instead)
424
+ * @param customizers one or more callbacks for customizing the factory's
425
+ * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
417
426
* @since 5.0
418
427
*/
419
- public <T > void registerBean (@ Nullable String beanName , Class <T > beanClass , @ Nullable Supplier < T > supplier ,
420
- BeanDefinitionCustomizer ... customizers ) {
428
+ public <T > void registerBean (@ Nullable String beanName , Class <T > beanClass ,
429
+ @ Nullable Supplier < T > supplier , BeanDefinitionCustomizer ... customizers ) {
421
430
422
- BeanDefinitionBuilder builder = (supplier != null ?
423
- BeanDefinitionBuilder .genericBeanDefinition (beanClass , supplier ) :
424
- BeanDefinitionBuilder .genericBeanDefinition (beanClass ));
425
- BeanDefinition beanDefinition = builder .applyCustomizers (customizers ).getRawBeanDefinition ();
431
+ ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition (beanClass );
432
+ if (supplier != null ) {
433
+ beanDefinition .setInstanceSupplier (supplier );
434
+ }
435
+ for (BeanDefinitionCustomizer customizer : customizers ) {
436
+ customizer .customize (beanDefinition );
437
+ }
426
438
427
439
String nameToUse = (beanName != null ? beanName : beanClass .getName ());
428
440
registerBeanDefinition (nameToUse , beanDefinition );
429
441
}
430
442
443
+
444
+ /**
445
+ * {@link RootBeanDefinition} marker subclass for {@code #registerBean} based
446
+ * registrations with flexible autowiring for public constructors.
447
+ */
448
+ @ SuppressWarnings ("serial" )
449
+ private static class ClassDerivedBeanDefinition extends RootBeanDefinition {
450
+
451
+ public ClassDerivedBeanDefinition (Class <?> beanClass ) {
452
+ super (beanClass );
453
+ }
454
+
455
+ public ClassDerivedBeanDefinition (ClassDerivedBeanDefinition original ) {
456
+ super (original );
457
+ }
458
+
459
+ @ Override
460
+ @ Nullable
461
+ public Constructor <?>[] getPreferredConstructors () {
462
+ Class <?> clazz = getBeanClass ();
463
+ Constructor <?> primaryCtor = BeanUtils .findPrimaryConstructor (clazz );
464
+ if (primaryCtor != null ) {
465
+ return new Constructor <?>[] {primaryCtor };
466
+ }
467
+ Constructor <?>[] publicCtors = clazz .getConstructors ();
468
+ if (publicCtors .length > 0 ) {
469
+ return publicCtors ;
470
+ }
471
+ return null ;
472
+ }
473
+
474
+ @ Override
475
+ public RootBeanDefinition cloneBeanDefinition () {
476
+ return new ClassDerivedBeanDefinition (this );
477
+ }
478
+ }
479
+
431
480
}
0 commit comments