Skip to content

Commit bff2bf2

Browse files
committed
AbstractAutowireCapableBeanFactory avoids early FactoryBean instantiation on currently created configuration bean
Issue: SPR-12141 (cherry picked from commit 4432c41)
1 parent 72d62a7 commit bff2bf2

File tree

3 files changed

+54
-22
lines changed

3 files changed

+54
-22
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,8 @@ private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, Root
832832
if (bw != null) {
833833
return (FactoryBean<?>) bw.getWrappedInstance();
834834
}
835-
if (isSingletonCurrentlyInCreation(beanName)) {
835+
if (isSingletonCurrentlyInCreation(beanName) ||
836+
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
836837
return null;
837838
}
838839
Object instance = null;

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

+10-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,12 +17,9 @@
1717
package org.springframework.context.annotation;
1818

1919
import org.junit.Test;
20-
import org.springframework.beans.factory.BeanCreationException;
20+
2121
import org.springframework.beans.factory.FactoryBean;
2222
import org.springframework.beans.factory.annotation.Autowired;
23-
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
24-
import org.springframework.context.annotation.Bean;
25-
import org.springframework.context.annotation.Configuration;
2623
import org.springframework.util.Assert;
2724

2825
/**
@@ -35,58 +32,51 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests {
3532

3633
@Test
3734
public void withConcreteFactoryBeanImplementationAsReturnType() {
38-
AnnotationConfigApplicationContext ctx =
39-
new AnnotationConfigApplicationContext();
35+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
4036
ctx.register(AppConfig.class);
4137
ctx.register(ConcreteFactoryBeanImplementationConfig.class);
4238
ctx.refresh();
4339
}
4440

4541
@Test
4642
public void withParameterizedFactoryBeanImplementationAsReturnType() {
47-
AnnotationConfigApplicationContext ctx =
48-
new AnnotationConfigApplicationContext();
43+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
4944
ctx.register(AppConfig.class);
5045
ctx.register(ParameterizedFactoryBeanImplementationConfig.class);
5146
ctx.refresh();
5247
}
5348

5449
@Test
5550
public void withParameterizedFactoryBeanInterfaceAsReturnType() {
56-
AnnotationConfigApplicationContext ctx =
57-
new AnnotationConfigApplicationContext();
51+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
5852
ctx.register(AppConfig.class);
5953
ctx.register(ParameterizedFactoryBeanInterfaceConfig.class);
6054
ctx.refresh();
6155
}
6256

6357
@Test
6458
public void withNonPublicParameterizedFactoryBeanInterfaceAsReturnType() {
65-
AnnotationConfigApplicationContext ctx =
66-
new AnnotationConfigApplicationContext();
59+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
6760
ctx.register(AppConfig.class);
6861
ctx.register(NonPublicParameterizedFactoryBeanInterfaceConfig.class);
6962
ctx.refresh();
7063
}
7164

72-
@Test(expected=BeanCreationException.class)
65+
@Test
7366
public void withRawFactoryBeanInterfaceAsReturnType() {
74-
AnnotationConfigApplicationContext ctx =
75-
new AnnotationConfigApplicationContext();
67+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
7668
ctx.register(AppConfig.class);
7769
ctx.register(RawFactoryBeanInterfaceConfig.class);
7870
ctx.refresh();
7971
}
8072

81-
@Test(expected=BeanCreationException.class)
73+
@Test
8274
public void withWildcardParameterizedFactoryBeanInterfaceAsReturnType() {
83-
AnnotationConfigApplicationContext ctx =
84-
new AnnotationConfigApplicationContext();
75+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
8576
ctx.register(AppConfig.class);
8677
ctx.register(WildcardParameterizedFactoryBeanInterfaceConfig.class);
8778
ctx.refresh();
8879
}
89-
9080
}
9181

9282

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

+42-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.junit.rules.ExpectedException;
2626

2727
import org.springframework.beans.factory.BeanDefinitionStoreException;
28+
import org.springframework.beans.factory.FactoryBean;
2829
import org.springframework.core.env.Environment;
2930
import org.springframework.core.env.MutablePropertySources;
3031
import org.springframework.tests.sample.beans.TestBean;
@@ -99,7 +100,7 @@ public void orderingIsLifo() {
99100
}
100101
}
101102

102-
@Test(expected=IllegalArgumentException.class)
103+
@Test(expected = IllegalArgumentException.class)
103104
public void withUnresolvablePlaceholder() {
104105
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
105106
ctx.register(ConfigWithUnresolvablePlaceholder.class);
@@ -124,6 +125,16 @@ public void withResolvablePlaceholder() {
124125
System.clearProperty("path.to.properties");
125126
}
126127

128+
@Test
129+
public void withResolvablePlaceholderAndFactoryBean() {
130+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
131+
ctx.register(ConfigWithResolvablePlaceholderAndFactoryBean.class);
132+
System.setProperty("path.to.properties", "org/springframework/context/annotation");
133+
ctx.refresh();
134+
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean"));
135+
System.clearProperty("path.to.properties");
136+
}
137+
127138
@Test(expected = IllegalArgumentException.class)
128139
public void withEmptyResourceLocations() {
129140
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -201,6 +212,7 @@ static class ConfigWithUnresolvablePlaceholder {
201212
@Configuration
202213
@PropertySource(value="classpath:${unresolvable:org/springframework/context/annotation}/p1.properties")
203214
static class ConfigWithUnresolvablePlaceholderAndDefault {
215+
204216
@Inject Environment env;
205217

206218
@Bean
@@ -213,6 +225,7 @@ public TestBean testBean() {
213225
@Configuration
214226
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
215227
static class ConfigWithResolvablePlaceholder {
228+
216229
@Inject Environment env;
217230

218231
@Bean
@@ -222,10 +235,37 @@ public TestBean testBean() {
222235
}
223236

224237

238+
@Configuration
239+
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
240+
static class ConfigWithResolvablePlaceholderAndFactoryBean {
241+
242+
@Inject Environment env;
243+
244+
@Bean
245+
public FactoryBean testBean() {
246+
final String name = env.getProperty("testbean.name");
247+
return new FactoryBean() {
248+
@Override
249+
public Object getObject() {
250+
return new TestBean(name);
251+
}
252+
@Override
253+
public Class<?> getObjectType() {
254+
return TestBean.class;
255+
}
256+
@Override
257+
public boolean isSingleton() {
258+
return false;
259+
}
260+
};
261+
}
262+
}
263+
225264

226265
@Configuration
227266
@PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties")
228267
static class ConfigWithExplicitName {
268+
229269
@Inject Environment env;
230270

231271
@Bean
@@ -238,6 +278,7 @@ public TestBean testBean() {
238278
@Configuration
239279
@PropertySource("classpath:org/springframework/context/annotation/p1.properties")
240280
static class ConfigWithImplicitName {
281+
241282
@Inject Environment env;
242283

243284
@Bean

0 commit comments

Comments
 (0)