revised scope inheritance: default scope is "" (empty String) now; consistent isPrototype checks

This commit is contained in:
Juergen Hoeller 2009-11-19 18:32:10 +00:00
parent ee5330801d
commit b41e3956bc
5 changed files with 34 additions and 16 deletions

View File

@ -211,9 +211,17 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
* @see #SCOPE_SINGLETON
*/
boolean isSingleton();
/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* Return whether this bean is "abstract", that is, not meant to be instantiated.
*/

View File

@ -301,7 +301,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
RootBeanDefinition bd = null;
if (mbd instanceof RootBeanDefinition) {
RootBeanDefinition rbd = (RootBeanDefinition) mbd;
if (SCOPE_PROTOTYPE.equals(rbd.getScope())) {
if (rbd.isPrototype()) {
bd = rbd;
}
}

View File

@ -33,6 +33,7 @@ import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Base class for concrete, full-fledged
@ -54,6 +55,13 @@ import org.springframework.util.ObjectUtils;
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
/**
* Constant for the default scope name: "", equivalent to singleton status
* but to be overridden from a parent bean definition (if applicable).
*/
public static final String SCOPE_DEFAULT = "";
/**
* Constant that indicates no autowiring at all.
* @see #setAutowireMode
@ -118,7 +126,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
private volatile Object beanClass;
private String scope;
private String scope = SCOPE_DEFAULT;
private boolean singleton = true;
@ -273,16 +281,16 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* </ul>
*/
public void overrideFrom(BeanDefinition other) {
if (other.getBeanClassName() != null) {
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
if (other.getFactoryBeanName() != null) {
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (other.getFactoryMethodName() != null) {
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
if (other.getScope() != null) {
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
setAbstract(other.isAbstract());
@ -306,11 +314,11 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
setDependsOn(otherAbd.getDependsOn());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
if (StringUtils.hasLength(otherAbd.getInitMethodName())) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
if (StringUtils.hasLength(otherAbd.getDestroyMethodName())) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
@ -405,14 +413,17 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Set the name of the target scope for the bean.
* <p>Default is "singleton"; the out-of-the-box alternative is "prototype".
* Extended bean factories might support further scopes.
* <p>Default is singleton status, although this is only applied once
* a bean definition becomes active in the containing factory. A bean
* definition may eventually inherit its scope from a parent bean definitionFor this
* reason, the default scope name is empty (empty String), with
* singleton status being assumed until a resolved scope will be set.
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
public void setScope(String scope) {
this.scope = scope;
this.singleton = SCOPE_SINGLETON.equals(scope);
this.singleton = SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
this.prototype = SCOPE_PROTOTYPE.equals(scope);
}

View File

@ -1115,7 +1115,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
// Set default singleton scope, if not configured before.
if (mbd.getScope() == null) {
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}

View File

@ -260,15 +260,14 @@
The scope of this bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton".
By default, a bean will be a singleton, unless the bean has a parent
bean definition in which case it will inherit the parent's scope.
Singletons are most commonly used, and are ideal for multi-threaded
service objects. Further scopes, such as "request" or "session", might
be supported by extended bean factories (e.g. in a web environment).
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
Inner bean definitions inherit the singleton status of their containing
bean definition, unless explicitly specified: The inner bean will be a
singleton if the containing bean is a singleton, and a prototype if