Skip to content

Commit 6b6cf1b

Browse files
committed
Avoid decorated definition bypass for scoped proxy determination
GenericApplicationContext registers proxy hints without any SmartInstantiationAwareBeanPostProcessor involved as well. Closes gh-29335
1 parent 5dca43e commit 6b6cf1b

File tree

2 files changed

+45
-34
lines changed

2 files changed

+45
-34
lines changed

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -689,33 +689,35 @@ public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuch
689689
}
690690

691691
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
692-
693-
// Check decorated bean definition, if any: We assume it'll be easier
694-
// to determine the decorated bean's type than the proxy's type.
695-
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
696-
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
697-
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
698-
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
699-
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
700-
return targetClass;
701-
}
702-
}
703-
704692
Class<?> beanClass = predictBeanType(beanName, mbd);
705693

706-
// Check bean class whether we're dealing with a FactoryBean.
707-
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
708-
if (!BeanFactoryUtils.isFactoryDereference(name)) {
709-
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
710-
return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve();
694+
if (beanClass != null) {
695+
// Check bean class whether we're dealing with a FactoryBean.
696+
if (FactoryBean.class.isAssignableFrom(beanClass)) {
697+
if (!BeanFactoryUtils.isFactoryDereference(name)) {
698+
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
699+
beanClass = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve();
700+
}
711701
}
712-
else {
713-
return beanClass;
702+
else if (BeanFactoryUtils.isFactoryDereference(name)) {
703+
return null;
714704
}
715705
}
716-
else {
717-
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
706+
707+
if (beanClass == null) {
708+
// Check decorated bean definition, if any: We assume it'll be easier
709+
// to determine the decorated bean's type than the proxy's type.
710+
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
711+
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
712+
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
713+
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
714+
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
715+
return targetClass;
716+
}
717+
}
718718
}
719+
720+
return beanClass;
719721
}
720722

721723
@Override

spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,29 +439,38 @@ private void preDetermineBeanTypes(RuntimeHints runtimeHints) {
439439
List<SmartInstantiationAwareBeanPostProcessor> bpps =
440440
PostProcessorRegistrationDelegate.loadBeanPostProcessors(
441441
this.beanFactory, SmartInstantiationAwareBeanPostProcessor.class);
442+
442443
for (String beanName : this.beanFactory.getBeanDefinitionNames()) {
443444
Class<?> beanType = this.beanFactory.getType(beanName);
444445
if (beanType != null) {
446+
registerProxyHintIfNecessary(beanType, runtimeHints);
445447
for (SmartInstantiationAwareBeanPostProcessor bpp : bpps) {
446-
beanType = bpp.determineBeanType(beanType, beanName);
447-
if (Proxy.isProxyClass(beanType)) {
448-
// A JDK proxy class needs an explicit hint
449-
runtimeHints.proxies().registerJdkProxy(beanType.getInterfaces());
450-
}
451-
else {
452-
// Potentially a CGLIB-generated subclass with reflection hints
453-
Class<?> userClass = ClassUtils.getUserClass(beanType);
454-
if (userClass != beanType) {
455-
runtimeHints.reflection()
456-
.registerType(beanType, asClassBasedProxy)
457-
.registerType(userClass, asProxiedUserClass);
458-
}
448+
Class<?> newBeanType = bpp.determineBeanType(beanType, beanName);
449+
if (newBeanType != beanType) {
450+
registerProxyHintIfNecessary(newBeanType, runtimeHints);
451+
beanType = newBeanType;
459452
}
460453
}
461454
}
462455
}
463456
}
464457

458+
private void registerProxyHintIfNecessary(Class<?> beanType, RuntimeHints runtimeHints) {
459+
if (Proxy.isProxyClass(beanType)) {
460+
// A JDK proxy class needs an explicit hint
461+
runtimeHints.proxies().registerJdkProxy(beanType.getInterfaces());
462+
}
463+
else {
464+
// Potentially a CGLIB-generated subclass with reflection hints
465+
Class<?> userClass = ClassUtils.getUserClass(beanType);
466+
if (userClass != beanType) {
467+
runtimeHints.reflection()
468+
.registerType(beanType, asClassBasedProxy)
469+
.registerType(userClass, asProxiedUserClass);
470+
}
471+
}
472+
}
473+
465474

466475
//---------------------------------------------------------------------
467476
// Convenient methods for registering individual beans

0 commit comments

Comments
 (0)