Skip to content

Commit

Permalink
Separate factory method cache for introspection purposes
Browse files Browse the repository at this point in the history
Issue: SPR-17358
Issue: SPR-8891
  • Loading branch information
jhoeller committed Oct 12, 2018
1 parent 658c7f9 commit 309e70a
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition m
}
}

mbd.factoryMethodToIntrospect = uniqueCandidate;
if (commonType == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,7 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
}
}
}
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
}
mbd.factoryMethodToIntrospect = uniqueCandidate;
}

/**
Expand Down Expand Up @@ -448,6 +446,7 @@ public BeanWrapper instantiateUsingFactoryMethod(
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
Expand Down Expand Up @@ -598,6 +597,7 @@ else if (ambiguousFactoryMethods != null) {
}

if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -755,14 +755,8 @@ protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,

String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
resolveBeanClass(mbd, beanDefinitionName);
if (mbd.isFactoryMethodUnique) {
boolean resolve;
synchronized (mbd.constructorArgumentLock) {
resolve = (mbd.resolvedConstructorOrFactoryMethod == null);
}
if (resolve) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
return resolver.isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
@Nullable
volatile ResolvableType factoryMethodReturnType;

/** Package-visible field for caching a unique factory method candidate for introspection. */
@Nullable
volatile Method factoryMethodToIntrospect;

/** Common lock for the four constructor fields below. */
final Object constructorArgumentLock = new Object();

Expand Down Expand Up @@ -370,10 +374,7 @@ public boolean isFactoryMethod(Method candidate) {
*/
@Nullable
public Method getResolvedFactoryMethod() {
synchronized (this.constructorArgumentLock) {
Executable candidate = this.resolvedConstructorOrFactoryMethod;
return (candidate instanceof Method ? (Method) candidate : null);
}
return this.factoryMethodToIntrospect;
}

public void registerExternallyManagedConfigMember(Member configMember) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ public void testCustomWithLazyResolution() {
new AnnotationConfigApplicationContext(CustomConfig.class, CustomPojo.class);
assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
assertFalse(ctx.getBeanFactory().containsSingleton("testBean2"));
// TODO: assertTrue(BeanFactoryAnnotationUtils.isQualifierMatch(value -> value.equals("boring"),
// "testBean2", ctx.getDefaultListableBeanFactory()));
assertTrue(BeanFactoryAnnotationUtils.isQualifierMatch(value -> value.equals("boring"),
"testBean2", ctx.getDefaultListableBeanFactory()));
CustomPojo pojo = ctx.getBean(CustomPojo.class);
assertThat(pojo.testBean.getName(), equalTo("interesting"));
TestBean testBean2 = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
Expand Down

0 comments on commit 309e70a

Please sign in to comment.