@@ -615,81 +615,125 @@ private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSi
615615 List <String > result = new ArrayList <>();
616616
617617 // Check all bean definitions.
618+ processBeanDefinitions (result , type , includeNonSingletons , allowEagerInit );
619+
620+ // Check manually registered singletons too.
621+ processManualSingletons (result , type , includeNonSingletons );
622+
623+ return StringUtils .toStringArray (result );
624+ }
625+
626+ private void processBeanDefinitions (List <String > result , ResolvableType type , boolean includeNonSingletons , boolean allowEagerInit ) {
618627 for (String beanName : this .beanDefinitionNames ) {
619628 // Only consider bean as eligible if the bean name is not defined as alias for some other bean.
620- if (!isAlias (beanName )) {
621- try {
622- RootBeanDefinition mbd = getMergedLocalBeanDefinition (beanName );
623- // Only check bean definition if it is complete.
624- if (!mbd .isAbstract () && (allowEagerInit ||
625- (mbd .hasBeanClass () || !mbd .isLazyInit () || isAllowEagerClassLoading ()) &&
626- !requiresEagerInitForType (mbd .getFactoryBeanName ()))) {
627- boolean isFactoryBean = isFactoryBean (beanName , mbd );
628- BeanDefinitionHolder dbd = mbd .getDecoratedDefinition ();
629- boolean matchFound = false ;
630- boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton (beanName ));
631- boolean isNonLazyDecorated = (dbd != null && !mbd .isLazyInit ());
632- if (!isFactoryBean ) {
633- if (includeNonSingletons || isSingleton (beanName , mbd , dbd )) {
634- matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit );
635- }
636- }
637- else {
638- if (includeNonSingletons || isNonLazyDecorated ) {
639- matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit );
640- }
641- else if (allowFactoryBeanInit ) {
642- // Type check before singleton check, avoiding FactoryBean instantiation
643- // for early FactoryBean.isSingleton() calls on non-matching beans.
644- matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit ) &&
645- isSingleton (beanName , mbd , dbd );
646- }
647- if (!matchFound ) {
648- // In case of FactoryBean, try to match FactoryBean instance itself next.
649- beanName = FACTORY_BEAN_PREFIX + beanName ;
650- if (includeNonSingletons || isSingleton (beanName , mbd , dbd )) {
651- matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit );
652- }
653- }
654- }
655- if (matchFound ) {
656- result .add (beanName );
657- }
658- }
659- }
660- catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex ) {
661- if (allowEagerInit ) {
662- throw ex ;
663- }
664- // Probably a placeholder: let's ignore it for type matching purposes.
665- LogMessage message = (ex instanceof CannotLoadBeanClassException ?
666- LogMessage .format ("Ignoring bean class loading failure for bean '%s'" , beanName ) :
667- LogMessage .format ("Ignoring unresolvable metadata in bean definition '%s'" , beanName ));
668- logger .trace (message , ex );
669- // Register exception, in case the bean was accidentally unresolvable.
670- onSuppressedException (ex );
671- }
672- catch (NoSuchBeanDefinitionException ex ) {
673- // Bean definition got removed while we were iterating -> ignore.
629+ if (isAlias (beanName )) {
630+ continue ;
631+ }
632+
633+ RootBeanDefinition mbd ;
634+ try {
635+ mbd = getMergedLocalBeanDefinition (beanName );
636+ }
637+ catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex ) {
638+ if (allowEagerInit ) {
639+ throw ex ;
674640 }
641+ handleBeanDefinitionException (beanName , ex );
642+ continue ;
643+ }
644+ catch (NoSuchBeanDefinitionException ex ) {
645+ // Bean definition got removed while we were iterating -> ignore.
646+ continue ;
647+ }
648+
649+ if (processBeanDefinition (result , beanName , mbd , type , includeNonSingletons , allowEagerInit )) {
650+ result .add (beanName );
675651 }
676652 }
653+ }
677654
678- // Check manually registered singletons too.
655+ private void handleBeanDefinitionException (String beanName , Exception ex ) {
656+ // Probably a placeholder: let's ignore it for type matching purposes.
657+ LogMessage message = (ex instanceof CannotLoadBeanClassException ?
658+ LogMessage .format ("Ignoring bean class loading failure for bean '%s'" , beanName ) :
659+ LogMessage .format ("Ignoring unresolvable metadata in bean definition '%s'" , beanName ));
660+ logger .trace (message , ex );
661+ // Register exception, in case the bean was accidentally unresolvable.
662+ onSuppressedException (ex );
663+ }
664+
665+ private boolean processBeanDefinition (List <String > result , String beanName , RootBeanDefinition mbd ,
666+ ResolvableType type , boolean includeNonSingletons , boolean allowEagerInit ) {
667+ // Cache merged bean definition properties to avoid repeated access
668+ boolean isAbstract = mbd .isAbstract ();
669+ boolean hasBeanClass = mbd .hasBeanClass ();
670+ boolean isLazyInit = mbd .isLazyInit ();
671+ String factoryBeanName = mbd .getFactoryBeanName ();
672+ BeanDefinitionHolder dbd = mbd .getDecoratedDefinition ();
673+
674+ // Only check bean definition if it is complete.
675+ if (isAbstract ) {
676+ return false ;
677+ }
678+
679+ if (!allowEagerInit &&
680+ !(hasBeanClass || !isLazyInit || isAllowEagerClassLoading ()) &&
681+ requiresEagerInitForType (factoryBeanName )) {
682+ return false ;
683+ }
684+
685+ boolean isFactoryBean = isFactoryBean (beanName , mbd );
686+ boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton (beanName ));
687+ boolean isNonLazyDecorated = (dbd != null && !isLazyInit );
688+
689+ if (!isFactoryBean ) {
690+ return processRegularBean (beanName , mbd , dbd , type , includeNonSingletons , allowFactoryBeanInit );
691+ } else {
692+ return processFactoryBean (result , beanName , mbd , dbd , type , includeNonSingletons , allowFactoryBeanInit , isNonLazyDecorated );
693+ }
694+ }
695+
696+ private boolean processRegularBean (String beanName , RootBeanDefinition mbd , @ Nullable BeanDefinitionHolder dbd ,
697+ ResolvableType type , boolean includeNonSingletons , boolean allowFactoryBeanInit ) {
698+ if (includeNonSingletons || isSingleton (beanName , mbd , dbd )) {
699+ return isTypeMatch (beanName , type , allowFactoryBeanInit );
700+ }
701+ return false ;
702+ }
703+
704+ private boolean processFactoryBean (List <String > result , String beanName , RootBeanDefinition mbd , @ Nullable BeanDefinitionHolder dbd ,
705+ ResolvableType type , boolean includeNonSingletons , boolean allowFactoryBeanInit , boolean isNonLazyDecorated ) {
706+ boolean matchFound = false ;
707+
708+ if (includeNonSingletons || isNonLazyDecorated ) {
709+ matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit );
710+ }
711+ else if (allowFactoryBeanInit ) {
712+ // Type check before singleton check, avoiding FactoryBean instantiation
713+ // for early FactoryBean.isSingleton() calls on non-matching beans.
714+ matchFound = isTypeMatch (beanName , type , allowFactoryBeanInit ) &&
715+ isSingleton (beanName , mbd , dbd );
716+ }
717+
718+ if (!matchFound ) {
719+ // In case of FactoryBean, try to match FactoryBean instance itself next.
720+ String factoryBeanName = FACTORY_BEAN_PREFIX + beanName ;
721+ if (includeNonSingletons || isSingleton (factoryBeanName , mbd , dbd )) {
722+ matchFound = isTypeMatch (factoryBeanName , type , allowFactoryBeanInit );
723+ }
724+ if (matchFound ) {
725+ result .add (factoryBeanName );
726+ return false ; // Don't add original beanName
727+ }
728+ }
729+
730+ return matchFound ;
731+ }
732+
733+ private void processManualSingletons (List <String > result , ResolvableType type , boolean includeNonSingletons ) {
679734 for (String beanName : this .manualSingletonNames ) {
680735 try {
681- // In case of FactoryBean, match object created by FactoryBean.
682- if (isFactoryBean (beanName )) {
683- if ((includeNonSingletons || isSingleton (beanName )) && isTypeMatch (beanName , type )) {
684- result .add (beanName );
685- // Match found for this bean: do not match FactoryBean itself anymore.
686- continue ;
687- }
688- // In case of FactoryBean, try to match FactoryBean itself next.
689- beanName = FACTORY_BEAN_PREFIX + beanName ;
690- }
691- // Match raw bean instance (might be raw FactoryBean).
692- if (isTypeMatch (beanName , type )) {
736+ if (processManualSingleton (result , beanName , type , includeNonSingletons )) {
693737 result .add (beanName );
694738 }
695739 }
@@ -699,8 +743,24 @@ else if (allowFactoryBeanInit) {
699743 "Failed to check manually registered singleton with name '%s'" , beanName ), ex );
700744 }
701745 }
746+ }
702747
703- return StringUtils .toStringArray (result );
748+ private boolean processManualSingleton (List <String > result , String beanName , ResolvableType type , boolean includeNonSingletons ) {
749+ // In case of FactoryBean, match object created by FactoryBean.
750+ if (isFactoryBean (beanName )) {
751+ if ((includeNonSingletons || isSingleton (beanName )) && isTypeMatch (beanName , type )) {
752+ return true ; // Match found for this bean
753+ }
754+ // In case of FactoryBean, try to match FactoryBean itself next.
755+ String factoryBeanName = FACTORY_BEAN_PREFIX + beanName ;
756+ if (isTypeMatch (factoryBeanName , type )) {
757+ result .add (factoryBeanName );
758+ }
759+ return false ; // Don't add original beanName
760+ }
761+
762+ // Match raw bean instance (might be raw FactoryBean).
763+ return isTypeMatch (beanName , type );
704764 }
705765
706766 private boolean isSingleton (String beanName , RootBeanDefinition mbd , @ Nullable BeanDefinitionHolder dbd ) {
@@ -1267,7 +1327,7 @@ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinitio
12671327 else { // alias pointing to non-existing bean definition
12681328 throw new BeanDefinitionStoreException (beanDefinition .getResourceDescription (), beanName ,
12691329 "Cannot register bean definition for bean '" + beanName +
1270- "' since there is already an alias for bean '" + aliasedName + "' bound." );
1330+ "' since there is already an alias for bean '" + aliasedName + "' bound." );
12711331 }
12721332 }
12731333 else {
@@ -2148,7 +2208,7 @@ else if (candidatePriority < highestPriority) {
21482208 if (highestPriorityConflictDetected ) {
21492209 throw new NoUniqueBeanDefinitionException (requiredType , candidates .size (),
21502210 "Multiple beans found with the same highest priority (" + highestPriority +
2151- ") among candidates: " + candidates .keySet ());
2211+ ") among candidates: " + candidates .keySet ());
21522212
21532213 }
21542214 return highestPriorityBeanName ;
@@ -2277,7 +2337,7 @@ private void raiseNoMatchingBeanFound(
22772337
22782338 throw new NoSuchBeanDefinitionException (resolvableType ,
22792339 "expected at least 1 bean which qualifies as autowire candidate. " +
2280- "Dependency annotations: " + ObjectUtils .nullSafeToString (descriptor .getAnnotations ()));
2340+ "Dependency annotations: " + ObjectUtils .nullSafeToString (descriptor .getAnnotations ()));
22812341 }
22822342
22832343 /**
@@ -2755,4 +2815,4 @@ private enum PreInstantiation {
27552815 MAIN , BACKGROUND
27562816 }
27572817
2758- }
2818+ }
0 commit comments