1. 程式人生 > >【Spring原始碼閱讀】 DefaultListableBeanFactory繼承結構講解分析

【Spring原始碼閱讀】 DefaultListableBeanFactory繼承結構講解分析

在基於ClassPathXmlApplicationContext建立BeanFactory時,我們從程式碼裡看到,建立的BeanFactory的型別是DefaultListableBeanFactory。
下面我們來分析下DefaultListableBeanFactory的繼承結構,以及基於這個結構下,每個父類介面的用途。
具體UML類圖實現如下:
image
下面開始從頂層實現類開始,依次向下逐層分析:

DefaultListableBeanFactory實現

實現介面向上可以追述至BeanFacotry,向下還有XmlBeanFactory實現,但從整個繼承結構來看,從DefaultListableBeanFactory開始可以作為獨立的IOC容器。
分析原始碼,在DefaultListableBeanFactory中定義了以下屬性

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    /** 儲存對映serializedId->DefaultListableBeanFactory的弱引用例項*/
	private static final Map<String, Reference<DefaultListableBeanFactory>
> serializableFactories = new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8); /** 當前工廠的可選序列化id */ private String serializationId; /** 是否允許同名的不同bean definition再次進行註冊 * 在註冊BeanDefinition發現存在同名BeanDefinition時,會檢查當前變數,如果為false會丟擲BeanDefinitionStoreException */ private
boolean allowBeanDefinitionOverriding = true; /** 是否允許eager類(相對於lazy)的載入,甚至延遲初始化的bean的載入, * 主要用於在呼叫doGetBeanNamesForType輔助尋找符合type要求的beanName */ private boolean allowEagerClassLoading = true; /**是一個策略介面,用來決定一個特定的bean definition 是否滿足做一個特定依賴的自動繫結的候選項 * 裡面定義了isAutowireCandidate方法用來判斷一個Bean是否參與自動裝配候選以及getSuggestedValue方法找出最佳候選Bean*/ private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); /** 定義了依賴型別和其對應的依賴注入物件鍵值對集合。 */ private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16); /** 定義了BeanName->BeanDefinition的對映關係 */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64); /** 定義了依賴型別->BeanNames的對映關係,包括單例和原型Bean * 具體儲存原理是先根據BeanName讀取beanDefinitionNames物件或frozenBeanDefinitionNames物件 * 再呼叫getMergedLocalBeanDefinition(beanName)方法拿到具體的BeanDefinition,比對BeanClass,滿足要求的都儲存到List統一返回*/ private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); /** 類似於allBeanNamesByType,不過只包含單例Bean */ private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); /** 根據註冊順序,儲存所有的beanDefinitionName,即beanName */ private final List<String> beanDefinitionNames = new ArrayList<String>(64); /** 配置是否凍結 在初始化完BeanFactory,開始初始化所有單例非懶載入Bean時呼叫finishBeanFactoryInitialization方法進行凍結*/ private boolean configurationFrozen = false; /** 在設定上一布林變數同時快取當前時刻的所有beanDefinitionNames到當前屬性 */ private String[] frozenBeanDefinitionNames; }

在DefaultListableBeanFactory內部,實現了ListableBeanFactory、ConfigurableListableBeanFactory、BeanDefinitionRegistry的相關介面,同時還實現瞭解析依賴,查到最佳的依賴注入BeanName等。
具體實現的方法可參照下圖:
image

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory定義bean definition的解析,修改等方法功能,還定義了初始化非懶載入單例Bean的核心方法preInstantiateSingletons.
具體介面定義如下:

public interface ConfigurableListableBeanFactory
		extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

	/**
	 * 忽略指定型別的自動裝配
	 * @param type 要忽略的依賴型別
	 */
	void ignoreDependencyType(Class<?> type);

	/**
	 * 在自動裝配時忽略該介面實現類中和setter方法入參相同的型別
	 * 在進行依賴注入時,會獲取待注入屬性的set方法,如果set方法的入參實現了本介面,會忽略該屬性的依賴注入
	 * 具體參考https://www.jianshu.com/p/3c7e0608ff1f
	 * @param ifc 要進行據略的介面
	 */
	void ignoreDependencyInterface(Class<?> ifc);

	/**
	 * 建議一個依賴型別->自動裝配Bean的對映關係
	 * @param dependencyType 依賴型別
	 * @param autowiredValue 對應的裝配例項,也可以是ObjectFactory的實現,會呼叫其中的getObject方法完成攔截在.
	 */
	void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);

	/**
	 * 判斷特定的bean是否可以作為一個自動裝配的候選Bean
	 * @param beanName 待檢查的BeanName
	 * @param descriptor 待解析的依賴引數的描述器
	 * @return 返回是否可以作為候選Bean
	 * @throws NoSuchBeanDefinitionException 如果沒有BeanName對應的BeanDefinition
	 */
	boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
			throws NoSuchBeanDefinitionException;

	/**
	 * 根據BeanName獲取具體的BeanDefinition
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 凍結配置
	 */
	void freezeConfiguration();

	/**
	 * 判斷相關配置是否已凍結
	 */
	boolean isConfigurationFrozen();

	/**
	 * 初始化所有非懶載入的單例Bean,相應的通過呼叫destroySingletons方法銷燬本方法註冊的單例
	 */
	void preInstantiateSingletons() throws BeansException;

}

