Spring原始碼系列:BeanFactory的建立

glmapper發表於2018-01-29

Spring的Ioc容器其實就是一個bean的關係網,依賴於core,bean,context三個元件來構建的。在spring中最核心的就是對於bean的管理。而bean又依託於我們的容器。本文將從頂層分析一下spring中beanFactory的具體建立過程,為後續的bean的生命週期提供一個基礎。

BeanFactory的繼承體系

Spring原始碼系列:BeanFactory的建立
從上圖可以看到,BeanFactory有三個子類:

  • ListableBeanFactory
  • HierarchicalBeanFactory
  • AutowireCapableBeanFactory

(上述三個類的子類體系小夥伴們可以自己對著原始碼看下,實在太多)

看下上圖中最底層的DefaultListableBeanFactory類的定義:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
	implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
複製程式碼

這個其實就是BeanFactory的預設實現類,它直接或者間接的實現了所有的介面。其實在看spring原始碼的時候都會遇到類似的設計模式,對於某一個具體的功能,通常都會定義很多層的介面,層層包裝,層層委託。這種做法的好處就是,對於不同的場合都會有特定的介面;這樣一來就可以在spring內部對物件的傳遞和轉化操作都會有一些訪問限制。

例如ListableBeanFactory介面表示這些Bean是可列表的,而HierarchicalBeanFactory表示的是這些Bean是有繼承關係的,也就是每個Bean有可能有父Bean。AutowireCapableBeanFactory介面定義Bean的自動裝配規則。這四個介面共同定義了Bean的集合、Bean之間的關係、以及Bean行為。

BeanFactory的建立

在之前的文章中說過了容器的重新整理過程。BeanFactory的建立也在wac.refresh()方法中。具體看下到底是通過哪些子類來完成的:

// 通知子類重新整理內部的bean工廠。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
複製程式碼

1.AbstractApplicationContext中的obtainFreshBeanFactory

下面是obtainFreshBeanFactory的方法邏輯:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //這個是具體建立的方法,由子類實現
	refreshBeanFactory();
	//獲取BeanFactory例項物件(ConfigurableListableBeanFactory型別的)
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}
複製程式碼

refreshBeanFactory並未有具體的實現邏輯,這個方法主要是通過委託給子類的refreshBeanFactory方法來實現,在AbstractApplicationContext中refreshBeanFactory是一個抽象模板方法:

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
複製程式碼

2.refreshBeanFactory方法(AbstractRefreshableApplicationContext類中):

下面只註釋與beanFactory建立相關的程式碼

protected final void refreshBeanFactory() throws BeansException {
    //是否已經有BeanFactory了
    if (hasBeanFactory()) {
        //銷燬原有的Bean
    	destroyBeans();
    	//關閉工廠
    	closeBeanFactory();
    }
    try {
        //建立一個新的beanFactory
    	DefaultListableBeanFactory beanFactory = createBeanFactory();
    	beanFactory.setSerializationId(getId());
    	customizeBeanFactory(beanFactory);
    	loadBeanDefinitions(beanFactory);
    	synchronized (this.beanFactoryMonitor) {
    		this.beanFactory = beanFactory;
    	}
    }
    catch (IOException ex) {
    	throw new ApplicationContextException("I/O error parsing bean definition 
    	source for " + getDisplayName(), ex);
    }
}
複製程式碼

這個方法是實現執行這個上下文的底層bean工廠的實際重新整理,如果有的話之前有BeanFactory存在,則關閉以前的bean工廠。併為上下文生命週期的下一個階段初始化一個新鮮的bean工廠。

3.createBeanFactory(AbstractRefreshableApplicationContext類中)

protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
複製程式碼

這個方法就是為當前上下文建立一個內部的bean工廠。每次呼叫refresh()方法是都會建立嘗試建立。預設實現是建立一個DefaultListableBeanFactory。並通過getInternalParentBeanFactory()獲取內部bean工廠來作為父級bean工廠。可以在子類中重寫,例如自定義DefaultListableBeanFactory的設定。

getInternalParentBeanFactory(AbstractApplicationContext類中)

protected BeanFactory getInternalParentBeanFactory() {
	return (getParent() instanceof ConfigurableApplicationContext) ?
	((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
}
複製程式碼

4.DefaultListableBeanFactory的建構函式

/**
 * 通過給定的父類建立一個新的DefaultListableBeanFactory容器
 * @param parentBeanFactory the parent BeanFactory
 */
public DefaultListableBeanFactory(BeanFactory parentBeanFactory) {
	super(parentBeanFactory);
}
複製程式碼

super(parentBeanFactory)呼叫的是AbstractAutowireCapableBeanFactory的建構函式

/**
 * 通過給定的父類構建新的AbstractAutowireCapableBeanFactory
 * @param parentBeanFactory parent bean factory, or {@code null} if none
 */
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
	this();
	//設定父工廠
	setParentBeanFactory(parentBeanFactory);
}
複製程式碼

this(),還是AbstractAutowireCapableBeanFactory的建構函式:

/**
 * 構建一個新的AbstractAutowireCapableBeanFactory.
 */
public AbstractAutowireCapableBeanFactory() {
	super();
	ignoreDependencyInterface(BeanNameAware.class);
	ignoreDependencyInterface(BeanFactoryAware.class);
	ignoreDependencyInterface(BeanClassLoaderAware.class);
}
複製程式碼

super() ; AbstractBeanFactory的建構函式

/**
 * 構建一個新的AbstractBeanFactory.
 */
public AbstractBeanFactory() {
}
複製程式碼

相關文章