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完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章