AbstractBeanFactory
Abstract base class for BeanFactory
implementations, providing the full capabilities of the ConfigurableBeanFactory
SPI.
Does not 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).
This class provides a singleton cache (through its base class DefaultSingletonBeanRegistry
, singleton/prototype determination, FactoryBean
handling, aliases, bean definition merging for child bean definitions, and bean destruction (DisposableBean
interface, custom destroy methods). Furthermore, it can manage a bean factory hierarchy (delegating to the parent in case of an unknown bean), through implementing the HierarchicalBeanFactory
interface.
The main template methods to be implemented by subclasses are getBeanDefinition(java.lang.String)
and createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
, retrieving a bean definition for a given bean name and creating a bean instance for a given bean definition, respectively. Default implementations of those operations can be found in DefaultListableBeanFactory
and AbstractAutowireCapableBeanFactory
.
member variable
/** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** * Parent bean factory, for bean inheritance support */ private BeanFactory parentBeanFactory; /** * Custom PropertyEditors to apply to the beans of this factory */ private Map customEditors = new HashMap(); /** * BeanPostProcessors to apply in createBean */ private final List beanPostProcessors = new ArrayList(); /** Indicates whether any DestructionAwareBeanPostProcessors have been registered */ private boolean hasDestructionAwareBeanPostProcessors; /** Map from alias to canonical bean name */ private final Map aliasMap = new HashMap(); /** Cache of singletons: bean name --> bean instance */ private final Map singletonCache = new HashMap(); /** Names of beans that are currently in creation */ private final Set currentlyInCreation = Collections.synchronizedSet(new HashSet()); /** Disposable bean instances: bean name --> disposable instance */ private final Map disposableBeans = CollectionFactory.createLinkedMapIfPossible(16); /** Map between dependent bean names: bean name --> dependent bean name */ private final Map dependentBeanMap = new HashMap();
在member variable中,除了parentBeanFactory没有赋值(初始化为空),所有的都是在声明的时候就赋值了。
therefor, 继续看看该类的构造函数,除了默认的构造函数外,还有一个参数为parentBeanFactory的构造器,目的是为已经声明的parentBeanFactory赋值。
现在分析getBean(String name, Class requiredType, Object[] args)
在方法的前后有固定的操作,查找与所查Bean规范的名字,在方法结尾,要对取得的bean进行类型匹配。
现在看看方法内部的流程
首先会在singletonCatch查找,如果查到了,会检查该singleton现在是否已经初始化完成了,
但此时无论该singleton是否初始化完成,会执行如下的代码
bean = getObjectForSharedInstance(name, sharedInstance);
目的是该Bean有可能是一个FactoryBean,如果是的话,在返回对象的时候就不能返回一个FactoryBean,而是要返回FactoryBean的getObject()得到的对象。
现在如果在singletonCatch缓存中没有查到,
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException { String beanName = transformedBeanName(name); Object bean = null; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = null; synchronized (this.singletonCache) { sharedInstance = this.singletonCache.get(beanName); } if (sharedInstance != null) { if (isSingletonCurrentlyInCreation(beanName)) { if (logger.isDebugEnabled()) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } } else { if (logger.isDebugEnabled()) { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForSharedInstance(name, sharedInstance); } else { // Fail if we're already creating this singleton instance: // We're assumably within a circular reference. if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. if (getParentBeanFactory() != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. if (getParentBeanFactory() instanceof AbstractBeanFactory) { // Delegation to parent with args only possible for AbstractBeanFactory. return ((AbstractBeanFactory) getParentBeanFactory()).getBean(name, requiredType, args); } else if (args == null) { // No args -> delegate to standard getBean method. return getParentBeanFactory().getBean(name, requiredType); } else { throw new NoSuchBeanDefinitionException(beanName, "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments"); } } RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false); checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args); // Create bean instance. if (mergedBeanDefinition.isSingleton()) { synchronized (this.singletonCache) { // Re-check singleton cache within synchronized block. sharedInstance = this.singletonCache.get(beanName); if (sharedInstance == null) { if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } this.currentlyInCreation.add(beanName); try { sharedInstance = createBean(beanName, mergedBeanDefinition, args); addSingleton(beanName, sharedInstance); } 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. destroyDisposableBean(beanName); throw ex; } finally { this.currentlyInCreation.remove(beanName); } } } bean = getObjectForSharedInstance(name, sharedInstance); } else { // It's a prototype -> create a new instance. bean = createBean(beanName, mergedBeanDefinition, args); } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return bean; }
// Delegation to parent with args only possible for AbstractBeanFactory.