Spring IOC容器分析(2) -- BeanDefinition


上文對Spring IOC容器的核心BeanFactory接口分析發現:在默認Bean工廠DefaultListableBeanFactory中對象不是以Object形成存儲,而是以BeanDefinition類封裝后存放在並發容器ConcurrentHashMap中的,如下所示:

/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

下面來對BeanDefinition接口進行分析。

BeanDefinition

首先來看一幅圖,BeanDefinition接口的UML類圖關系:

BeanDefinition接口UML類圖

可以看到BeanDefinition接口繼承了兩個接口,這兩個接口均為祖宗級接口。AtributeAccessor位於spring-core包下,定義了屬性的操作方式;BeanMetadataElement位於spring-beans包下,定義了獲取元數據元素的配置源。其源碼如下:

package org.springframework.beans.factory.config;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

	int ROLE_APPLICATION = 0;

	int ROLE_SUPPORT = 1;

	int ROLE_INFRASTRUCTURE = 2;

	void setParentName(String parentName);

	String getParentName();

	void setBeanClassName(String beanClassName);

	String getBeanClassName();

	void setScope(String scope);

	String getScope();

	void setLazyInit(boolean lazyInit);

	boolean isLazyInit();

	void setDependsOn(String... dependsOn);

	String[] getDependsOn();

	void setAutowireCandidate(boolean autowireCandidate);

	boolean isAutowireCandidate();

	void setPrimary(boolean primary);

	boolean isPrimary();

	void setFactoryBeanName(String factoryBeanName);

	String getFactoryBeanName();

	void setFactoryMethodName(String factoryMethodName);

	String getFactoryMethodName();

	ConstructorArgumentValues getConstructorArgumentValues();

	MutablePropertyValues getPropertyValues();

	boolean isSingleton();

	boolean isPrototype();

	boolean isAbstract();

	int getRole();

	String getDescription();

	String getResourceDescription();

	BeanDefinition getOriginatingBeanDefinition();
}

考慮到篇幅限制,將源碼中注釋部分去掉。從接口名字即可大致知道該接口實現了哪些功能。

  • setParentName(String parentName)getParentName()可以設置獲取該bean的父類bean
  • setBeanClassName(String beanClassName)getBeanClassName()可以設置獲取該bean的別名
  • setLazyInit(boolean lazyInit)讀取配置文件,設置該bean是否延遲加載;isLazyInit()判斷該bean是否延遲加載
  • setDependsOn(String... dependsOn)設置bean的依賴項,String[] getDependsOn()獲取依賴項
  • setFactoryBeanName(String factoryBeanName)設置該bean的加載工廠,String getFactoryBeanName()獲取bean的加載工廠

通過對接口方法分析,可以發現BeanDefinition定義了bean實例的基礎方法,基本上通過BeanDefinition接口就可以描述一個bean對象。也即表面在beanDefinitionMap中BeanDefinition接口可以替代Object對象存儲bean實例。

既然兩者都可以存儲bean對象,為啥是用BeanDefinition而不是Object呢?其實細究可以發現:在Spring中,我們可以自定義是否延遲加載bean對象,合適初始化對象,要想實現加載、初始化時機控制,簡單的通過Object對象是無法實現的,必須在此基礎上有一個封裝,這樣才可以實現更多的自定義性質。所以在beanDefinitionMap中bean對象是以BeanDefinition形式存儲。

本文介紹了Spring IOC容器中一個非常重要的接口BeanDefinition,以及解釋了為啥beanDefinitionMap中存儲的是BeanDefinition。下文將進入Spring IOC類加載的具體過程,重點看看默認的bean工廠DefaultListableBeanFactory


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM