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
if (bw != null) { if (bw != null) {
return (FactoryBean<?>) bw.getWrappedInstance(); return (FactoryBean<?>) bw.getWrappedInstance();
} }
if (isSingletonCurrentlyInCreation(beanName)) { if (isSingletonCurrentlyInCreation(beanName) ||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
return null; return null;
} }
Object instance = null; Object instance = null;

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

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

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

@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.MutablePropertySources;
import org.springframework.tests.sample.beans.TestBean; import org.springframework.tests.sample.beans.TestBean;
@ -138,6 +139,16 @@ public class PropertySourceAnnotationTests {
System.clearProperty("path.to.properties"); 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 @Test
public void withEmptyResourceLocations() { public void withEmptyResourceLocations() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@ -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 @Configuration
@PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties") @PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties")
static class ConfigWithExplicitName { static class ConfigWithExplicitName {

Loading…
Cancel
Save