Skip to content

Commit e15f7ef

Browse files
committed
InjectionPoint propagated for shortcut bean name resolution as well
Issue: SPR-14400
1 parent 4102c62 commit e15f7ef

File tree

4 files changed

+75
-34
lines changed

4 files changed

+75
-34
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
5252
import org.springframework.beans.factory.config.DependencyDescriptor;
5353
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
54-
import org.springframework.beans.factory.config.RuntimeBeanReference;
5554
import org.springframework.beans.factory.support.LookupOverride;
5655
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
5756
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -529,9 +528,6 @@ private Object resolvedCachedArgument(String beanName, Object cachedArgument) {
529528
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
530529
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
531530
}
532-
else if (cachedArgument instanceof RuntimeBeanReference) {
533-
return this.beanFactory.getBean(((RuntimeBeanReference) cachedArgument).getBeanName());
534-
}
535531
else {
536532
return cachedArgument;
537533
}
@@ -581,7 +577,7 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
581577
String autowiredBeanName = autowiredBeanNames.iterator().next();
582578
if (beanFactory.containsBean(autowiredBeanName)) {
583579
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
584-
this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
580+
this.cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName);
585581
}
586582
}
587583
}
@@ -665,7 +661,8 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
665661
String autowiredBeanName = it.next();
666662
if (beanFactory.containsBean(autowiredBeanName)) {
667663
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
668-
this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName);
664+
this.cachedMethodArguments[i] =
665+
new ShortcutDependencyDescriptor(descriptors[i], autowiredBeanName);
669666
}
670667
}
671668
}
@@ -701,4 +698,24 @@ private Object[] resolveCachedArguments(String beanName) {
701698
}
702699
}
703700

701+
702+
/**
703+
* DependencyDescriptor variant with a pre-resolved target bean name.
704+
*/
705+
@SuppressWarnings("serial")
706+
private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
707+
708+
private final String shortcutBeanName;
709+
710+
public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcutBeanName) {
711+
super(original);
712+
this.shortcutBeanName = shortcutBeanName;
713+
}
714+
715+
@Override
716+
public Object resolveShortcut(BeanFactory beanFactory) {
717+
return resolveCandidate(this.shortcutBeanName, beanFactory);
718+
}
719+
}
720+
704721
}

spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,21 @@ public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
187187
return beanFactory.getBean(beanName);
188188
}
189189

190+
/**
191+
* Resolve a shortcut for this dependency against the given factory, for example
192+
* taking some pre-resolved information into account.
193+
* <p>The resolution algorithm will first attempt to resolve a shortcut through this
194+
* method before going into the regular type matching algorithm across all beans.
195+
* Subclasses may override this method to improve resolution performance based on
196+
* pre-cached information while still receiving {@link InjectionPoint} exposure etc.
197+
* @param beanFactory the associated factory
198+
* @return the shortcut result if any, or {@code null} if none
199+
* @since 4.3.1
200+
*/
201+
public Object resolveShortcut(BeanFactory beanFactory) {
202+
return null;
203+
}
204+
190205

191206
/**
192207
* Increase this descriptor's nesting level.

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,27 +1024,32 @@ else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
10241024
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
10251025
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
10261026

1027-
Class<?> type = descriptor.getDependencyType();
1028-
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
1029-
if (value != null) {
1030-
if (value instanceof String) {
1031-
String strVal = resolveEmbeddedValue((String) value);
1032-
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
1033-
value = evaluateBeanDefinitionString(strVal, bd);
1027+
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
1028+
try {
1029+
Object shortcut = descriptor.resolveShortcut(this);
1030+
if (shortcut != null) {
1031+
return shortcut;
1032+
}
1033+
1034+
Class<?> type = descriptor.getDependencyType();
1035+
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
1036+
if (value != null) {
1037+
if (value instanceof String) {
1038+
String strVal = resolveEmbeddedValue((String) value);
1039+
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
1040+
value = evaluateBeanDefinitionString(strVal, bd);
1041+
}
1042+
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
1043+
return (descriptor.getField() != null ?
1044+
converter.convertIfNecessary(value, type, descriptor.getField()) :
1045+
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
10341046
}
1035-
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
1036-
return (descriptor.getField() != null ?
1037-
converter.convertIfNecessary(value, type, descriptor.getField()) :
1038-
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
1039-
}
10401047

1041-
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
1042-
if (multipleBeans != null) {
1043-
return multipleBeans;
1044-
}
1048+
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
1049+
if (multipleBeans != null) {
1050+
return multipleBeans;
1051+
}
10451052

1046-
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
1047-
try {
10481053
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
10491054
if (matchingBeans.isEmpty()) {
10501055
if (descriptor.isRequired()) {

spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
import org.springframework.beans.factory.ListableBeanFactory;
3232
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3333
import org.springframework.beans.factory.annotation.Autowired;
34-
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
3534
import org.springframework.beans.factory.annotation.Qualifier;
36-
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
3735
import org.springframework.beans.factory.annotation.Required;
3836
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
3937
import org.springframework.beans.factory.annotation.Value;
@@ -210,16 +208,17 @@ public void configurationWithPrototypeScopedBeans() {
210208

211209
@Test
212210
public void configurationWithAdaptivePrototypes() {
213-
DefaultListableBeanFactory factory =
214-
initBeanFactory(ConfigWithPrototypeBean.class, AdaptiveInjectionPoints.class);
215-
AutowiredAnnotationBeanPostProcessor aabpp = new AutowiredAnnotationBeanPostProcessor();
216-
aabpp.setBeanFactory(factory);
217-
factory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
218-
factory.addBeanPostProcessor(aabpp);
211+
AnnotationConfigApplicationContext factory = new AnnotationConfigApplicationContext();
212+
factory.register(ConfigWithPrototypeBean.class, AdaptiveInjectionPoints.class);
213+
factory.refresh();
219214

220215
AdaptiveInjectionPoints adaptive = factory.getBean(AdaptiveInjectionPoints.class);
221216
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
222-
assertEquals("adaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
217+
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
218+
219+
adaptive = factory.getBean(AdaptiveInjectionPoints.class);
220+
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
221+
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
223222
}
224223

225224
@Test
@@ -357,13 +356,18 @@ public TestBean adaptive2(DependencyDescriptor dd) {
357356
}
358357

359358

359+
@Scope("prototype")
360360
static class AdaptiveInjectionPoints {
361361

362362
@Autowired @Qualifier("adaptive1")
363363
public TestBean adaptiveInjectionPoint1;
364364

365-
@Autowired @Qualifier("adaptive2")
366365
public TestBean adaptiveInjectionPoint2;
366+
367+
@Autowired @Qualifier("adaptive2")
368+
public void setAdaptiveInjectionPoint2(TestBean adaptiveInjectionPoint2) {
369+
this.adaptiveInjectionPoint2 = adaptiveInjectionPoint2;
370+
}
367371
}
368372

369373

0 commit comments

Comments
 (0)