Allow meta-annotations to override attributes from their parent

Issue: SPR-10181
This commit is contained in:
Juergen Hoeller
2013-08-21 17:35:56 +02:00
parent 87c2d6fd12
commit 6d3649858e
11 changed files with 434 additions and 261 deletions

View File

@@ -16,12 +16,11 @@
package org.springframework.context.annotation;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
@@ -29,6 +28,8 @@ import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import static org.junit.Assert.*;
/**
* @author Rick Evans
* @author Chris Beams
@@ -83,6 +84,15 @@ public final class AnnotationScopeMetadataResolverTests {
assertEquals(ScopedProxyMode.NO, scopeMetadata.getScopedProxyMode());
}
@Test
public void testCustomRequestScopeWithAttribute() {
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(AnnotatedWithCustomRequestScopeWithAttribute.class);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(bd);
assertNotNull("resolveScopeMetadata(..) must *never* return null.", scopeMetadata);
assertEquals("request", scopeMetadata.getScopeName());
assertEquals(ScopedProxyMode.TARGET_CLASS, scopeMetadata.getScopedProxyMode());
}
@Test(expected=IllegalArgumentException.class)
public void testCtorWithNullScopedProxyMode() {
new AnnotationScopeMetadataResolver(null);
@@ -98,17 +108,21 @@ public final class AnnotationScopeMetadataResolverTests {
private static final class AnnotatedWithSingletonScope {
}
@Scope("prototype")
private static final class AnnotatedWithPrototypeScope {
}
@Scope(value="request", proxyMode = ScopedProxyMode.TARGET_CLASS)
private static final class AnnotatedWithScopedProxy {
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Scope("request")
public @interface CustomRequestScope {
}
@CustomRequestScope
private static final class AnnotatedWithCustomRequestScope {
}
@@ -117,8 +131,13 @@ public final class AnnotationScopeMetadataResolverTests {
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Scope("request")
public @interface CustomRequestScope {
public @interface CustomRequestScopeWithAttribute {
ScopedProxyMode proxyMode();
}
@CustomRequestScopeWithAttribute(proxyMode = ScopedProxyMode.TARGET_CLASS)
private static final class AnnotatedWithCustomRequestScopeWithAttribute {
}
}

View File

@@ -20,6 +20,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.Test;
import org.springframework.tests.sample.beans.NestedTestBean;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -60,9 +62,19 @@ public class BeanMethodQualificationTests {
assertThat(pojo.testBean.getName(), equalTo("interesting"));
}
@Test
public void testCustomWithAttributeOverride() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(CustomConfigWithAttributeOverride.class, CustomPojo.class);
assertFalse(ctx.getBeanFactory().containsSingleton("testBeanX"));
CustomPojo pojo = ctx.getBean(CustomPojo.class);
assertThat(pojo.testBean.getName(), equalTo("interesting"));
}
@Configuration
static class StandardConfig {
@Bean @Lazy @Qualifier("interesting")
public TestBean testBean1() {
return new TestBean("interesting");
@@ -76,11 +88,13 @@ public class BeanMethodQualificationTests {
@Component @Lazy
static class StandardPojo {
@Autowired @Qualifier("interesting") TestBean testBean;
}
@Configuration
static class CustomConfig {
@InterestingBean
public TestBean testBean1() {
return new TestBean("interesting");
@@ -92,9 +106,26 @@ public class BeanMethodQualificationTests {
}
}
@Configuration
static class CustomConfigWithAttributeOverride {
@InterestingBeanWithName(name="testBeanX")
public TestBean testBean1() {
return new TestBean("interesting");
}
@Bean @Qualifier("boring")
public TestBean testBean2() {
return new TestBean("boring");
}
}
@InterestingPojo
static class CustomPojo {
@InterestingNeed TestBean testBean;
@InterestingNeedWithRequiredOverride(required=false) NestedTestBean nestedTestBean;
}
@Bean @Lazy @Qualifier("interesting")
@@ -102,11 +133,25 @@ public class BeanMethodQualificationTests {
public @interface InterestingBean {
}
@Bean @Lazy @Qualifier("interesting")
@Retention(RetentionPolicy.RUNTIME)
public @interface InterestingBeanWithName {
String name();
}
@Autowired @Qualifier("interesting")
@Retention(RetentionPolicy.RUNTIME)
public @interface InterestingNeed {
}
@Autowired @Qualifier("interesting")
@Retention(RetentionPolicy.RUNTIME)
public @interface InterestingNeedWithRequiredOverride {
boolean required();
}
@Component @Lazy
@Retention(RetentionPolicy.RUNTIME)
public @interface InterestingPojo {