Discovering and accumulating all @Profile meta-annotations

Issue: SPR-10812
This commit is contained in:
Juergen Hoeller 2013-08-26 20:03:32 +02:00
parent c9771012e9
commit aecf60d21f
2 changed files with 78 additions and 27 deletions

View File

@ -16,8 +16,8 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.MultiValueMap;
/** /**
* {@link Condition} that matches based on the value of a {@link Profile @Profile} * {@link Condition} that matches based on the value of a {@link Profile @Profile}
@ -25,15 +25,21 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
* *
* @author Chris Beams * @author Chris Beams
* @author Phillip Webb * @author Phillip Webb
* @author Juergen Hoeller
* @since 4.0 * @since 4.0
*/ */
class ProfileCondition implements Condition { class ProfileCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment() != null && metadata.isAnnotated(Profile.class.getName())) { if (context.getEnvironment() != null) {
AnnotationAttributes profile = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(Profile.class.getName())); MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (!context.getEnvironment().acceptsProfiles(profile.getStringArray("value"))) { if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
return true;
}
}
return false; return false;
} }
} }

View File

@ -16,29 +16,11 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import static org.hamcrest.CoreMatchers.is; import java.lang.annotation.Retention;
import static org.junit.Assert.assertEquals; import java.lang.annotation.RetentionPolicy;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import example.profilescan.DevComponent; import example.profilescan.DevComponent;
import example.profilescan.ProfileAnnotatedComponent; import example.profilescan.ProfileAnnotatedComponent;
import example.profilescan.ProfileMetaAnnotatedComponent; import example.profilescan.ProfileMetaAnnotatedComponent;
@ -50,6 +32,22 @@ import example.scannable.NamedComponent;
import example.scannable.NamedStubDao; import example.scannable.NamedStubDao;
import example.scannable.ServiceInvocationCounter; import example.scannable.ServiceInvocationCounter;
import example.scannable.StubFooDao; import example.scannable.StubFooDao;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/** /**
* @author Mark Fisher * @author Mark Fisher
@ -276,9 +274,39 @@ public class ClassPathScanningCandidateComponentProviderTests {
} }
} }
@Test
public void testIntegrationWithAnnotationConfigApplicationContext_metaProfile() {
Class<?> beanClass = MetaProfileAnnotatedComponent.class;
String beanName = MetaProfileAnnotatedComponent.BEAN_NAME;
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setDefaultProfiles(TEST_DEFAULT_PROFILE_NAME);
// no active profiles are set
ctx.register(beanClass);
ctx.refresh();
assertThat(ctx.containsBean(beanName), is(true));
}
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setDefaultProfiles(TEST_DEFAULT_PROFILE_NAME);
ctx.getEnvironment().setActiveProfiles("dev");
ctx.register(beanClass);
ctx.refresh();
assertThat(ctx.containsBean(beanName), is(true));
}
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setDefaultProfiles(TEST_DEFAULT_PROFILE_NAME);
ctx.getEnvironment().setActiveProfiles("other");
ctx.register(beanClass);
ctx.refresh();
assertThat(ctx.containsBean(beanName), is(false));
}
}
private boolean containsBeanClass(Set<BeanDefinition> candidates, Class<?> beanClass) { private boolean containsBeanClass(Set<BeanDefinition> candidates, Class<?> beanClass) {
for (Iterator<BeanDefinition> it = candidates.iterator(); it.hasNext();) { for (BeanDefinition candidate : candidates) {
ScannedGenericBeanDefinition definition = (ScannedGenericBeanDefinition) it.next(); ScannedGenericBeanDefinition definition = (ScannedGenericBeanDefinition) candidate;
if (beanClass.getName().equals(definition.getBeanClassName())) { if (beanClass.getName().equals(definition.getBeanClassName())) {
return true; return true;
} }
@ -293,9 +321,26 @@ public class ClassPathScanningCandidateComponentProviderTests {
static final String BEAN_NAME = "defaultProfileAnnotatedComponent"; static final String BEAN_NAME = "defaultProfileAnnotatedComponent";
} }
@Profile({TEST_DEFAULT_PROFILE_NAME,"dev"}) @Profile({TEST_DEFAULT_PROFILE_NAME, "dev"})
@Component(DefaultAndDevProfileAnnotatedComponent.BEAN_NAME) @Component(DefaultAndDevProfileAnnotatedComponent.BEAN_NAME)
private static class DefaultAndDevProfileAnnotatedComponent { private static class DefaultAndDevProfileAnnotatedComponent {
static final String BEAN_NAME = "defaultAndDevProfileAnnotatedComponent"; static final String BEAN_NAME = "defaultAndDevProfileAnnotatedComponent";
} }
@DefaultProfile @DevProfile
@Component(MetaProfileAnnotatedComponent.BEAN_NAME)
private static class MetaProfileAnnotatedComponent {
static final String BEAN_NAME = "metaProfileAnnotatedComponent";
}
@Profile(TEST_DEFAULT_PROFILE_NAME)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultProfile {
}
@Profile("dev")
@Retention(RetentionPolicy.RUNTIME)
public @interface DevProfile {
}
} }