ListableBeanFactory

繼承自BeanFactory介面,定義了迭代列舉容器Bean例項的相關方法,具體定義如下:

public interface ListableBeanFactory extends BeanFactory {

	/**
	 * 容器是否定義了指定beanName的
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * 獲取BeanDefinition數量
	 */
	int getBeanDefinitionCount();

	/**
	 * 獲取所有的BeanDefinition的BeanName
	 */
	String[] getBeanDefinitionNames();

	/**
	 * 獲取指定型別的所有BeanNames,預設包含非單例(原型Bean),允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
	 */
	String[] getBeanNamesForType(Class<?> type);

	/**
	 * 獲取指定型別的所有BeanNames
	 * @param type 要獲取BeanName的型別
	 * @param includeNonSingletons 是否包含包含非單例(原型Bean)
	 * @param allowEagerInit 允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
	 */
	String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

	/**
	 * 獲取指定型別的的beanName->bean例項對映,預設包含非單例(原型Bean),允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
	 */
	<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

	/**
	 * 獲取指定型別的的beanName->bean例項對映
	 * @param type 要獲取BeanName的型別
	 * @param includeNonSingletons 是否包含包含非單例(原型Bean)
	 * @param allowEagerInit 允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
	 */
	<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException;

	/**
	 * 獲取帶有指定註解型別的beanName->bean例項對映
	 */
	Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
			throws BeansException;

	/**
	 * 根據註解型別和beanName獲取相關的Bean註解例項
	 */
	<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);

}

AbstractAutowireCapableBeanFactory

在本類中定義了Spring容器的幾乎最核心的實現邏輯,包括例項化bean和依賴注入的具體實現等。
在本類,基本的屬性定義如下所示:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

	/** 例項化Bean的策略,預設是CglibSubclassingInstantiationStrategy,
	 * 對於實現了lookup-method或replace-method,會通過當前策略生成的CGLIB代理類增強呼叫相應的方法*/
	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

	/** 預設的方法引數名字解析策略 */
	private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

	/** 是否允許出現迴圈引用,如果為false,在例項化Bean後不會放入單例工廠中以提前暴露給其他Bean依賴注入 */
	private boolean allowCircularReferences = true;

	/**
	 * 是否在迴圈引用的情況下注入原始bean例項,即使注入的bean最終被包裝。
	 */
	private boolean allowRawInjectionDespiteWrapping = false;

	/**
	 * 儲存在依賴注入時要忽略的類
	 */
	private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();

	/**
	 * 儲存在自動裝配時,要忽略的在setter方法中實現本介面的入參
	 */
	private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();

	/** 快取FactoryBean name 到具體的FactoryBean例項(具體表現為對映BeanWrapper)*/
	private final Map<String, BeanWrapper> factoryBeanInstanceCache =
			new ConcurrentHashMap<String, BeanWrapper>(16);

	/** 快取根據ignoredDependencyTypes,ignoredDependencyInterfaces條件過濾的特定Bean類的屬性描述器*/
	private final Map<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
			new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(64);
}

AbstractAutowireCapableBeanFactory實現的方法相當多而複雜,總結來說,AbstractAutowireCapableBeanFactory實現了Spring容器例項化、依賴注入Bean相關屬性、初始化Bean等相關方法,具體定義的方法可參照下圖:
image

AutowireCapableBeanFactory

定義提供了BeanFacotry實現了依賴注入的功能,定義了依賴注入型別的相關列舉,內部包含以下常量屬性:

public interface AutowireCapableBeanFactory extends BeanFactory {

    /**
     * 不使用自動裝配,不影響通過xml配置或註解等方式的顯式依賴注入配置
     */
    int AUTOWIRE_NO = 0;

