Skip to content

Commit f7f164f

Browse files
committed
Refactor Improve performance by inducing hot path from the point of view of the jit compilor
Signed-off-by: KNU-K <[email protected]>
1 parent 015edb3 commit f7f164f

File tree

1 file changed

+132
-72
lines changed

1 file changed

+132
-72
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 132 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)