diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 5ca6ec33a3..f1bbf0325c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -795,7 +795,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (bw != null) { return (FactoryBean) bw.getWrappedInstance(); } - if (isSingletonCurrentlyInCreation(beanName)) { + if (isSingletonCurrentlyInCreation(beanName) || + (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) { return null; } Object instance = null; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanAndAutowiringTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanAndAutowiringTests.java index 81e7b1af66..6f4602bd45 100755 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationWithFactoryBeanAndAutowiringTests.java +++ b/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"); * you may not use this file except in compliance with the License. @@ -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; /** @@ -35,8 +32,7 @@ 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(); @@ -44,8 +40,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @Test public void withParameterizedFactoryBeanImplementationAsReturnType() { - AnnotationConfigApplicationContext ctx = - new AnnotationConfigApplicationContext(); + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.register(ParameterizedFactoryBeanImplementationConfig.class); ctx.refresh(); @@ -53,8 +48,7 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @Test public void withParameterizedFactoryBeanInterfaceAsReturnType() { - AnnotationConfigApplicationContext ctx = - new AnnotationConfigApplicationContext(); + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.register(ParameterizedFactoryBeanInterfaceConfig.class); ctx.refresh(); @@ -62,31 +56,27 @@ public class ConfigurationWithFactoryBeanAndAutowiringTests { @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(); } - } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java index 45673cfd65..2a82c94b96 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/PropertySourceAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 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. @@ -16,29 +16,36 @@ package org.springframework.context.annotation; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - +import java.io.FileNotFoundException; import java.util.Iterator; - import javax.inject.Inject; +import org.junit.Rule; import org.junit.Test; +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; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + /** * Tests the processing of @PropertySource annotations on @Configuration classes. * * @author Chris Beams + * @author Phillip Webb * @since 3.1 */ public class PropertySourceAnnotationTests { + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test public void withExplicitName() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); @@ -93,7 +100,7 @@ public class PropertySourceAnnotationTests { } } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void withUnresolvablePlaceholder() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(ConfigWithUnresolvablePlaceholder.class); @@ -118,21 +125,24 @@ public class PropertySourceAnnotationTests { System.clearProperty("path.to.properties"); } - /** - * Corner bug reported in SPR-9127. - */ @Test - public void withNameAndMultipleResourceLocations() { + public void withResolvablePlaceholderAndFactoryBean() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.register(ConfigWithNameAndMultipleResourceLocations.class); + ctx.register(ConfigWithResolvablePlaceholderAndFactoryBean.class); + System.setProperty("path.to.properties", "org/springframework/context/annotation"); ctx.refresh(); - assertThat(ctx.getEnvironment().containsProperty("from.p1"), is(true)); - assertThat(ctx.getEnvironment().containsProperty("from.p2"), is(true)); + assertThat(ctx.getBean(TestBean.class).getName(), equalTo("p1TestBean")); + System.clearProperty("path.to.properties"); } - /** - * SPR-10820 - */ + @Test(expected = IllegalArgumentException.class) + public void withEmptyResourceLocations() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(ConfigWithEmptyResourceLocations.class); + ctx.refresh(); + } + + // SPR-10820 @Test public void orderingWithAndWithoutNameAndMultipleResourceLocations() { // p2 should 'win' as it was registered last @@ -142,11 +152,22 @@ public class PropertySourceAnnotationTests { assertThat(ctxWithName.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean")); } - @Test(expected=IllegalArgumentException.class) - public void withEmptyResourceLocations() { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.register(ConfigWithEmptyResourceLocations.class); - ctx.refresh(); + @Test + public void withNameAndMultipleResourceLocations() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithNameAndMultipleResourceLocations.class); + assertThat(ctx.getEnvironment().containsProperty("from.p1"), is(true)); + assertThat(ctx.getEnvironment().containsProperty("from.p2"), is(true)); + // p2 should 'win' as it was registered last + assertThat(ctx.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean")); + } + + @Test + public void withMultipleResourceLocations() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithMultipleResourceLocations.class); + assertThat(ctx.getEnvironment().containsProperty("from.p1"), is(true)); + assertThat(ctx.getEnvironment().containsProperty("from.p2"), is(true)); + // p2 should 'win' as it was registered last + assertThat(ctx.getEnvironment().getProperty("testbean.name"), equalTo("p2TestBean")); } @@ -159,6 +180,7 @@ public class PropertySourceAnnotationTests { @Configuration @PropertySource(value="classpath:${unresolvable:org/springframework/context/annotation}/p1.properties") static class ConfigWithUnresolvablePlaceholderAndDefault { + @Inject Environment env; @Bean @@ -171,6 +193,7 @@ public class PropertySourceAnnotationTests { @Configuration @PropertySource(value="classpath:${path.to.properties}/p1.properties") static class ConfigWithResolvablePlaceholder { + @Inject Environment env; @Bean @@ -180,10 +203,37 @@ 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 @PropertySource(name="p1", value="classpath:org/springframework/context/annotation/p1.properties") static class ConfigWithExplicitName { + @Inject Environment env; @Bean @@ -196,6 +246,7 @@ public class PropertySourceAnnotationTests { @Configuration @PropertySource("classpath:org/springframework/context/annotation/p1.properties") static class ConfigWithImplicitName { + @Inject Environment env; @Bean @@ -221,6 +272,7 @@ public class PropertySourceAnnotationTests { static class ConfigWithNameAndMultipleResourceLocations { } + @Configuration @PropertySource( value = { @@ -235,4 +287,5 @@ public class PropertySourceAnnotationTests { @PropertySource(value = {}) static class ConfigWithEmptyResourceLocations { } + }