    /**
     * 在初始化容器內Bean的時候,檢索出Bean內可以進行依賴注入的屬性,然後根據名字檢索容器內的Bean進行注入
     */
    int AUTOWIRE_BY_NAME = 1;

    /**
     * 在初始化容器內Bean的時候,檢索出Bean內可以進行依賴注入的屬性,然後根據型別檢索容器內的Bean進行注入
     */
    int AUTOWIRE_BY_TYPE = 2;

    /**
     * 檢索最符合的構造方法,對建構函式內的入參進行依賴注入,再傳入建構函式
     */
    int AUTOWIRE_CONSTRUCTOR = 3;

    /**
     * 自動探測,如果Bean內有無參建構函式,則用AUTOWIRE_BY_TYPE,否則用AUTOWIRE_CONSTRUCTOR
     */
    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

}

AutowireCapableBeanFactory介面定義的方法主要涵蓋建立、初始化Bean並在初始化前後呼叫相應的後置處理器,解析依賴,完成依賴注入等功能。
具體內部方法參照下圖:
image

AbstractBeanFactory

BeanFactory的抽象實現,繼承自FactoryBeanRegistrySupport。提供了單例物件管理、父子容器管理,BeanDefinition管理和FactoryBean註冊管理等相關功能,AbstractBeanFactory具體定義的屬性如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

	/** 父容器,為BeanFactory提供繼承能力 */
	private BeanFactory parentBeanFactory;

	/** 必要時用於解析載入bean類,當tempClassLoader=null時使用  */
	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

	/**必要時用於臨時解析載入bean類,在預載入非攔截在單例Bean的凍結配置前使用*/
	private ClassLoader tempClassLoader;

	/** 是否快取bean元資料,或者每次訪問重新獲取,如果為true,每次呼叫getMergedBeanDefinition後必要時會快取到mergedBeanDefinitions */
	private boolean cacheBeanMetadata = true;

	/** 表示式解析策略,用於解析beanDefinition中的表示式如SpEL等 */
	private BeanExpressionResolver beanExpressionResolver;

	/** 在屬性編輯(讀寫)過程通過ConversionService完成屬性的型別轉換,預設全部屬性為String型別,最終轉換成各種物件型別*/
	private ConversionService conversionService;

	/** 自定義屬性編輯器註冊商,持有屬性編輯器的註冊器,通過呼叫registerCustomEditors方法完成批量註冊拓展的自定義屬性編輯器的邏輯*/
	private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
			new LinkedHashSet<PropertyEditorRegistrar>(4);

	/** 自定義TypeConverter,重寫預設的PropertyEditor機制,定義了屬性轉換的機制 */
	private TypeConverter typeConverter;

	/** 自定義屬性編輯器,用於編輯容器內的Bean屬性
     * 呼叫鏈是通過createBean->doCreateBean->populateBean->applyPropertyValues->TypeConverter.convertIfNecessary進行 */
	private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
			new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);

	/** 用於諸如註解屬性的字串解析器 */
	private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();

	/** 儲存例項化和初始化Bean過程用到的Bean後置處理器BeanPostProcessors to apply in createBean */
	private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

	/** 標誌容器內是否註冊了InstantiationAwareBeanPostProcessors */
	private boolean hasInstantiationAwareBeanPostProcessors;

	/** 標誌容器內是否註冊了destructionAwareBeanPostProcessors */
	private boolean hasDestructionAwareBeanPostProcessors;

	/** 建立字串型別->Scope的對映關係
     * 具體用例如registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope())
     * */
	private final Map<String, Scope> scopes = new HashMap<String, Scope>(8);

	/** 容器內執行的安全上下文的提供者 */
	private SecurityContextProvider securityContextProvider;

	/** 建立BeanName->RootBeanDefinition的對映關係 */
	private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
			new ConcurrentHashMap<String, RootBeanDefinition>(64);

	/** 記錄特定BeanName的bean已經建立過至少一次 */
	private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);

	/** 記錄當前處於建立狀態的Bean */
	private final ThreadLocal<Object> prototypesCurrentlyInCreation =
			new NamedThreadLocal<Object>("Prototype beans currently in creation");
}

ConfigurableBeanFactory

提供配置管理Bean的能力,定義了Bean作用域的基礎型別,包括singleton和prototype,繼承自HierarchicalBeanFactory, SingletonBeanRegistry,具有父子容器繼承和單例Bean註冊等相關能力

FactoryBeanRegistrySupport

