spring IOC核心類DefaultListableBeanFactory的世界觀

IOC作爲Spring的核心功能其核心思想:

幫用戶管理對象,對象的創建不需要再由應用實現,而是交給了spring來管理。也就是對象的控制交給了第三方,也就是控制反轉的由來。

下面是Spring IOC核心工廠類的結構圖

從這個類結構圖我們可以看出DefaultListableBeanFactory實現了哪些功能

1、 是一個BeanDefinition註冊器

2、 最重要的它是一個bean工廠

3、 它是一個別名註冊器

4、 他是一個單例對象註冊器

BeanDefinition

通過解析Xml或者註解掃描獲取到的目標對象的屬性,spring根據這個對象通過反射機制來創建目標對象。我們可以看看BeanDefinition接口的一個重要方法

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	String getBeanClassName();
	void setBeanClassName(String beanClassName);

}

實現這個接口的肯定會提供類全限定名屬性,spring可以通過全限定名反射並實例化對象。

Alias

spring可以實現一個Bean對象有多個別名

<bean id="pos" class="com.yanlink.chapter4.alias.Pos">
        <property name="name" value="密碼鍵盤"/>
    </bean>
    <alias name="pos" alias="pax"/>
    <alias name="pos" alias="box"/>
Pos pos1 = (Pos) beanFactory.getBean("pax");
pos1 = (Pos) beanFactory.getBean("box");

兩次獲取的對象是同一個對象。

我們看看別名的實現類

public class SimpleAliasRegistry implements AliasRegistry {

	/** Map from alias to canonical name */
	private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);


	public void registerAlias(String name, String alias) {
	
		if (alias.equals(name)) {
            // 如果別名和本名一樣,則不需要添加別名機制
			this.aliasMap.remove(alias);
		}
		else {
			this.aliasMap.put(alias, name);
		}
	}

我們看到了註冊別名的時候其實就是往一個Map對象中添加別名映射的實際對象名。在使用的時候會再根據別名找到實際對象名。

BeanFactory

我們看看BeanFactory接口

public interface BeanFactory {
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	<T> T getBean(Class<T> requiredType) throws BeansException;
	Object getBean(String name, Object... args) throws BeansException;
}

這裏接口定義了通過各種方式獲取Bean的方法,這裏面的細節單獨需要一個章節來講解,這裏我們只要知道DefaultListableBeanFactory是一個工廠就可以了,這裏使用了工廠方法的設計模式,定義創建產品的方法,具體實現交給子類處理。

SingletonBeanRegistry

spring管理的主要還是Scope爲Singleton類型的Bean,這個接口就是針對創建的Singleton的bean對象的管理。

先來看看其接口

public interface SingletonBeanRegistry {

	// 註冊singleton對象
	void registerSingleton(String beanName, Object singletonObject);

	// 獲取singleton對象
	Object getSingleton(String beanName);
	
	boolean containsSingleton(String beanName);
	
	String[] getSingletonNames();
	int getSingletonCount();

}

從這個接口可以看出來,spring創建的bean如果是singleton是需要被管理起來的,我們來看看其實現

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/**
	 * Internal marker for a null singleton object:
	 * used as marker value for concurrent Maps (which don't support null values).
	 */
	protected static final Object NULL_OBJECT = new Object();


	/** Cache of singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

	/** Cache of singleton factories: bean name --> ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

	/** Cache of early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

	/** Set of registered singletons, containing the bean names in registration order */
	private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);



	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		
			addSingleton(beanName, singletonObject);
	}

	
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
            // 向singletonObjects中添加對象,如果添加的是null,則向singletonObjects中添加NULL_OBJECT
			this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}


	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

	
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 從singletonObjects獲取對象
		Object singletonObject = this.singletonObjects.get(beanName);
		
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

	
	protected void removeSingleton(String beanName) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}
}

從這個實現看出來spring創建的對象如果是singleton的,將會保存在一個ConcurrentHashMap中緩存起來,多次獲取同一名稱的對象spring返回的是同一個對象,所以Singleton在spring中表現爲單例形式的對象。

singleton相關的可不僅僅是緩存單例對象,它還解決了一個比較重要的問題循環依賴,這個我也分一個小章節來講解。

總結:

今天這篇文章簡單地介紹了Spring的核心類DefaultListableBeanFactory是什麼

1、它是一個BeanDefinition註冊器

2、它是一個Bean工廠

3、它是一個別名註冊器

4、它是一個Singleton註冊器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章