support scope meta-annotations on factory methods as well

This commit is contained in:
Juergen Hoeller 2009-07-21 14:23:25 +00:00
parent 54285ea57c
commit ec1f0e6211
5 changed files with 41 additions and 31 deletions

View File

@ -63,7 +63,7 @@ import org.springframework.beans.factory.annotation.Autowire;
* @see Primary
* @see org.springframework.context.annotation.Scope
*/
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {

View File

@ -182,8 +182,8 @@ class ConfigurationClassBeanDefinitionReader {
// consider scoping
ScopedProxyMode proxyMode = ScopedProxyMode.NO;
if (metadata.hasAnnotation(Scope.class.getName())) {
Map<String, Object> scopeAttributes = metadata.getAnnotationAttributes(Scope.class.getName());
Map<String, Object> scopeAttributes = metadata.getAnnotationAttributes(Scope.class.getName());
if (scopeAttributes != null) {
beanDef.setScope((String) scopeAttributes.get("value"));
proxyMode = (ScopedProxyMode) scopeAttributes.get("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
@ -195,7 +195,7 @@ class ConfigurationClassBeanDefinitionReader {
BeanDefinition beanDefToRegister = beanDef;
if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = proxyDef.getBeanDefinition();
}

View File

@ -72,7 +72,7 @@ class ConfigurationClassEnhancer {
// handling a @Bean-annotated method; otherwise, return index of the NoOp callback.
callbackFilter = new CallbackFilter() {
public int accept(Method candidateMethod) {
return (AnnotationUtils.findAnnotation(candidateMethod, Bean.class) != null) ? 0 : 1;
return (AnnotationUtils.findAnnotation(candidateMethod, Bean.class) != null ? 0 : 1);
}
};
}
@ -149,8 +149,8 @@ class ConfigurationClassEnhancer {
String beanName = method.getName();
// check to see if the user has explicitly set the bean name
Bean bean = method.getAnnotation(Bean.class);
if(bean != null && bean.name().length > 0) {
Bean bean = AnnotationUtils.findAnnotation(method, Bean.class);
if (bean != null && bean.name().length > 0) {
beanName = bean.name()[0];
}

View File

@ -57,10 +57,9 @@ public @interface Scope {
/**
* Specifies whether a component should be configured as a scoped proxy
* and if so, whether the proxy should be interface-based or subclass-based.
* <p>Defaults to {@link ScopedProxyMode#NO}, indicating no scoped proxy
* should be created.
* <p>Analogous to {@literal <aop:scoped-proxy/>} support in Spring XML. Valid
* only in conjunction with a non-singleton, non-prototype {@link #value()}.
* <p>Defaults to {@link ScopedProxyMode#NO}, indicating that no scoped
* proxy should be created.
* <p>Analogous to {@literal <aop:scoped-proxy/>} support in Spring XML.
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;

View File

@ -16,10 +16,13 @@
package org.springframework.context.annotation.configuration;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.CoreMatchers.*;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
@ -29,8 +32,8 @@ import test.beans.TestBean;
import org.springframework.aop.scope.ScopedObject;
import org.springframework.beans.factory.ObjectFactory;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
@ -67,13 +70,13 @@ public class ScopingTests {
ctx = null;
customScope = null;
}
private GenericApplicationContext createContext(org.springframework.beans.factory.config.Scope customScope, Class<?> configClass) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
if(customScope != null)
if (customScope != null) {
beanFactory.registerScope(SCOPE, customScope);
beanFactory.registerBeanDefinition("config",
rootBeanDefinition(configClass).getBeanDefinition());
}
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(configClass));
GenericApplicationContext ctx = new GenericApplicationContext(beanFactory);
ctx.addBeanFactoryPostProcessor(new ConfigurationClassPostProcessor());
ctx.refresh();
@ -187,10 +190,9 @@ public class ScopingTests {
@Test
public void testScopedConfigurationBeanDefinitionCount() throws Exception {
// count the beans
// 6 @Beans + 1 Configuration + 2 scoped proxy
assertThat(ctx.getBeanDefinitionCount(), equalTo(9));
assertEquals(9, ctx.getBeanDefinitionCount());
}
// /**
@ -294,14 +296,16 @@ public class ScopingTests {
@Configuration
public static class InvalidProxyOnPredefinedScopesConfiguration {
@Bean @Scope(proxyMode=ScopedProxyMode.INTERFACES)
public Object invalidProxyOnPredefinedScopes() { return new Object(); }
}
@Configuration
public static class ScopedConfigurationClass {
@Bean
@Scope(SCOPE)
@MyScope
public TestBean scopedClass() {
TestBean tb = new TestBean();
tb.setName(flag);
@ -309,23 +313,21 @@ public class ScopingTests {
}
@Bean
@Scope(SCOPE)
@MyScope
public ITestBean scopedInterface() {
TestBean tb = new TestBean();
tb.setName(flag);
return tb;
}
@Bean
@Scope(value=SCOPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
@MyProxiedScope
public ITestBean scopedProxyInterface() {
TestBean tb = new TestBean();
tb.setName(flag);
return tb;
}
@Bean
@Scope(value=SCOPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
@MyProxiedScope
public TestBean scopedProxyClass() {
TestBean tb = new TestBean();
tb.setName(flag);
@ -348,6 +350,21 @@ public class ScopingTests {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Scope(SCOPE)
@interface MyScope {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Bean
@Scope(value=SCOPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
@interface MyProxiedScope {
}
/**
* Simple scope implementation which creates object based on a flag.
* @author Costin Leau
@ -359,11 +376,6 @@ public class ScopingTests {
private Map<String, Object> beans = new HashMap<String, Object>();
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
* org.springframework.beans.factory.ObjectFactory)
*/
public Object get(String name, ObjectFactory<?> objectFactory) {
if (createNewScope) {
beans.clear();
@ -394,7 +406,6 @@ public class ScopingTests {
}
public Object resolveContextualObject(String key) {
// TODO Auto-generated method stub
return null;
}
}