Skip to content

Commit 4432c41

Browse files
committed
AbstractAutowireCapableBeanFactory avoids early FactoryBean instantiation on currently created configuration bean
Issue: SPR-12141
1 parent 1f6c40f commit 4432c41

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,8 @@ private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, Root
847847
if (bw != null) {
848848
return (FactoryBean<?>) bw.getWrappedInstance();
849849
}
850-
if (isSingletonCurrentlyInCreation(beanName)) {
850+
if (isSingletonCurrentlyInCreation(beanName) ||
851+
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
851852
return null;
852853
}
853854
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

+38
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;
@@ -138,6 +139,16 @@ public void withResolvablePlaceholder() {
138139
System.clearProperty("path.to.properties");
139140
}
140141

142+
@Test
143+
public void withResolvablePlaceholderAndFactoryBean() {
144+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
145+
ctx.register(ConfigWithResolvablePlaceholderAndFactoryBean.class);
146+
System.setProperty("path.to.properties", "org/springframework/context/annotation");
147+
ctx.refresh();
148+
assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean"));
149+
System.clearProperty("path.to.properties");
150+
}
151+
141152
@Test
142153
public void withEmptyResourceLocations() {
143154
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -251,6 +262,33 @@ public TestBean testBean() {
251262
}
252263

253264

265+
@Configuration
266+
@PropertySource(value="classpath:${path.to.properties}/p1.properties")
267+
static class ConfigWithResolvablePlaceholderAndFactoryBean {
268+
269+
@Inject Environment env;
270+
271+
@Bean
272+
public FactoryBean testBean() {
273+
final String name = env.getProperty("testbean.name");
274+
return new FactoryBean() {
275+
@Override
276+
public Object getObject() {
277+
return new TestBean(name);
278+
}
279+
@Override
280+
public Class<?> getObjectType() {
281+
return TestBean.class;
282+
}
283+
@Override
284+
public boolean isSingleton() {
285+
return false;
286+
}
287+
};
288+
}
289+
}
290+
291+
254292
@Configuration
255293
@PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties")
256294
static class ConfigWithExplicitName {

0 commit comments

Comments
 (0)