spring 技術內幕--IOC初始化過程深入之BeanDefinition的載入和解析1

protected final void refreshBeanFactory() throws BeanFactory{
if(hasbeanFactory){
destroyBeans();
closeBeanFactory();
}
try{
//創建IOC容器,使用DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory=createBeanFactory();
beanFactory.setSerializationId(getId());
custmoizaBeanFactory(beanFactory);
//啓動對BeanDefinition的載入
loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor){
this.beanFactory=beanFactory;}
}
}catch(IOException ex){
}

對IOC容器來說,載入過程相當於把定義的BeanDefinition在IOC容器中轉化成一個Spring內部表示的數據結構的過程。IOC容器對Bean的管理和依賴注入功能的實現,是通過對其持有的BeanDefinition進行各種相關的操作來完成的。這些BeanDefinition數據在IOC容器中通過一個HashMap來保持和維護。


AbstractRefreshableApplicationContext的refreshBeanFactory方法:

public void refresh() throws BeansException,IllegalStateException{
  Synchronised (this.startupShutdownMonitor){
prepareRefresh();
//在子類啓動refreshBeanFactory()的地方
ConfigurableListableBeanFactory beanFactory=obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try{
//設置BeanFactory的後置處理
postProcessBeanFactory(beanFactory);
//調用BeanFactory的後處理器,這些後處理器是在Bean定義中向容器註冊的
invoceBeanFactoryPostPrecessors(beanFactory);
//註冊Bean的後處理器,在Bean的創建過程中調用
registerBeanPostProcessors(beanFactory);
//對上下文的消息源進行初始化
initMessageSource();
//初始化上下文中的事件機制
initApplicationEventMulticaster();
//初始化其他的特殊Bean
onRefresh();
//檢查監聽Bean並且將Bean向這些容器中註冊
registerListeners();
//實例化所有的non-lazy-init事件
finishBeanFactoryInitialization(beanFactory);
//發佈容器事件,結束Refresh過程
finishRefresh();
}catch(BeanException ex){
//爲防止Bean資源佔用,在異常處理中,銷燬已經生成的事件Bean
destroyBeans();
//重置active 標誌
cancleRefresh(ex);
throw ex;
 }
}
}


AbstractXmlApplicationContext繼承AbstractRefreshableConfigApplicationContext,實現了loadBeanDefinitions方法.

protected void loadbeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException{
//創建XMLBeanDefinitionReader,並回調設置的BeanFactory中去。
DefaultListableBeanFactory beanDefinitionReader=new XmlBeanDefinitionReader(beanFactory);
//設置XmlBeanDefinitionReader,爲XMLBeanDefinitionReader匹配ResourceLoader,因爲DefaultResourceLoader是父類,所有this可以直接使用
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//啓動Bean定義信息載入的過程
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
XmlBeanDefinitionReader載入BeanDefinition

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException,IOException{
Resource[] configResources=getConfigResources();
if(configResources!=null){
reader.loadBeanDefinitions(configResources);
}
//以String的形式獲得配置文件的位置
String[] configLocations=getConfigLocations();
if(configLocations!=null){
reader.loadBeanDefinitions(configLocations);
}
}
protected Resource[] getConfigResources(){
return null;
}


通過調用IOC容器--(DefaultListableBeanFactory)的refresh來啓動BeanDefinition的載入。

AbstractBeanDefinitionReader載入BeanDefinition


//BeanDefinition的載入實現
調用的入口
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionstoreException{
return loadBeanDefinitions(new EncodeResource(resource));
}
//載入xml形式的BeanDefinition的地方
public int loadBeanDefinitions(EncodedResource er)throws BeanDefinitionStoreException{
Assert.notNull(er,"must not null");
if(logger.isInfoEnabled()){
logger,info(er.getResource());}
Set<EncodedResource> currentResources=this,resourceCurrentlyBeingLoaded.set(surrentResources);
}
//得到xml文件,並得到IO的inputtSource準備進行讀取
try{
InputStream is=er.getResource().getInputStream();
try{
InputSource ie=new InputSource(is);
if(er.getEncoding()!=null){
ie.setEncoding(encodeResource.getEncoding());}
return doLoadBeanDefinitions(ie,encodedResource.getresource());
}finally{
inputStream.close();}catch(IOException ex){}finally{
currentResources.remove(encodedResource);
if(currentResources.isEmpty()){
this.resourceCurrentlyBeingLoaded.set(null);
}}
}

具體讀取過程可以在doLoadBeanDefinitions方法中找到。Spring的BeanDefinition怎樣按照Spring的Bean語義要求進行解析和轉化爲容器的內部數據結構?---registerBeanDefinitions(doc,resource),具體由BeanDefinitionDocumentReader完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章