abstractbeanfactory.java
来自「spring,z几 塞积极 决撒 积极上经济歼击机就 将计就计经济年毫毫毫毫毫毫」· Java 代码 · 共 1,161 行 · 第 1/3 页
JAVA
1,161 行
if (parentBeanFactory != null) {
return parentBeanFactory.getAliases(name);
}
throw new NoSuchBeanDefinitionException(beanName, toString());
}
}
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
//---------------------------------------------------------------------
public BeanFactory getParentBeanFactory() {
return parentBeanFactory;
}
public boolean containsLocalBean(String name) {
String beanName = transformedBeanName(name);
return (containsSingleton(beanName) || containsBeanDefinition(beanName));
}
//---------------------------------------------------------------------
// Implementation of ConfigurableBeanFactory interface
//---------------------------------------------------------------------
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
this.parentBeanFactory = parentBeanFactory;
}
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);
}
/**
* Return the map of custom editors, with Classes as keys
* and PropertyEditors as values.
*/
public Map getCustomEditors() {
return customEditors;
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
public int getBeanPostProcessorCount() {
return this.beanPostProcessors.size();
}
/**
* Return the list of BeanPostProcessors that will get applied
* to beans created with this factory.
*/
public List getBeanPostProcessors() {
return beanPostProcessors;
}
/**
* Return whether this factory holds a DestructionAwareBeanPostProcessor
* that will get applied to singleton beans on shutdown.
* @see #addBeanPostProcessor
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
*/
protected boolean hasDestructionAwareBeanPostProcessors() {
return this.hasDestructionAwareBeanPostProcessors;
}
public void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.hasText(alias, "Alias must not be empty");
if (logger.isDebugEnabled()) {
logger.debug("Registering alias '" + alias + "' for bean with name '" + beanName + "'");
}
synchronized (this.aliasMap) {
Object registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
throw new BeanDefinitionStoreException("Cannot register alias '" + alias + "' for bean name '" +
beanName + "': it's already registered for bean name '" + registeredName + "'");
}
this.aliasMap.put(alias, beanName);
}
}
public void registerSingleton(String beanName, Object singletonObject) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonCache) {
Object oldObject = this.singletonCache.get(beanName);
if (oldObject != null) {
throw new BeanDefinitionStoreException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there's already object [" + oldObject + " bound");
}
addSingleton(beanName, singletonObject);
}
}
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonCache) {
this.singletonCache.put(beanName, singletonObject);
}
}
/**
* Remove the bean with the given name from the singleton cache of this factory.
* <p>To be able to clean up eager registration of a singleton if creation failed.
* @param beanName the name of the bean
*/
protected void removeSingleton(String beanName) {
Assert.hasText(beanName, "Bean name must not be empty");
synchronized (this.singletonCache) {
this.singletonCache.remove(beanName);
}
}
/**
* Return the number of beans in the singleton cache.
* <p>Does not consider any hierarchy this factory may participate in.
*/
public int getSingletonCount() {
synchronized (this.singletonCache) {
return this.singletonCache.size();
}
}
/**
* Return the names of beans in the singleton cache.
* <p>Does not consider any hierarchy this factory may participate in.
*/
public String[] getSingletonNames() {
synchronized (this.singletonCache) {
return StringUtils.toStringArray(this.singletonCache.keySet());
}
}
/**
* Return whether the specified singleton is currently in creation
* @param beanName the name of the bean
*/
protected boolean isSingletonCurrentlyInCreation(String beanName) {
return this.currentlyInCreation.contains(beanName);
}
public boolean containsSingleton(String beanName) {
Assert.hasText(beanName, "Bean name must not be empty");
synchronized (this.singletonCache) {
return this.singletonCache.containsKey(beanName);
}
}
public void destroySingletons() {
if (logger.isInfoEnabled()) {
logger.info("Destroying singletons in factory {" + this + "}");
}
synchronized (this.singletonCache) {
synchronized (this.disposableBeans) {
String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
for (int i = 0; i < disposableBeanNames.length; i++) {
destroyDisposableBean(disposableBeanNames[i]);
}
}
this.singletonCache.clear();
}
}
//---------------------------------------------------------------------
// Implementation methods
//---------------------------------------------------------------------
/**
* Return whether the given name is a factory dereference
* (beginning with the factory dereference prefix).
* @see BeanFactory#FACTORY_BEAN_PREFIX
* @see org.springframework.beans.factory.BeanFactoryUtils#isFactoryDereference
*/
protected boolean isFactoryDereference(String name) {
return BeanFactoryUtils.isFactoryDereference(name);
}
/**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
*/
protected String transformedBeanName(String name) {
String beanName = BeanFactoryUtils.transformedBeanName(name);
// handle aliasing
synchronized (this.aliasMap) {
String canonicalName = (String) this.aliasMap.get(beanName);
return canonicalName != null ? canonicalName : beanName;
}
}
/**
* Initialize the given BeanWrapper with the custom editors registered
* with this factory. To be called for BeanWrappers that will create
* and populate bean instances.
* @param bw the BeanWrapper to initialize
*/
protected void initBeanWrapper(BeanWrapper bw) {
for (Iterator it = getCustomEditors().entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Class clazz = (Class) entry.getKey();
PropertyEditor editor = (PropertyEditor) entry.getValue();
bw.registerCustomEditor(clazz, editor);
}
}
/**
* Convert the given value into the specified target type,
* using a default BeanWrapper instance.
* @param value the original value
* @param targetType the target type
* @return the converted value, matching the target type
* @throws org.springframework.beans.TypeMismatchException if type conversion failed
* @see #doTypeConversionIfNecessary(Object, Class, org.springframework.beans.BeanWrapperImpl)
*/
protected Object doTypeConversionIfNecessary(Object value, Class targetType) throws TypeMismatchException {
BeanWrapperImpl bw = new BeanWrapperImpl();
initBeanWrapper(bw);
return doTypeConversionIfNecessary(value, targetType, bw);
}
/**
* Convert the given value into the specified target type,
* using the specified BeanWrapper.
* @param value the original value
* @param targetType the target type
* @param bw the BeanWrapper to work on
* @return the converted value, matching the target type
* @throws org.springframework.beans.TypeMismatchException if type conversion failed
* @see org.springframework.beans.BeanWrapperImpl#doTypeConversionIfNecessary(Object, Class)
*/
protected Object doTypeConversionIfNecessary(Object value, Class targetType, BeanWrapperImpl bw)
throws TypeMismatchException {
// Synchronize if custom editors are registered.
// Necessary because PropertyEditors are not thread-safe.
if (!getCustomEditors().isEmpty()) {
synchronized (getCustomEditors()) {
return bw.doTypeConversionIfNecessary(value, targetType);
}
}
else {
return bw.doTypeConversionIfNecessary(value, targetType);
}
}
/**
* Return a RootBeanDefinition for the given bean name,
* merging a child bean definition with its parent if necessary.
* @param name the name of the bean to retrieve the merged definition for
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeansException in case of errors
*/
public RootBeanDefinition getMergedBeanDefinition(String name) throws BeansException {
return getMergedBeanDefinition(name, false);
}
/**
* Return a RootBeanDefinition, even by traversing parent if the parameter is a
* child definition. Can ask the parent bean factory if not found in this instance.
* @param name the name of the bean to retrieve the merged definition for
* @param includingAncestors whether to ask the parent bean factory if not found
* in this instance
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(String name, boolean includingAncestors)
throws BeansException {
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
if (includingAncestors && !containsBeanDefinition(beanName) &&
getParentBeanFactory() instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName, true);
}
// Resolve merged bean definition locally.
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
/**
* Return a RootBeanDefinition for the given bean name, by merging with the
* parent if the given original bean definition is a child bean definition.
* @param beanName the name of the bean definition
* @param bd the original bean definition (Root/ChildBeanDefinition)
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
if (bd instanceof RootBeanDefinition) {
// Return root bean definition as-is.
return (RootBeanDefinition) bd;
}
else if (bd instanceof ChildBeanDefinition) {
// Child bean definition: needs to be merged with parent.
ChildBeanDefinition cbd = (ChildBeanDefinition) bd;
RootBeanDefinition pbd = null;
try {
if (!beanName.equals(cbd.getParentName())) {
pbd = getMergedBeanDefinition(cbd.getParentName(), true);
}
else {
if (getParentBeanFactory() instanceof AbstractBeanFactory) {
AbstractBeanFactory parentFactory = (AbstractBeanFactory) getParentBeanFactory();
pbd = parentFactory.getMergedBeanDefinition(cbd.getParentName(), true);
}
else {
throw new NoSuchBeanDefinitionException(cbd.getParentName(),
"Parent name '" + cbd.getParentName() + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(cbd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + cbd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
RootBeanDefinition rbd = new RootBeanDefinition(pbd);
rbd.overrideFrom(cbd);
// Validate merged definition: mainly to prepare method overrides.
try {
rbd.validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(rbd.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
return rbd;
}
else {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Definition is neither a RootBeanDefinition nor a ChildBeanDefinition");
}
}
/**
* Check the given merged bean definition,
* potentially throwing validation exceptions.
* @param mergedBeanDefinition the bean definition to check
* @param beanName the name of the bean
* @param requiredType the required type of the bean
* @param args the arguments for bean creation, if any
* @throws BeansException in case of validation failure
*/
protected void checkMergedBeanDefinition(
RootBeanDefinition mergedBeanDefinition, String beanName, Class requiredType, Object[] args)
throws BeansException {
// check if bean definition is not abstract
if (mergedBeanDefinition.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
// Check if required type can match according to the bean definition.
// This is only possible at this early stage for conventional beans!
if (mergedBeanDefinition.hasBeanClass()) {
Class beanClass = mergedBeanDefinition.getBeanClass();
if (requiredType != null && mergedBeanDefinition.getFactoryMethodName() == null &&
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?