Skip to content

Commit 309e70a

Browse files
committed
Separate factory method cache for introspection purposes
Issue: SPR-17358 Issue: SPR-8891
1 parent 658c7f9 commit 309e70a

File tree

5 files changed

+13
-17
lines changed

5 files changed

+13
-17
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition m
775775
}
776776
}
777777

778+
mbd.factoryMethodToIntrospect = uniqueCandidate;
778779
if (commonType == null) {
779780
return null;
780781
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,7 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
337337
}
338338
}
339339
}
340-
synchronized (mbd.constructorArgumentLock) {
341-
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
342-
}
340+
mbd.factoryMethodToIntrospect = uniqueCandidate;
343341
}
344342

345343
/**
@@ -448,6 +446,7 @@ public BeanWrapper instantiateUsingFactoryMethod(
448446
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
449447
Method uniqueCandidate = candidateList.get(0);
450448
if (uniqueCandidate.getParameterCount() == 0) {
449+
mbd.factoryMethodToIntrospect = uniqueCandidate;
451450
synchronized (mbd.constructorArgumentLock) {
452451
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
453452
mbd.constructorArgumentsResolved = true;
@@ -598,6 +597,7 @@ else if (ambiguousFactoryMethods != null) {
598597
}
599598

600599
if (explicitArgs == null && argsHolderToUse != null) {
600+
mbd.factoryMethodToIntrospect = factoryMethodToUse;
601601
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
602602
}
603603
}

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,8 @@ protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
755755

756756
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
757757
resolveBeanClass(mbd, beanDefinitionName);
758-
if (mbd.isFactoryMethodUnique) {
759-
boolean resolve;
760-
synchronized (mbd.constructorArgumentLock) {
761-
resolve = (mbd.resolvedConstructorOrFactoryMethod == null);
762-
}
763-
if (resolve) {
764-
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
765-
}
758+
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
759+
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
766760
}
767761
return resolver.isAutowireCandidate(
768762
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
7575
@Nullable
7676
volatile ResolvableType factoryMethodReturnType;
7777

78+
/** Package-visible field for caching a unique factory method candidate for introspection. */
79+
@Nullable
80+
volatile Method factoryMethodToIntrospect;
81+
7882
/** Common lock for the four constructor fields below. */
7983
final Object constructorArgumentLock = new Object();
8084

@@ -370,10 +374,7 @@ public boolean isFactoryMethod(Method candidate) {
370374
*/
371375
@Nullable
372376
public Method getResolvedFactoryMethod() {
373-
synchronized (this.constructorArgumentLock) {
374-
Executable candidate = this.resolvedConstructorOrFactoryMethod;
375-
return (candidate instanceof Method ? (Method) candidate : null);
376-
}
377+
return this.factoryMethodToIntrospect;
377378
}
378379

379380
public void registerExternallyManagedConfigMember(Member configMember) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ public void testCustomWithLazyResolution() {
8383
new AnnotationConfigApplicationContext(CustomConfig.class, CustomPojo.class);
8484
assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
8585
assertFalse(ctx.getBeanFactory().containsSingleton("testBean2"));
86-
// TODO: assertTrue(BeanFactoryAnnotationUtils.isQualifierMatch(value -> value.equals("boring"),
87-
// "testBean2", ctx.getDefaultListableBeanFactory()));
86+
assertTrue(BeanFactoryAnnotationUtils.isQualifierMatch(value -> value.equals("boring"),
87+
"testBean2", ctx.getDefaultListableBeanFactory()));
8888
CustomPojo pojo = ctx.getBean(CustomPojo.class);
8989
assertThat(pojo.testBean.getName(), equalTo("interesting"));
9090
TestBean testBean2 = BeanFactoryAnnotationUtils.qualifiedBeanOfType(

0 commit comments

Comments
 (0)