Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Refactor doGetBeanNamesForType for improved readability and performance #35503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
polyglot-k wants to merge 7 commits into spring-projects:main
base: main
Choose a base branch
Loading
from polyglot-k:main
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -614,93 +614,117 @@ public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonS
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();

// Check all bean definitions.
processBeanDefinitions(result, type, includeNonSingletons, allowEagerInit);
processManualSingletons(result, type, includeNonSingletons);

return StringUtils.toStringArray(result);
}

private void processBeanDefinitions(List<String> result, ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
if (!isFactoryBean) {
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
else if (allowFactoryBeanInit) {
// Type check before singleton check, avoiding FactoryBean instantiation
// for early FactoryBean.isSingleton() calls on non-matching beans.
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit) &&
isSingleton(beanName, mbd, dbd);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
if (isAlias(beanName)) {
continue;
}

try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

// cache merged bean definition
boolean isAbstract = mbd.isAbstract();
boolean hasBeanClass = mbd.hasBeanClass();
boolean isLazyInit = mbd.isLazyInit();
String factoryBeanName = mbd.getFactoryBeanName();
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();

if (shouldSkipBeanDefinition(isAbstract, allowEagerInit, hasBeanClass, isLazyInit, factoryBeanName)) {
continue;
}

boolean isFactoryBean = isFactoryBean(beanName, mbd);
boolean matchFound = false;
boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
boolean isNonLazyDecorated = (dbd != null && !isLazyInit);

if (!isFactoryBean && (includeNonSingletons || isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
else {
if (includeNonSingletons || isNonLazyDecorated) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
else if (allowFactoryBeanInit) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit) &&
isSingleton(beanName, mbd, dbd);
}

if (!matchFound) {
String factoryBeanFullName = FACTORY_BEAN_PREFIX + beanName;
if (includeNonSingletons || isSingleton(factoryBeanFullName, mbd, dbd)) {
matchFound = isTypeMatch(factoryBeanFullName, type, allowFactoryBeanInit);
}
if (matchFound) {
result.add(beanName);
result.add(factoryBeanFullName);
continue;
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably a placeholder: let's ignore it for type matching purposes.
LogMessage message = (ex instanceof CannotLoadBeanClassException ?
LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
logger.trace(message, ex);
// Register exception, in case the bean was accidentally unresolvable.
onSuppressedException(ex);

if (matchFound) {
result.add(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Bean definition got removed while we were iterating -> ignore.
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
LogMessage message = (ex instanceof CannotLoadBeanClassException ?
LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
logger.trace(message, ex);
onSuppressedException(ex);
}
catch (NoSuchBeanDefinitionException ex) {
// Bean definition got removed while we were iterating -> ignore
}
}
}

// Check manually registered singletons too.
private void processManualSingletons(List<String> result, ResolvableType type, boolean includeNonSingletons) {
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).

if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Shouldn't happen - probably a result of circular reference resolution...
logger.trace(LogMessage.format(
"Failed to check manually registered singleton with name '%s'", beanName), ex);
}
}
}

return StringUtils.toStringArray(result);
private boolean shouldSkipBeanDefinition(boolean isAbstract, boolean allowEagerInit,
boolean hasBeanClass, boolean isLazyInit, @Nullable String factoryBeanName) {

if (isAbstract) {
return true;
}
if (!allowEagerInit) {
boolean needsEagerInit = (!hasBeanClass && isLazyInit && !isAllowEagerClassLoading()) ||
requiresEagerInitForType(factoryBeanName);
if (needsEagerInit) {
return true;
}
}
return false;
}

private boolean isSingleton(String beanName, RootBeanDefinition mbd, @Nullable BeanDefinitionHolder dbd) {
Expand Down

AltStyle によって変換されたページ (->オリジナル) /