Browse Source

Separate factory method cache for introspection purposes

Issue: SPR-17358
Issue: SPR-8891
pull/1985/merge
Juergen Hoeller 8 years ago
parent
commit
309e70a48e
  1. 1
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  2. 6
      spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
  3. 10
      spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
  4. 9
      spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java
  5. 4
      spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanMethodQualificationTests.java

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

@ -775,6 +775,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac @@ -775,6 +775,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
}
mbd.factoryMethodToIntrospect = uniqueCandidate;
if (commonType == null) {
return null;
}

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

@ -337,9 +337,7 @@ class ConstructorResolver { @@ -337,9 +337,7 @@ class ConstructorResolver {
}
}
}
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
}
mbd.factoryMethodToIntrospect = uniqueCandidate;
}
/**
@ -448,6 +446,7 @@ class ConstructorResolver { @@ -448,6 +446,7 @@ class ConstructorResolver {
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;
@ -598,6 +597,7 @@ class ConstructorResolver { @@ -598,6 +597,7 @@ class ConstructorResolver {
}
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}

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

@ -755,14 +755,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -755,14 +755,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
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);

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

@ -75,6 +75,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition { @@ -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();
@ -370,10 +374,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition { @@ -370,10 +374,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
*/
@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) {

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

@ -83,8 +83,8 @@ public class BeanMethodQualificationTests { @@ -83,8 +83,8 @@ public class BeanMethodQualificationTests {
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(

Loading…
Cancel
Save