diff --git a/spring-test/.springBeans b/spring-test/.springBeans
index aa53e0e658..dc7397a838 100644
--- a/spring-test/.springBeans
+++ b/spring-test/.springBeans
@@ -1,7 +1,7 @@
Prior to Spring 3.1, only path-based resource locations were supported. * As of Spring 3.1, {@linkplain #loader context loaders} may choose to support - * either path-based or class-based resources (but not both). Consequently + * either path-based or class-based resources. As of Spring + * 4.0.4, {@linkplain #loader context loaders} may choose to support path-based + * and class-based resources simultaneously. Consequently * {@code @ContextConfiguration} can be used to declare either path-based - * resource locations (via the {@link #locations} or {@link #value} - * attribute) or annotated classes (via the {@link #classes} - * attribute). + * resource locations (via the {@link #locations} or {@link #value} attribute) + * or annotated classes (via the {@link #classes} attribute). Note, + * however, that most implementations of {@link SmartContextLoader} only support + * a single resource type. * *
This attribute may not be used in conjunction - * with {@link #locations} or {@link #classes}, but it may be used - * instead of {@link #locations}. + *
This attribute may not be used in conjunction with + * {@link #locations}, but it may be used instead of {@link #locations}. * @since 3.0 * @see #inheritLocations */ @@ -117,8 +119,7 @@ public @interface ContextConfiguration { * loaders. * *
This attribute may not be used in conjunction with - * {@link #value} or {@link #classes}, but it may be used instead of - * {@link #value}. + * {@link #value}, but it may be used instead of {@link #value}. * @since 2.5 * @see #inheritLocations */ @@ -135,9 +136,6 @@ public @interface ContextConfiguration { * annotated classes are specified. See the documentation for * {@link #loader} for further details regarding default loaders. * - *
This attribute may not be used in conjunction with - * {@link #locations} or {@link #value}. - * * @since 3.1 * @see org.springframework.context.annotation.Configuration * @see org.springframework.test.context.support.AnnotationConfigContextLoader diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java index fcf1ab05b8..16569e5aea 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.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. @@ -29,9 +29,8 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** - * {@code ContextConfigurationAttributes} encapsulates the context - * configuration attributes declared on a test class via - * {@link ContextConfiguration @ContextConfiguration}. + * {@code ContextConfigurationAttributes} encapsulates the context configuration + * attributes declared via {@link ContextConfiguration @ContextConfiguration}. * * @author Sam Brannen * @since 3.1 @@ -111,8 +110,9 @@ public class ContextConfigurationAttributes { /** * Construct a new {@link ContextConfigurationAttributes} instance for the - * supplied {@link ContextConfiguration @ContextConfiguration} annotation and - * the {@linkplain Class test class} that declared it. + * supplied {@link AnnotationAttributes} (parsed from a + * {@link ContextConfiguration @ContextConfiguration} annotation) and + * the {@linkplain Class test class} that declared them. * @param declaringClass the test class that declared {@code @ContextConfiguration} * @param annAttrs the annotation attributes from which to retrieve the attributes */ @@ -140,7 +140,7 @@ public class ContextConfigurationAttributes { * @param inheritLocations the {@code inheritLocations} flag declared via {@code @ContextConfiguration} * @param contextLoaderClass the {@code ContextLoader} class declared via {@code @ContextConfiguration} * @throws IllegalArgumentException if the {@code declaringClass} or {@code contextLoaderClass} is - * {@code null}, or if the {@code locations} and {@code classes} are both non-empty + * {@code null} * @deprecated as of Spring 3.2, use * {@link #ContextConfigurationAttributes(Class, String[], Class[], boolean, Class[], boolean, String, Class)} * instead @@ -165,7 +165,7 @@ public class ContextConfigurationAttributes { * @param inheritInitializers the {@code inheritInitializers} flag declared via {@code @ContextConfiguration} * @param contextLoaderClass the {@code ContextLoader} class declared via {@code @ContextConfiguration} * @throws IllegalArgumentException if the {@code declaringClass} or {@code contextLoaderClass} is - * {@code null}, or if the {@code locations} and {@code classes} are both non-empty + * {@code null} */ public ContextConfigurationAttributes(Class> declaringClass, String[] locations, Class>[] classes, boolean inheritLocations, @@ -190,7 +190,7 @@ public class ContextConfigurationAttributes { * @param name the name of level in the context hierarchy, or {@code null} if not applicable * @param contextLoaderClass the {@code ContextLoader} class declared via {@code @ContextConfiguration} * @throws IllegalArgumentException if the {@code declaringClass} or {@code contextLoaderClass} is - * {@code null}, or if the {@code locations} and {@code classes} are both non-empty + * {@code null} */ public ContextConfigurationAttributes(Class> declaringClass, String[] locations, Class>[] classes, boolean inheritLocations, @@ -200,14 +200,13 @@ public class ContextConfigurationAttributes { Assert.notNull(declaringClass, "declaringClass must not be null"); Assert.notNull(contextLoaderClass, "contextLoaderClass must not be null"); - if (!ObjectUtils.isEmpty(locations) && !ObjectUtils.isEmpty(classes)) { - String msg = String.format( + if (!ObjectUtils.isEmpty(locations) && !ObjectUtils.isEmpty(classes) && logger.isDebugEnabled()) { + logger.debug(String.format( "Test class [%s] has been configured with @ContextConfiguration's 'locations' (or 'value') %s " - + "and 'classes' %s attributes. Only one declaration of resources " - + "is permitted per @ContextConfiguration annotation.", declaringClass.getName(), - ObjectUtils.nullSafeToString(locations), ObjectUtils.nullSafeToString(classes)); - logger.error(msg); - throw new IllegalArgumentException(msg); + + "and 'classes' %s attributes. Most SmartContextLoader implementations support " + + "only one declaration of resources per @ContextConfiguration annotation.", + declaringClass.getName(), ObjectUtils.nullSafeToString(locations), + ObjectUtils.nullSafeToString(classes))); } this.declaringClass = declaringClass; diff --git a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index befe85c7cb..5dc0f20cff 100644 --- a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -226,6 +226,46 @@ public class MergedContextConfiguration implements Serializable { return classes; } + /** + * Determine if this {@code MergedContextConfiguration} instance has + * path-based resource locations. + * + * @return {@code true} if the {@link #getLocations() locations} array is not empty + * @since 4.0.4 + * @see #hasResources() + * @see #hasClasses() + */ + public boolean hasLocations() { + return !ObjectUtils.isEmpty(getLocations()); + } + + /** + * Determine if this {@code MergedContextConfiguration} instance has + * class-based resources. + * + * @return {@code true} if the {@link #getClasses() classes} array is not empty + * @since 4.0.4 + * @see #hasResources() + * @see #hasLocations() + */ + public boolean hasClasses() { + return !ObjectUtils.isEmpty(getClasses()); + } + + /** + * Determine if this {@code MergedContextConfiguration} instance has + * either path-based resource locations or class-based resources. + * + * @return {@code true} if either the {@link #getLocations() locations} + * or the {@link #getClasses() classes} array is not empty + * @since 4.0.4 + * @see #hasLocations() + * @see #hasClasses() + */ + public boolean hasResources() { + return hasLocations() || hasClasses(); + } + /** * Get the merged {@code ApplicationContextInitializer} classes for the * {@linkplain #getTestClass() test class}. diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java index dc8bb8d68a..41e42fcf4e 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.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. @@ -68,6 +68,8 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader *
Implementation details: * *
The default implementation is a no-op but can be overridden by + * subclasses as appropriate. + * @param mergedConfig the merged configuration to validate + * @throws IllegalStateException if the supplied configuration is not valid + * for this context loader + * @since 4.0.4 + */ + protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) { + /* no-op */ + } + /** * Load a Spring ApplicationContext from the supplied {@code locations}. * diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java index 29a26c5e25..c3b63aef92 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.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. @@ -76,9 +76,8 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader */ @Override public void processContextConfiguration(ContextConfigurationAttributes configAttributes) { - if (ObjectUtils.isEmpty(configAttributes.getClasses()) && isGenerateDefaultLocations()) { - Class>[] defaultConfigClasses = detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()); - configAttributes.setClasses(defaultConfigClasses); + if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) { + configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass())); } } @@ -148,6 +147,24 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader // --- AbstractGenericContextLoader ---------------------------------------- + /** + * Ensure that the supplied {@link MergedContextConfiguration} does not + * contain {@link MergedContextConfiguration#getLocations() locations}. + * @since 4.0.4 + * @see AbstractGenericContextLoader#validateMergedContextConfiguration + */ + @Override + protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) { + if (mergedConfig.hasLocations()) { + String msg = String.format( + "Test class [%s] has been configured with @ContextConfiguration's 'locations' (or 'value') attribute %s, " + + "but %s does not support resource locations.", mergedConfig.getTestClass().getName(), + ObjectUtils.nullSafeToString(mergedConfig.getLocations()), getClass().getSimpleName()); + logger.error(msg); + throw new IllegalStateException(msg); + } + } + /** * Register classes in the supplied {@link GenericApplicationContext context} * from the classes in the supplied {@link MergedContextConfiguration}. diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java index f192a194ca..9b247990d1 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.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. @@ -83,7 +83,7 @@ public abstract class AnnotationConfigContextLoaderUtils { * configuration classes that comply with the constraints required of * {@code @Configuration} class implementations. If a potential candidate * configuration class does not meet these requirements, this method will log a - * warning, and the potential candidate class will be ignored. + * debug message, and the potential candidate class will be ignored. * @param declaringClass the test class that declared {@code @ContextConfiguration} * @return an array of default configuration classes, potentially empty but * never {@code null} diff --git a/spring-test/src/main/java/org/springframework/test/context/support/GenericPropertiesContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/GenericPropertiesContextLoader.java index 823688797f..86d0c3a0b8 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/GenericPropertiesContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/GenericPropertiesContextLoader.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. @@ -21,6 +21,8 @@ import java.util.Properties; import org.springframework.beans.factory.support.BeanDefinitionReader; import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.util.ObjectUtils; /** * Concrete implementation of {@link AbstractGenericContextLoader} that reads @@ -45,8 +47,26 @@ public class GenericPropertiesContextLoader extends AbstractGenericContextLoader * Returns "{@code -context.properties}". */ @Override - public String getResourceSuffix() { + protected String getResourceSuffix() { return "-context.properties"; } + /** + * Ensure that the supplied {@link MergedContextConfiguration} does not + * contain {@link MergedContextConfiguration#getClasses() classes}. + * @since 4.0.4 + * @see AbstractGenericContextLoader#validateMergedContextConfiguration + */ + @Override + protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) { + if (mergedConfig.hasClasses()) { + String msg = String.format( + "Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, " + + "but %s does not support annotated classes.", mergedConfig.getTestClass().getName(), + ObjectUtils.nullSafeToString(mergedConfig.getClasses()), getClass().getSimpleName()); + logger.error(msg); + throw new IllegalStateException(msg); + } + } + } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/GenericXmlContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/GenericXmlContextLoader.java index 9c636e0e70..0e43bec0e9 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/GenericXmlContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/GenericXmlContextLoader.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. @@ -19,6 +19,8 @@ package org.springframework.test.context.support; import org.springframework.beans.factory.support.BeanDefinitionReader; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.util.ObjectUtils; /** * Concrete implementation of {@link AbstractGenericContextLoader} that reads @@ -43,8 +45,26 @@ public class GenericXmlContextLoader extends AbstractGenericContextLoader { * Returns "{@code -context.xml}". */ @Override - public String getResourceSuffix() { + protected String getResourceSuffix() { return "-context.xml"; } + /** + * Ensure that the supplied {@link MergedContextConfiguration} does not + * contain {@link MergedContextConfiguration#getClasses() classes}. + * @since 4.0.4 + * @see AbstractGenericContextLoader#validateMergedContextConfiguration + */ + @Override + protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) { + if (mergedConfig.hasClasses()) { + String msg = String.format( + "Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, " + + "but %s does not support annotated classes.", mergedConfig.getTestClass().getName(), + ObjectUtils.nullSafeToString(mergedConfig.getClasses()), getClass().getSimpleName()); + logger.error(msg); + throw new IllegalStateException(msg); + } + } + } diff --git a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java index 91ee9e79aa..7482eafd3b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.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. @@ -20,7 +20,6 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; @@ -59,7 +58,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext; */ public abstract class AbstractGenericWebContextLoader extends AbstractContextLoader { - private static final Log logger = LogFactory.getLog(AbstractGenericWebContextLoader.class); + protected static final Log logger = LogFactory.getLog(AbstractGenericWebContextLoader.class); // --- SmartContextLoader ----------------------------------------------- @@ -71,6 +70,8 @@ public abstract class AbstractGenericWebContextLoader extends AbstractContextLoa *
Implementation details: * *
The default implementation is a no-op but can be overridden by
+ * subclasses as appropriate.
+ * @param mergedConfig the merged configuration to validate
+ * @throws IllegalStateException if the supplied configuration is not valid
+ * for this context loader
+ * @since 4.0.4
+ */
+ protected void validateMergedContextConfiguration(WebMergedContextConfiguration mergedConfig) {
+ /* no-op */
+ }
+
/**
* Configures web resources for the supplied web application context (WAC).
*
diff --git a/spring-test/src/main/java/org/springframework/test/context/web/AnnotationConfigWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/AnnotationConfigWebContextLoader.java
index e82a63807d..940b11bdcc 100644
--- a/spring-test/src/main/java/org/springframework/test/context/web/AnnotationConfigWebContextLoader.java
+++ b/spring-test/src/main/java/org/springframework/test/context/web/AnnotationConfigWebContextLoader.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.
@@ -18,9 +18,9 @@ package org.springframework.test.context.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.test.context.ContextConfigurationAttributes;
+import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.support.GenericWebApplicationContext;
@@ -77,9 +77,8 @@ public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextL
*/
@Override
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
- if (ObjectUtils.isEmpty(configAttributes.getClasses()) && isGenerateDefaultLocations()) {
- Class>[] defaultConfigClasses = detectDefaultConfigurationClasses(configAttributes.getDeclaringClass());
- configAttributes.setClasses(defaultConfigClasses);
+ if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
+ configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
}
}
@@ -170,4 +169,22 @@ public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextL
new AnnotatedBeanDefinitionReader(context).register(annotatedClasses);
}
+ /**
+ * Ensure that the supplied {@link WebMergedContextConfiguration} does not
+ * contain {@link MergedContextConfiguration#getLocations() locations}.
+ * @since 4.0.4
+ * @see AbstractGenericWebContextLoader#validateMergedContextConfiguration
+ */
+ @Override
+ protected void validateMergedContextConfiguration(WebMergedContextConfiguration webMergedConfig) {
+ if (webMergedConfig.hasLocations()) {
+ String msg = String.format(
+ "Test class [%s] has been configured with @ContextConfiguration's 'locations' (or 'value') attribute %s, "
+ + "but %s does not support resource locations.", webMergedConfig.getTestClass().getName(),
+ ObjectUtils.nullSafeToString(webMergedConfig.getLocations()), getClass().getSimpleName());
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ }
+
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/web/GenericXmlWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/GenericXmlWebContextLoader.java
index d172fed883..a704ec3b0a 100644
--- a/spring-test/src/main/java/org/springframework/test/context/web/GenericXmlWebContextLoader.java
+++ b/spring-test/src/main/java/org/springframework/test/context/web/GenericXmlWebContextLoader.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,6 +17,8 @@
package org.springframework.test.context.web;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.test.context.MergedContextConfiguration;
+import org.springframework.util.ObjectUtils;
import org.springframework.web.context.support.GenericWebApplicationContext;
/**
@@ -46,4 +48,22 @@ public class GenericXmlWebContextLoader extends AbstractGenericWebContextLoader
return "-context.xml";
}
+ /**
+ * Ensure that the supplied {@link WebMergedContextConfiguration} does not
+ * contain {@link MergedContextConfiguration#getClasses() classes}.
+ * @since 4.0.4
+ * @see AbstractGenericWebContextLoader#validateMergedContextConfiguration
+ */
+ @Override
+ protected void validateMergedContextConfiguration(WebMergedContextConfiguration webMergedConfig) {
+ if (webMergedConfig.hasClasses()) {
+ String msg = String.format(
+ "Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, "
+ + "but %s does not support annotated classes.", webMergedConfig.getTestClass().getName(),
+ ObjectUtils.nullSafeToString(webMergedConfig.getClasses()), getClass().getSimpleName());
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ }
+
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java
index f32d068e43..6025c2d47f 100644
--- a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java
@@ -143,9 +143,26 @@ public class ContextLoaderUtilsConfigurationAttributesTests extends AbstractCont
assertClassesFooAttributes(attributesList.get(1));
}
+ /**
+ * Verifies change requested in SPR-11634.
+ * @since 4.0.4
+ */
+ @Test
+ public void resolveConfigAttributesWithLocationsAndClasses() {
+ List This test loader is inspired by Spring Boot.
+ * Detects defaults for XML configuration and annotated classes.
+ * Beans from XML configuration always override those from annotated classes.
+ *
+ * @author Sam Brannen
+ * @since 4.0.4
+ */
+public class HybridContextLoader extends AbstractGenericContextLoader {
+
+ @Override
+ protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
+ Assert.isTrue(mergedConfig.hasClasses() || mergedConfig.hasLocations(), getClass().getSimpleName()
+ + " requires either classes or locations");
+ }
+
+ @Override
+ public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
+ // Detect default XML configuration files:
+ super.processContextConfiguration(configAttributes);
+
+ // Detect default configuration classes:
+ if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
+ configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
+ }
+ }
+
+ @Override
+ protected void loadBeanDefinitions(GenericApplicationContext context, MergedContextConfiguration mergedConfig) {
+ // Order doesn't matter: