@@ -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