提供了FacotryBean型別Bean的註冊管理,定義了一個ConcurrentHashMap建立了beanName->FactoryBean的快取。
具體實現如下:

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

	/** 建立BeanName->factoryBeanObject的快取對映 */
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);


	/**
	 * 呼叫factoryBean.getObjectType()獲取實現了FactoryBean介面的相應例項方法.
	 */
	protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean);

	/**
	 * 嘗試從快取中獲取FactoryBeanObject
	 */
	protected Object getCachedObjectForFactoryBean(String beanName);

	/**
	 * 獲取當前factory的實際例項物件,會先嚐試從快取獲取,再通過呼叫doGetObjectFromFactoryBean獲取
	 */
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess);

	/**
	 * 真正獲取物件的方法,通過呼叫factory.getObject()
	 */
	private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException;

	/**
	 * 預設實現是直接返回入參Object,子類可以自行拓展,如新增Bean後置處理器邏輯等
	 */
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
		return object;
	}

	/**
	 * 判斷beanInstance是否是FactoryBean例項,如果是則進行型別轉換返回.
	 */
	protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException;

	/**
	 * 先呼叫父類removeSingleton,並嘗試從當前factoryBean快取中移除特定Bean
	 */
	@Override
	protected void removeSingleton(String beanName);

	/**
	 * 呼叫jdk原始碼AccessController.getContext()獲取安全上線文訪問器
	 */
	protected AccessControlContext getAccessControlContext();

}

DefaultSingletonBeanRegistry

SingletonBeanRegistry介面的預設實現,繼承自SimpleAliasRegistry類,具有別名、單例Bean註冊管理的相關能力。
具體定義如下:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/**
	 * 標記一個null值,多用於在Concurrent Map中作值存在
	 */
	protected static final Object NULL_OBJECT = new Object();


	/** 子類可訪問的日誌管理器 */
	protected final Log logger = LogFactory.getLog(getClass());

	/**  下面三個屬性定義了單例初始化過程的"三級快取"
	 * 在Bean例項化後儲存在三級快取singletonFactories中,
	 * 當需要時呼叫ObjectFactory.getObject延遲獲取Bean例項,並放入二級快取earlySingletonObjects
	 * 當Bean初始化結束後,從二級快取earlySingletonObjects移除,放入一級快取singletonObjects中
	 * 具體獲取順序,singletonObjects->earlySingletonObjects->singletonFactories
	 **/

	/** 一級快取 對映beanName->單例物件*/
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

	/** 二級快取 對映beanName->ObjectFactory*/
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

	/** 三級快取 對映beanName->早期單例物件,即未完整初始化的單例物件*/
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

	/** 根據單例Bean的注入順序,儲存單例BeanName */
	private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);

	/** 儲存處於建立狀態的BeanName */
	private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);

	/** 儲存需要過濾建立狀態檢測的BeanName */
	private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);

	/** 記錄在嘗試獲取/建立單例過程中遇到的多層捕捉到的異常,最後統一丟擲 */
	private Set<Exception> suppressedExceptions;

	/** 標誌當前容器是否正在銷燬容器內的所有單例物件 */
	private boolean singletonsCurrentlyInDestruction = false;

	/** 對映儲存BeanName->實現了Disposable介面bean例項 */
	private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();

	/** 對映儲存外部BeanName和巢狀Bean集合的對映關係 */
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

	/** 對映儲存被依賴的BeanName和依賴BeanName集合的對映關係 */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

	/** 儲存關係和dependentBeanMap相仿對映儲存依賴的BeanName和被依賴BeanName集合的對映關係 */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
}

具體實現的方法如下所示,主要圍繞上面定義的屬性進行讀寫管理:
image

SimpleAliasRegistry

一個簡單的別名註冊中心,實現了AliasRegistry介面。
AliasRegistry介面內部定義了4個方法,包括註冊、移除、判斷特定BeanName是否為別名,獲取特定name的所有可能別名(遞迴遍歷過程的所有別名)等。內部定義了唯一的屬性

// 儲存別名->"真名"的對映關係,這裡真名可能為另一個真名的別名
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);

SingletonBeanRegistry

定義了單例Bean註冊管理的相關方法,具體定義如下:

public interface SingletonBeanRegistry {

	/**
	 * 註冊指定beanName的單例物件
	 */
	void registerSingleton(String beanName, Object singletonObject);

	/**
	 * 獲取指定beanName的單例物件
	 */
	Object getSingleton(String beanName);

	/**
	 * 判斷是否包含指定beanName的單例物件
	 */
	boolean containsSingleton(String beanName);

	/**
	 * 獲取所有註冊的單例物件beanName
	 */
	String[] getSingletonNames();

	/**
	 * 獲取註冊的單例個數
	 */
	int getSingletonCount();

}