support scope meta-annotations on factory methods as well
This commit is contained in:
parent
54285ea57c
commit
ec1f0e6211
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue