Browse Source

AbstractAutowireCapableBeanFactory avoids early FactoryBean instantiation on currently created configuration bean

Issue: SPR-12141
pull/639/head
Juergen Hoeller 11 years ago
parent
commit
4432c41dbd
  1. 3
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  2. 30
      spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanAndAutowiringTests.java
  3. 38
      spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java

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

@ -847,7 +847,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac @@ -847,7 +847,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (bw != null) {
return (FactoryBean<?>) bw.getWrappedInstance();
}
if (isSingletonCurrentlyInCreation(beanName)) {
if (isSingletonCurrentlyInCreation(beanName) ||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
return null;
}
Object instance = null;

30
spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanAndAutowiringTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,12 +17,9 @@ @@ -17,12 +17,9 @@
package org.springframework.context.annotation;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
/**
@ -35,8 +32,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @@ -35,8 +32,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests {
@Test
public void withConcreteFactoryBeanImplementationAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(ConcreteFactoryBeanImplementationConfig.class);
ctx.refresh();
@ -44,8 +40,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @@ -44,8 +40,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests {
@Test
public void withParameterizedFactoryBeanImplementationAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(ParameterizedFactoryBeanImplementationConfig.class);
ctx.refresh();
@ -53,8 +48,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @@ -53,8 +48,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests {
@Test
public void withParameterizedFactoryBeanInterfaceAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(ParameterizedFactoryBeanInterfaceConfig.class);
ctx.refresh();
@ -62,31 +56,27 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @@ -62,31 +56,27 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests {
@Test
public void withNonPublicParameterizedFactoryBeanInterfaceAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(NonPublicParameterizedFactoryBeanInterfaceConfig.class);
ctx.refresh();
}
@Test(expected=BeanCreationException.class)
@Test
public void withRawFactoryBeanInterfaceAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(RawFactoryBeanInterfaceConfig.class);
ctx.refresh();
}
@Test(expected=BeanCreationException.class)
@Test
public void withWildcardParameterizedFactoryBeanInterfaceAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(WildcardParameterizedFactoryBeanInterfaceConfig.class);
ctx.refresh();
}
}

38
spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java

@ -25,6 +25,7 @@ import org.junit.Test; @@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.tests.sample.beans.TestBean;
@ -138,6 +139,16 @@ public class PropertySourceAnnotationTests { @@ -138,6 +139,16 @@ public class PropertySourceAnnotationTests {
System.clearProperty("path.to.properties");
}
@Test
public void withResolvablePlaceholderAndFactoryBean() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithResolvablePlaceholderAndFactoryBean.class);
System.setProperty("path.to.properties", "org/springframework/context/annotation");
ctx.refresh();
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean"));
System.clearProperty("path.to.properties");
}
@Test
public void withEmptyResourceLocations() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@ -251,6 +262,33 @@ public class PropertySourceAnnotationTests { @@ -251,6 +262,33 @@ public class PropertySourceAnnotationTests {
}
@Configuration
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
static class ConfigWithResolvablePlaceholderAndFactoryBean {
@Inject Environment env;
@Bean
public FactoryBean testBean() {
final String name = env.getProperty("testbean.name");
return new FactoryBean() {
@Override
public Object getObject() {
return new TestBean(name);
}
@Override
public Class<?> getObjectType() {
return TestBean.class;
}
@Override
public boolean isSingleton() {
return false;
}
};
}
}
@Configuration
@PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties")
static class ConfigWithExplicitName {

Loading…
Cancel
Save