AbstractAutowireCapableBeanFactory avoids early FactoryBean instantiation on currently created configuration bean
Issue: SPR-12141
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user