Skip to content

Commit

Permalink
AbstractAutowireCapableBeanFactory avoids early FactoryBean instantia…
Browse files Browse the repository at this point in the history
…tion on currently created configuration bean

Issue: SPR-12141
  • Loading branch information
jhoeller committed Sep 2, 2014
1 parent 1f6c40f commit 4432c41
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 21 deletions.
Expand Up @@ -847,7 +847,8 @@ private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, Root
if (bw != null) {
return (FactoryBean<?>) bw.getWrappedInstance();
}
if (isSingletonCurrentlyInCreation(beanName)) {
if (isSingletonCurrentlyInCreation(beanName) ||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
return null;
}
Object instance = null;
Expand Down
@@ -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.
Expand All @@ -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;

/**
Expand All @@ -35,58 +32,51 @@ 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();
}

@Test
public void withParameterizedFactoryBeanImplementationAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(ParameterizedFactoryBeanImplementationConfig.class);
ctx.refresh();
}

@Test
public void withParameterizedFactoryBeanInterfaceAsReturnType() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.register(ParameterizedFactoryBeanInterfaceConfig.class);
ctx.refresh();
}

@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();
}

}


Expand Down
Expand Up @@ -25,6 +25,7 @@
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;
Expand Down Expand Up @@ -138,6 +139,16 @@ public void withResolvablePlaceholder() {
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();
Expand Down Expand Up @@ -251,6 +262,33 @@ public TestBean testBean() {
}


@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 {
Expand Down

0 comments on commit 4432c41

Please sign in to comment.