[SPR-7960] Renamed @ActivateProfiles to @ActiveProfiles and fleshed out JavaDoc.
This commit is contained in:
parent
0c775416a6
commit
24a97805ef
|
|
@ -24,9 +24,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code ActivateProfiles} is a class-level annotation that is used to
|
* {@code ActiveProfiles} is a class-level annotation that is used to declare
|
||||||
* activate the bean definition profiles to use when loading an
|
* which <em>active bean definition profiles</em> should be used when loading
|
||||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
* an {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||||
* for test classes.
|
* for test classes.
|
||||||
*
|
*
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
|
|
@ -40,7 +40,7 @@ import java.lang.annotation.Target;
|
||||||
@Inherited
|
@Inherited
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface ActivateProfiles {
|
public @interface ActiveProfiles {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for {@link #profiles() profiles}.
|
* Alias for {@link #profiles() profiles}.
|
||||||
|
|
@ -54,9 +54,9 @@ abstract class ContextLoaderUtils {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the {@link ContextLoader}
|
* Resolves the {@link ContextLoader} {@link Class} to use for the
|
||||||
* {@link Class} to use for the supplied {@link Class testClass} and
|
* supplied {@link Class testClass} and then instantiates and returns
|
||||||
* then instantiates and returns that <code>ContextLoader</code>.
|
* that <code>ContextLoader</code>.
|
||||||
*
|
*
|
||||||
* <p>If the supplied <code>defaultContextLoaderClassName</code> is
|
* <p>If the supplied <code>defaultContextLoaderClassName</code> is
|
||||||
* <code>null</code> or <em>empty</em>, the <em>standard</em>
|
* <code>null</code> or <em>empty</em>, the <em>standard</em>
|
||||||
|
|
@ -68,7 +68,7 @@ abstract class ContextLoaderUtils {
|
||||||
* @param defaultContextLoaderClassName the name of the default
|
* @param defaultContextLoaderClassName the name of the default
|
||||||
* <code>ContextLoader</code> class to use (may be <code>null</code>)
|
* <code>ContextLoader</code> class to use (may be <code>null</code>)
|
||||||
* @return the resolved <code>ContextLoader</code> for the supplied
|
* @return the resolved <code>ContextLoader</code> for the supplied
|
||||||
* <code>testClass</code>
|
* <code>testClass</code> (never <code>null</code>)
|
||||||
* @see #resolveContextLoaderClass(Class, String)
|
* @see #resolveContextLoaderClass(Class, String)
|
||||||
*/
|
*/
|
||||||
static ContextLoader resolveContextLoader(Class<?> testClass, String defaultContextLoaderClassName) {
|
static ContextLoader resolveContextLoader(Class<?> testClass, String defaultContextLoaderClassName) {
|
||||||
|
|
@ -85,8 +85,9 @@ abstract class ContextLoaderUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the {@link ContextLoader} {@link Class} to use for the supplied
|
* Resolves the {@link ContextLoader} {@link Class} to use for the supplied
|
||||||
* {@link Class test class}.
|
* {@link Class test class}.
|
||||||
|
*
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>If the {@link ContextConfiguration#loader() loader} attribute of
|
* <li>If the {@link ContextConfiguration#loader() loader} attribute of
|
||||||
* {@link ContextConfiguration @ContextConfiguration} is configured
|
* {@link ContextConfiguration @ContextConfiguration} is configured
|
||||||
|
|
@ -98,11 +99,13 @@ abstract class ContextLoaderUtils {
|
||||||
* the class hierarchy, an attempt will be made to load and return the class
|
* the class hierarchy, an attempt will be made to load and return the class
|
||||||
* with the supplied <code>defaultContextLoaderClassName</code>.</li>
|
* with the supplied <code>defaultContextLoaderClassName</code>.</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
* @param clazz the class for which to retrieve <code>ContextLoader</code>
|
*
|
||||||
|
* @param clazz the class for which to resolve the <code>ContextLoader</code>
|
||||||
* class; must not be <code>null</code>
|
* class; must not be <code>null</code>
|
||||||
* @param defaultContextLoaderClassName the name of the default
|
* @param defaultContextLoaderClassName the name of the default
|
||||||
* <code>ContextLoader</code> class to use; must not be <code>null</code> or empty
|
* <code>ContextLoader</code> class to use; must not be <code>null</code> or empty
|
||||||
* @return the <code>ContextLoader</code> class to use for the specified class
|
* @return the <code>ContextLoader</code> class to use for the specified class
|
||||||
|
* (never <code>null</code>)
|
||||||
* @throws IllegalArgumentException if {@link ContextConfiguration
|
* @throws IllegalArgumentException if {@link ContextConfiguration
|
||||||
* @ContextConfiguration} is not <em>present</em> on the supplied class
|
* @ContextConfiguration} is not <em>present</em> on the supplied class
|
||||||
*/
|
*/
|
||||||
|
|
@ -155,7 +158,7 @@ abstract class ContextLoaderUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve {@link ApplicationContext} resource locations for the supplied
|
* Resolves {@link ApplicationContext} resource locations for the supplied
|
||||||
* {@link Class class}, using the supplied {@link ContextLoader} to
|
* {@link Class class}, using the supplied {@link ContextLoader} to
|
||||||
* {@link ContextLoader#processLocations(Class, String...) process} the
|
* {@link ContextLoader#processLocations(Class, String...) process} the
|
||||||
* locations.
|
* locations.
|
||||||
|
|
@ -166,12 +169,14 @@ abstract class ContextLoaderUtils {
|
||||||
* Specifically, if the <code>inheritLocations</code> flag is set to
|
* Specifically, if the <code>inheritLocations</code> flag is set to
|
||||||
* <code>true</code>, locations defined in the annotated class will be
|
* <code>true</code>, locations defined in the annotated class will be
|
||||||
* appended to the locations defined in superclasses.
|
* appended to the locations defined in superclasses.
|
||||||
|
*
|
||||||
* @param contextLoader the ContextLoader to use for processing the
|
* @param contextLoader the ContextLoader to use for processing the
|
||||||
* locations (must not be <code>null</code>)
|
* locations (must not be <code>null</code>)
|
||||||
* @param clazz the class for which to retrieve the resource locations (must
|
* @param clazz the class for which to resolve the resource locations (must
|
||||||
* not be <code>null</code>)
|
* not be <code>null</code>)
|
||||||
* @return the list of ApplicationContext resource locations for the
|
* @return the list of ApplicationContext resource locations for the
|
||||||
* specified class, including locations from superclasses if appropriate
|
* specified class, including locations from superclasses if appropriate
|
||||||
|
* (never <code>null</code>)
|
||||||
* @throws IllegalArgumentException if {@link ContextConfiguration
|
* @throws IllegalArgumentException if {@link ContextConfiguration
|
||||||
* @ContextConfiguration} is not <em>present</em> on the supplied class
|
* @ContextConfiguration} is not <em>present</em> on the supplied class
|
||||||
*/
|
*/
|
||||||
|
|
@ -190,7 +195,7 @@ abstract class ContextLoaderUtils {
|
||||||
"Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", annotationType,
|
"Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", annotationType,
|
||||||
clazz));
|
clazz));
|
||||||
|
|
||||||
List<String> locationsList = new ArrayList<String>();
|
final List<String> locationsList = new ArrayList<String>();
|
||||||
|
|
||||||
while (declaringClass != null) {
|
while (declaringClass != null) {
|
||||||
ContextConfiguration contextConfiguration = declaringClass.getAnnotation(annotationType);
|
ContextConfiguration contextConfiguration = declaringClass.getAnnotation(annotationType);
|
||||||
|
|
@ -202,25 +207,34 @@ abstract class ContextLoaderUtils {
|
||||||
|
|
||||||
String[] resolvedLocations = locationsResolver.resolveLocations(contextConfiguration, declaringClass);
|
String[] resolvedLocations = locationsResolver.resolveLocations(contextConfiguration, declaringClass);
|
||||||
String[] processedLocations = contextLoader.processLocations(declaringClass, resolvedLocations);
|
String[] processedLocations = contextLoader.processLocations(declaringClass, resolvedLocations);
|
||||||
locationsList.addAll(0, Arrays.<String> asList(processedLocations));
|
locationsList.addAll(0, Arrays.asList(processedLocations));
|
||||||
|
|
||||||
declaringClass = contextConfiguration.inheritLocations() ? AnnotationUtils.findAnnotationDeclaringClass(
|
declaringClass = contextConfiguration.inheritLocations() ? AnnotationUtils.findAnnotationDeclaringClass(
|
||||||
annotationType, declaringClass.getSuperclass()) : null;
|
annotationType, declaringClass.getSuperclass()) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return locationsList.toArray(new String[locationsList.size()]);
|
return StringUtils.toStringArray(locationsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Document resolveActiveProfiles().
|
* Resolves <em>active bean definition profiles</em> for the supplied
|
||||||
|
* {@link Class class}.
|
||||||
|
*
|
||||||
|
* <p>Note that the {@link ActiveProfiles#inheritProfiles() inheritProfiles}
|
||||||
|
* flag of {@link ActiveProfiles @ActiveProfiles} will be taken into
|
||||||
|
* consideration. Specifically, if the <code>inheritProfiles</code> flag is
|
||||||
|
* set to <code>true</code>, profiles defined in the annotated class will be
|
||||||
|
* merged with those defined in superclasses.
|
||||||
*
|
*
|
||||||
* @param clazz
|
* @param clazz the class for which to resolve the active profiles (must
|
||||||
* @return
|
* not be <code>null</code>)
|
||||||
|
* @return the set of active profiles for the specified class, including
|
||||||
|
* active profiles from superclasses if appropriate (never <code>null</code>)
|
||||||
*/
|
*/
|
||||||
static String[] resolveActiveProfiles(Class<?> clazz) {
|
static String[] resolveActiveProfiles(Class<?> clazz) {
|
||||||
Assert.notNull(clazz, "Class must not be null");
|
Assert.notNull(clazz, "Class must not be null");
|
||||||
|
|
||||||
Class<ActivateProfiles> annotationType = ActivateProfiles.class;
|
Class<ActiveProfiles> annotationType = ActiveProfiles.class;
|
||||||
Class<?> declaringClass = AnnotationUtils.findAnnotationDeclaringClass(annotationType, clazz);
|
Class<?> declaringClass = AnnotationUtils.findAnnotationDeclaringClass(annotationType, clazz);
|
||||||
|
|
||||||
if (declaringClass == null && logger.isDebugEnabled()) {
|
if (declaringClass == null && logger.isDebugEnabled()) {
|
||||||
|
|
@ -232,20 +246,20 @@ abstract class ContextLoaderUtils {
|
||||||
final Set<String> activeProfiles = new LinkedHashSet<String>();
|
final Set<String> activeProfiles = new LinkedHashSet<String>();
|
||||||
|
|
||||||
while (declaringClass != null) {
|
while (declaringClass != null) {
|
||||||
ActivateProfiles activateProfiles = declaringClass.getAnnotation(annotationType);
|
ActiveProfiles annotation = declaringClass.getAnnotation(annotationType);
|
||||||
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Retrieved @ActivateProfiles [%s] for declaring class [%s].",
|
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", activeProfiles,
|
||||||
activateProfiles, declaringClass));
|
declaringClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] profiles = activateProfiles.profiles();
|
String[] profiles = annotation.profiles();
|
||||||
String[] valueProfiles = activateProfiles.value();
|
String[] valueProfiles = annotation.value();
|
||||||
|
|
||||||
if (!ObjectUtils.isEmpty(valueProfiles) && !ObjectUtils.isEmpty(profiles)) {
|
if (!ObjectUtils.isEmpty(valueProfiles) && !ObjectUtils.isEmpty(profiles)) {
|
||||||
String msg = String.format("Test class [%s] has been configured with @ActivateProfiles' 'value' [%s] "
|
String msg = String.format("Test class [%s] has been configured with @ActiveProfiles' 'value' [%s] "
|
||||||
+ "and 'profiles' [%s] attributes. Only one declaration of bean "
|
+ "and 'profiles' [%s] attributes. Only one declaration of active bean "
|
||||||
+ "definition profiles is permitted per @ActivateProfiles annotation.", declaringClass,
|
+ "definition profiles is permitted per @ActiveProfiles annotation.", declaringClass,
|
||||||
ObjectUtils.nullSafeToString(valueProfiles), ObjectUtils.nullSafeToString(profiles));
|
ObjectUtils.nullSafeToString(valueProfiles), ObjectUtils.nullSafeToString(profiles));
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new IllegalStateException(msg);
|
throw new IllegalStateException(msg);
|
||||||
|
|
@ -260,7 +274,7 @@ abstract class ContextLoaderUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declaringClass = activateProfiles.inheritProfiles() ? AnnotationUtils.findAnnotationDeclaringClass(
|
declaringClass = annotation.inheritProfiles() ? AnnotationUtils.findAnnotationDeclaringClass(
|
||||||
annotationType, declaringClass.getSuperclass()) : null;
|
annotationType, declaringClass.getSuperclass()) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,30 +108,30 @@ public class ContextLoaderUtilsTests {
|
||||||
private static class Enigma {
|
private static class Enigma {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles
|
@ActiveProfiles
|
||||||
private static class NoProfilesDeclared {
|
private static class NoProfilesDeclared {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles({ " ", "\t" })
|
@ActiveProfiles({ " ", "\t" })
|
||||||
private static class EmptyProfiles {
|
private static class EmptyProfiles {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles({ "foo", "bar", "foo", "bar", "baz" })
|
@ActiveProfiles({ "foo", "bar", "foo", "bar", "baz" })
|
||||||
private static class DuplicatedProfiles {
|
private static class DuplicatedProfiles {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles(profiles = "foo")
|
@ActiveProfiles(profiles = "foo")
|
||||||
private static class Foo {
|
private static class Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InheritedFoo extends Foo {
|
private static class InheritedFoo extends Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles("bar")
|
@ActiveProfiles("bar")
|
||||||
private static class Bar extends Foo {
|
private static class Bar extends Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActivateProfiles(profiles = { "dog", "cat" }, inheritProfiles = false)
|
@ActiveProfiles(profiles = { "dog", "cat" }, inheritProfiles = false)
|
||||||
private static class Animals extends Bar {
|
private static class Animals extends Bar {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue