assume a listable bean factory: can therefore also be used
as base class for bean factory implementations which obtain bean definitions
from some backend resource (where bean definition access is an expensive operation).
| Method from org.springframework.beans.factory.support.AbstractBeanFactory Detail: |
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
|
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
this.propertyEditorRegistrars.add(registrar);
}
|
protected void afterPrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.set(null);
}
else if (curVal instanceof Set) {
Set beanNameSet = (Set) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.set(null);
}
}
}
|
protected void beforePrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
else if (curVal instanceof String) {
Set beanNameSet = new HashSet(2);
beanNameSet.add(curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
Set beanNameSet = (Set) curVal;
beanNameSet.add(beanName);
}
}
|
protected void checkMergedBeanDefinition(RootBeanDefinition mbd,
String beanName,
Object[] args) throws BeanDefinitionStoreException {
// check if bean definition is not abstract
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
// Check validity of the usage of the args parameter. This can
// only be used for prototypes constructed via a factory method.
if (args != null && !mbd.isPrototype()) {
throw new BeanDefinitionStoreException(
"Can only specify arguments for the getBean method when referring to a prototype bean definition");
}
}
Check the given merged bean definition,
potentially throwing validation exceptions. |
protected void clearMergedBeanDefinition(String beanName) {
this.mergedBeanDefinitions.remove(beanName);
}
Remove the merged bean definition for the specified bean,
recreating it on next access. |
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found - > check parent.
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}
|
abstract protected boolean containsBeanDefinition(String beanName)
Check if this bean factory contains a bean definition with the given name.
Does not consider any hierarchy this factory may participate in.
Invoked by containsBean when no cached singleton instance is found.
Depending on the nature of the concrete bean factory implementation,
this operation might be expensive (for example, because of directory lookups
in external registries). However, for listable bean factories, this usually
just amounts to a local hash lookup: The operation is therefore part of the
public interface there. The same implementation can serve for both this
template method and the public interface method in that case. |
public boolean containsLocalBean(String name) {
String beanName = transformedBeanName(name);
return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
(!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName)));
}
|
public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
Assert.notNull(otherFactory, "BeanFactory must not be null");
setBeanClassLoader(otherFactory.getBeanClassLoader());
setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
if (otherFactory instanceof AbstractBeanFactory) {
AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
this.customEditors.putAll(otherAbstractFactory.customEditors);
this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
this.scopes.putAll(otherAbstractFactory.scopes);
}
}
|
abstract protected Object createBean(String beanName,
RootBeanDefinition mbd,
Object[] args) throws BeanCreationException
Create a bean instance for the given bean definition.
The bean definition will already have been merged with the parent
definition in case of a child definition.
All the other methods in this class invoke this method, although
beans may be cached after being instantiated by this method. All bean
instantiation within this class is performed by this method. |
public void destroyBean(String beanName,
Object beanInstance) {
destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
}
|
protected void destroyBean(String beanName,
Object beanInstance,
RootBeanDefinition mbd) {
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors()).destroy();
}
Destroy the given bean instance (usually a prototype instance
obtained from this factory) according to the given bean definition. |
public void destroyScopedBean(String beanName) {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (mbd.isSingleton() || mbd.isPrototype()) {
throw new IllegalArgumentException(
"Bean name '" + beanName + "' does not correspond to an object in a Scope");
}
String scopeName = mbd.getScope();
Scope scope = (Scope) this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
Object bean = scope.remove(beanName);
if (bean != null) {
destroyBean(beanName, bean, mbd);
}
}
|
protected Object doGetBean(String name,
Class requiredType,
Object[] args,
boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean = null;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found - > check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args - > delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
String dependsOnBean = dependsOn[i];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype - > create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = (Scope) this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return bean;
}
Return an instance, which may be shared or independent, of the specified bean. |
public String[] getAliases(String name) {
String beanName = transformedBeanName(name);
List aliases = new ArrayList();
boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);
String fullBeanName = beanName;
if (factoryPrefix) {
fullBeanName = FACTORY_BEAN_PREFIX + beanName;
}
if (!fullBeanName.equals(name)) {
aliases.add(fullBeanName);
}
String[] retrievedAliases = super.getAliases(beanName);
for (int i = 0; i < retrievedAliases.length; i++) {
String alias = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + retrievedAliases[i];
if (!alias.equals(name)) {
aliases.add(alias);
}
}
if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null) {
aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName)));
}
}
return StringUtils.toStringArray(aliases);
}
|
public Object getBean(String name) throws BeansException {
return getBean(name, null, null);
}
|
public Object getBean(String name,
Class requiredType) throws BeansException {
return getBean(name, requiredType, null);
}
|
public Object getBean(String name,
Object[] args) throws BeansException {
return getBean(name, null, args);
}
|
public Object getBean(String name,
Class requiredType,
Object[] args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
Return an instance, which may be shared or independent, of the specified bean. |
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
|
abstract protected BeanDefinition getBeanDefinition(String beanName) throws BeansException
Return the bean definition for the given bean name.
Subclasses should normally implement caching, as this method is invoked
by this class every time bean definition metadata is needed.
Depending on the nature of the concrete bean factory implementation,
this operation might be expensive (for example, because of directory lookups
in external registries). However, for listable bean factories, this usually
just amounts to a local hash lookup: The operation is therefore part of the
public interface there. The same implementation can serve for both this
template method and the public interface method in that case. |
public int getBeanPostProcessorCount() {
return this.beanPostProcessors.size();
}
|
public List getBeanPostProcessors() {
return this.beanPostProcessors;
}
Return the list of BeanPostProcessors that will get applied
to beans created with this factory. |
public Map getCustomEditors() {
return this.customEditors;
}
Return the map of custom editors, with Classes as keys
and PropertyEditor instances or PropertyEditor classes as values. |
protected TypeConverter getCustomTypeConverter() {
return this.typeConverter;
}
Return the custom TypeConverter to use, if any. |
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
return getMergedLocalBeanDefinition(beanName);
}
|
protected RootBeanDefinition getMergedBeanDefinition(String beanName,
BeanDefinition bd) throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
Return a RootBeanDefinition for the given top-level bean, by merging with
the parent if the given bean's definition is a child bean definition. |
protected RootBeanDefinition getMergedBeanDefinition(String beanName,
BeanDefinition bd,
BeanDefinition containingBd) throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = (RootBeanDefinition) this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
mbd = new RootBeanDefinition(bd);
}
else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd = null;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(bd.getParentName(),
"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Only cache the merged bean definition if we're already about to create an
// instance of the bean, or at least have already created an instance before.
if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
Return a RootBeanDefinition for the given bean, by merging with the
parent if the given bean's definition is a child bean definition. |
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = (RootBeanDefinition) this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
Return a merged RootBeanDefinition, traversing the parent bean definition
if the specified bean corresponds to a child bean definition. |
protected Object getObjectForBeanInstance(Object beanInstance,
String name,
String beanName,
RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean factory = (FactoryBean) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
Get the object for the given bean instance, either the bean
instance itself or its created object in case of a FactoryBean. |
public BeanFactory getParentBeanFactory() {
return this.parentBeanFactory;
}
|
public Set getPropertyEditorRegistrars() {
return this.propertyEditorRegistrars;
}
Return the set of PropertyEditorRegistrars. |
public Scope getRegisteredScope(String scopeName) {
Assert.notNull(scopeName, "Scope identifier must not be null");
return (Scope) this.scopes.get(scopeName);
}
|
public String[] getRegisteredScopeNames() {
return StringUtils.toStringArray(this.scopes.keySet());
}
|
public ClassLoader getTempClassLoader() {
return this.tempClassLoader;
}
|
public Class getType(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
// Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
return getTypeForFactoryBean((FactoryBean) beanInstance);
}
else {
return beanInstance.getClass();
}
}
else {
// No singleton instance found - > check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory - > delegate to parent.
return parentBeanFactory.getType(originalBeanName(name));
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
Class beanClass = predictBeanType(beanName, mbd, null);
// Check bean class whether we're dealing with a FactoryBean.
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
return getTypeForFactoryBean(beanName, mbd);
}
else {
return beanClass;
}
}
else {
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
}
}
}
|
public TypeConverter getTypeConverter() {
TypeConverter customConverter = getCustomTypeConverter();
if (customConverter != null) {
return customConverter;
}
else {
// Build default TypeConverter, registering custom editors.
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
registerCustomEditors(typeConverter);
return typeConverter;
}
}
|
protected Class getTypeForFactoryBean(String beanName,
RootBeanDefinition mbd) {
if (!mbd.isSingleton()) {
return null;
}
try {
FactoryBean factoryBean =
(FactoryBean) doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
return getTypeForFactoryBean(factoryBean);
}
catch (BeanCreationException ex) {
// Can only happen when getting a FactoryBean.
if (logger.isDebugEnabled()) {
logger.debug("Ignoring bean creation exception on FactoryBean type check: " + ex);
}
onSuppressedException(ex);
return null;
}
}
Determine the bean type for the given FactoryBean definition, as far as possible.
Only called if there is no singleton instance registered for the target bean already.
The default implementation creates the FactoryBean via getBean
to call its getObjectType method. Subclasses are encouraged to optimize
this, typically by just instantiating the FactoryBean but not populating it yet,
trying whether its getObjectType method already returns a type.
If no type found, a full FactoryBean creation as performed by this implementation
should be used as fallback. |
protected boolean hasDestructionAwareBeanPostProcessors() {
return this.hasDestructionAwareBeanPostProcessors;
}
Return whether this factory holds a DestructionAwareBeanPostProcessor
that will get applied to singleton beans on shutdown. |
protected boolean hasInstantiationAwareBeanPostProcessors() {
return this.hasInstantiationAwareBeanPostProcessors;
}
Return whether this factory holds a InstantiationAwareBeanPostProcessor
that will get applied to singleton beans on shutdown. |
protected void initBeanWrapper(BeanWrapper bw) {
registerCustomEditors(bw);
}
|
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
return this.alreadyCreated.contains(beanName);
}
Determine whether the specified bean is eligible for having
its bean definition metadata cached. |
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName);
}
Determine whether the given bean name is already in use within this factory,
i.e. whether there is a local bean or alias registered under this name or
an inner bean created with this name. |
public boolean isCacheBeanMetadata() {
return this.cacheBeanMetadata;
}
|
public boolean isCurrentlyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName);
}
|
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found - > check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory - > delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
|
protected boolean isFactoryBean(String beanName,
RootBeanDefinition mbd) {
Class beanClass = predictBeanType(beanName, mbd, new Class[] {FactoryBean.class});
return (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass));
}
Check whether the given bean is defined as a FactoryBean . |
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory - > delegate to parent.
return parentBeanFactory.isPrototype(originalBeanName(name));
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (mbd.isPrototype()) {
// In case of FactoryBean, return singleton status of created object if not a dereference.
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd));
}
else {
// Singleton or scoped - not a prototype.
// However, FactoryBean may still produce a prototype object...
if (BeanFactoryUtils.isFactoryDereference(name)) {
return false;
}
if (isFactoryBean(beanName, mbd)) {
FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean) factoryBean).isPrototype()) ||
!factoryBean.isSingleton());
}
else {
return false;
}
}
}
|
protected final boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set) curVal).contains(beanName))));
}
Return whether the specified prototype bean is currently in creation
(within the current thread). |
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean) {
return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean) beanInstance).isSingleton());
}
else {
return !BeanFactoryUtils.isFactoryDereference(name);
}
}
else {
// No singleton instance found - > check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory - > delegate to parent.
return parentBeanFactory.isSingleton(originalBeanName(name));
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// In case of FactoryBean, return singleton status of created object if not a dereference.
if (mbd.isSingleton()) {
if (isFactoryBean(beanName, mbd)) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
return true;
}
FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
return factoryBean.isSingleton();
}
else {
return !BeanFactoryUtils.isFactoryDereference(name);
}
}
else {
return false;
}
}
}
|
public boolean isTypeMatch(String name,
Class targetType) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Class typeToMatch = (targetType != null ? targetType : Object.class);
// Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
Class type = getTypeForFactoryBean((FactoryBean) beanInstance);
return (type != null && typeToMatch.isAssignableFrom(type));
}
else {
return typeToMatch.isAssignableFrom(beanInstance.getClass()) ;
}
}
else {
return !BeanFactoryUtils.isFactoryDereference(name) &&
typeToMatch.isAssignableFrom(beanInstance.getClass());
}
}
else {
// No singleton instance found - > check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory - > delegate to parent.
return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
Class beanClass = predictBeanType(beanName, mbd, new Class[] {FactoryBean.class, typeToMatch});
if (beanClass == null) {
return false;
}
// Check bean class whether we're dealing with a FactoryBean.
if (FactoryBean.class.isAssignableFrom(beanClass)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
Class type = getTypeForFactoryBean(beanName, mbd);
return (type != null && typeToMatch.isAssignableFrom(type));
}
else {
return typeToMatch.isAssignableFrom(beanClass);
}
}
else {
return !BeanFactoryUtils.isFactoryDereference(name) &&
typeToMatch.isAssignableFrom(beanClass);
}
}
}
|
protected void markBeanAsCreated(String beanName) {
this.alreadyCreated.add(beanName);
}
|
protected String originalBeanName(String name) {
String beanName = transformedBeanName(name);
if (name.startsWith(FACTORY_BEAN_PREFIX)) {
beanName = FACTORY_BEAN_PREFIX + beanName;
}
return beanName;
}
Determine the original bean name, resolving locally defined aliases to canonical names. |
protected Class predictBeanType(String beanName,
RootBeanDefinition mbd,
Class[] typesToMatch) {
if (mbd.getFactoryMethodName() != null) {
return null;
}
return resolveBeanClass(mbd, beanName, typesToMatch);
}
Predict the eventual bean type (of the processed bean instance) for the
specified bean. Called by #getType and #isTypeMatch .
Does not need to handle FactoryBeans specifically, since it is only
supposed to operate on the raw bean type.
This implementation is simplistic in that it is not able to
handle factory methods and InstantiationAwareBeanPostProcessors.
It only predicts the bean type correctly for a standard bean.
To be overridden in subclasses, applying more sophisticated type detection. |
public void registerCustomEditor(Class requiredType,
Class propertyEditorClass) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
this.customEditors.put(requiredType, propertyEditorClass);
}
|
public void registerCustomEditor(Class requiredType,
PropertyEditor propertyEditor) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.notNull(propertyEditor, "PropertyEditor must not be null");
this.customEditors.put(requiredType, propertyEditor);
}
|
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport =
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
if (!this.propertyEditorRegistrars.isEmpty()) {
for (Iterator it = this.propertyEditorRegistrars.iterator(); it.hasNext();) {
PropertyEditorRegistrar registrar = (PropertyEditorRegistrar) it.next();
try {
registrar.registerCustomEditors(registry);
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
"] failed because it tried to obtain currently created bean '" + ex.getBeanName() +
"': " + ex.getMessage());
}
onSuppressedException(ex);
continue;
}
}
throw ex;
}
}
}
if (!this.customEditors.isEmpty()) {
for (Iterator it = this.customEditors.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Class requiredType = (Class) entry.getKey();
Object value = entry.getValue();
if (value instanceof PropertyEditor) {
PropertyEditor editor = (PropertyEditor) value;
// Register the editor as shared instance, if possible,
// to make it clear that it might be used concurrently.
if (registrySupport != null) {
registrySupport.registerSharedEditor(requiredType, editor);
}
else {
registry.registerCustomEditor(requiredType, editor);
}
}
else if (value instanceof Class) {
Class editorClass = (Class) value;
registry.registerCustomEditor(requiredType, (PropertyEditor) BeanUtils.instantiateClass(editorClass));
}
else {
throw new IllegalStateException("Illegal custom editor value type: " + value.getClass().getName());
}
}
}
}
Initialize the given PropertyEditorRegistry with the custom editors
registered with this BeanFactory.
To be called for BeanWrappers that will create and populate bean
instances, and for SimpleTypeConverter used for constructor argument
and factory method type conversion. |
protected void registerDisposableBeanIfNecessary(String beanName,
Object bean,
RootBeanDefinition mbd) {
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors()));
}
else {
// A bean with a custom scope...
Scope scope = (Scope) this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors()));
}
}
}
Add the given bean to the list of disposable beans in this factory,
registering its DisposableBean interface and/or the given destroy method
to be called on factory shutdown (if applicable). Only applies to singletons. |
public void registerScope(String scopeName,
Scope scope) {
Assert.notNull(scopeName, "Scope identifier must not be null");
Assert.notNull(scope, "Scope must not be null");
if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) {
throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'");
}
this.scopes.put(scopeName, scope);
}
|
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
removeSingleton(beanName);
return true;
}
else {
return false;
}
}
Remove the singleton instance (if any) for the given bean name,
but only if it hasn't been used for other purposes than type checking. |
protected boolean requiresDestruction(Object bean,
RootBeanDefinition mbd) {
return (bean instanceof DisposableBean || mbd.getDestroyMethodName() != null ||
hasDestructionAwareBeanPostProcessors());
}
Determine whether the given bean requires destruction on shutdown.
The default implementation checks the DisposableBean interface as well as
a specified destroy method and registered DestructionAwareBeanPostProcessors. |
protected Class resolveBeanClass(RootBeanDefinition mbd,
String beanName) {
return resolveBeanClass(mbd, beanName, null);
}
Resolve the bean class for the specified bean definition,
resolving a bean class name into a Class reference (if necessary)
and storing the resolved Class in the bean definition for further use. |
protected Class resolveBeanClass(RootBeanDefinition mbd,
String beanName,
Class[] typesToMatch) throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (typesToMatch != null) {
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (int i = 0; i < typesToMatch.length; i++) {
dcl.excludeClass(typesToMatch[i].getName());
}
}
String className = mbd.getBeanClassName();
return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
}
}
return mbd.resolveBeanClass(getBeanClassLoader());
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
Resolve the bean class for the specified bean definition,
resolving a bean class name into a Class reference (if necessary)
and storing the resolved Class in the bean definition for further use. |
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader());
}
|
public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
this.cacheBeanMetadata = cacheBeanMetadata;
}
|
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
}
this.parentBeanFactory = parentBeanFactory;
}
|
public void setTempClassLoader(ClassLoader tempClassLoader) {
this.tempClassLoader = tempClassLoader;
}
|
public void setTypeConverter(TypeConverter typeConverter) {
this.typeConverter = typeConverter;
}
|
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
Return the bean name, stripping out the factory dereference prefix if necessary,
and resolving aliases to canonical names. |