diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ImportedConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ImportedConfig.java new file mode 100644 index 0000000000..f20e79eb7e --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ImportedConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * + * @author Rob Winch + */ +@Configuration +public class ImportedConfig { + @Bean + public String myBean() { + return "myBean"; + } +} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentConfig.java new file mode 100644 index 0000000000..884622e22d --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentConfig.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * + * @author Rob Winch + */ +@Configuration +public class ParentConfig { + @Bean + public String myBean() { + return "myBean"; + } +} + diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithComponentScanConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithComponentScanConfig.java new file mode 100644 index 0000000000..bd6c7b4977 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithComponentScanConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.spr10546.scanpackage.AEnclosingConfig; + + +/** + * + * @author Rob Winch + */ +@Configuration +@ComponentScan(basePackageClasses=AEnclosingConfig.class) +public class ParentWithComponentScanConfig { + +} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportConfig.java new file mode 100644 index 0000000000..450d13fbad --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportConfig.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + + +/** + * + * @author Rob Winch + */ +@Configuration +@Import(ImportedConfig.class) +public class ParentWithImportConfig { + +} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportResourceConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportResourceConfig.java new file mode 100644 index 0000000000..e05f4134ec --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithImportResourceConfig.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + + +/** + * + * @author Rob Winch + */ +@Configuration +@ImportResource("classpath:org/springframework/context/annotation/spr10546/importedResource.xml") +public class ParentWithImportResourceConfig { + +} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithParentConfig.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithParentConfig.java new file mode 100644 index 0000000000..dcaaa3b5b2 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/ParentWithParentConfig.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.springframework.context.annotation.Configuration; + + +/** + * + * @author Rob Winch + */ +@Configuration +public class ParentWithParentConfig extends ParentConfig { + +} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/Spr10546Tests.java b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/Spr10546Tests.java new file mode 100644 index 0000000000..59dac470a2 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/Spr10546Tests.java @@ -0,0 +1,149 @@ +/* + * Copyright 2002-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.spr10546; + +import org.junit.After; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.spr10546.scanpackage.AEnclosingConfig; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + + +/** + * + * @author Rob Winch + */ +public class Spr10546Tests { + private ConfigurableApplicationContext context; + + @After + public void closeContext() { + if(context != null) { + context.close(); + } + } + + // These fail prior to fixing SPR-10546 + + @Test + public void enclosingConfigFirstParentDefinesBean() { + assertLoadsMyBean(AEnclosingConfig.class,AEnclosingConfig.ChildConfig.class); + } + + /** + * Prior to fixing SPR-10546 this might have succeeded depending on the ordering the + * classes were picked up. If they are picked up in the same order as + * {@link #enclosingConfigFirstParentDefinesBean()} then it would fail. This test is + * mostly for illustration purposes, but doesn't hurt to continue using it. + * + *
We purposely use the {@link AEnclosingConfig} to make it alphabetically prior to the
+ * {@link AEnclosingConfig.ChildConfig} which encourages this to occur with the
+ * classpath scanning implementation being used by the author of this test.
+ */
+ @Test
+ public void enclosingConfigFirstParentDefinesBeanWithScanning() {
+ AnnotationConfigApplicationContext ctx= new AnnotationConfigApplicationContext();
+ context = ctx;
+ ctx.scan(AEnclosingConfig.class.getPackage().getName());
+ ctx.refresh();
+ assertThat(context.getBean("myBean",String.class), equalTo("myBean"));
+ }
+
+ @Test
+ public void enclosingConfigFirstParentDefinesBeanWithImportResource() {
+ assertLoadsMyBean(AEnclosingWithImportResourceConfig.class,AEnclosingWithImportResourceConfig.ChildConfig.class);
+ }
+
+ @Configuration
+ static class AEnclosingWithImportResourceConfig {
+ @Configuration
+ public static class ChildConfig extends ParentWithImportResourceConfig {}
+ }
+
+ @Test
+ public void enclosingConfigFirstParentDefinesBeanWithComponentScan() {
+ assertLoadsMyBean(AEnclosingWithComponentScanConfig.class,AEnclosingWithComponentScanConfig.ChildConfig.class);
+ }
+
+ @Configuration
+ static class AEnclosingWithComponentScanConfig {
+ @Configuration
+ public static class ChildConfig extends ParentWithComponentScanConfig {}
+ }
+
+ @Test
+ public void enclosingConfigFirstParentWithParentDefinesBean() {
+ assertLoadsMyBean(AEnclosingWithGrandparentConfig.class,AEnclosingWithGrandparentConfig.ChildConfig.class);
+ }
+
+ @Configuration
+ static class AEnclosingWithGrandparentConfig {
+ @Configuration
+ public static class ChildConfig extends ParentWithParentConfig {}
+ }
+
+ @Test
+ public void importChildConfigThenChildConfig() {
+ assertLoadsMyBean(ImportChildConfig.class,ChildConfig.class);
+ }
+
+ @Configuration
+ static class ChildConfig extends ParentConfig {}
+
+ @Configuration
+ @Import(ChildConfig.class)
+ static class ImportChildConfig {}
+
+
+ // These worked prior, but validating they continue to work
+
+ @Test
+ public void enclosingConfigFirstParentDefinesBeanWithImport() {
+ assertLoadsMyBean(AEnclosingWithImportConfig.class,AEnclosingWithImportConfig.ChildConfig.class);
+ }
+
+ @Configuration
+ static class AEnclosingWithImportConfig {
+ @Configuration
+ public static class ChildConfig extends ParentWithImportConfig {}
+ }
+
+ @Test
+ public void childConfigFirst() {
+ assertLoadsMyBean(AEnclosingConfig.ChildConfig.class, AEnclosingConfig.class);
+ }
+
+ @Test
+ public void enclosingConfigOnly() {
+ assertLoadsMyBean(AEnclosingConfig.class);
+ }
+
+ @Test
+ public void childConfigOnly() {
+ assertLoadsMyBean(AEnclosingConfig.ChildConfig.class);
+ }
+
+ private void assertLoadsMyBean(Class>... annotatedClasses) {
+ context = new AnnotationConfigApplicationContext(annotatedClasses);
+ assertThat(context.getBean("myBean",String.class), equalTo("myBean"));
+ }
+}
diff --git a/spring-context/src/test/java/org/springframework/context/annotation/spr10546/importedResource.xml b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/importedResource.xml
new file mode 100644
index 0000000000..6ce3074b51
--- /dev/null
+++ b/spring-context/src/test/java/org/springframework/context/annotation/spr10546/importedResource.xml
@@ -0,0 +1,8 @@
+
+