2.2.3 资源定位、解释2.2.3.1 资源定位加载与容器的关系     loadBeanDefinitions方法主要是加载BeanDefinition,而BeanDefinition的定义是来自于一组资源的,要加载BeanDefinition,Spring首先要加载、解释这些资源,资源的定位、加载由ResourceLoader与ResourcePatternResolver负责。在loadBeanDefinitions方法分析之前,我们先来了解下容器与ResourceLoader之间的联系。ResourceLoader是资源加载器接口;ResourcePatternResolver是资源模式解释器接口,它把一个定位模式(例如,ant样式模式)转变为Resource对象; ResourcePatternResolver扩展自ResourceLoader,因此也可以说一个ResourcePatternResolver的实现在同时具备资源模式解释的同时,也具备资源的加载功能呢(关于继承结构参见图1)。那么容器与ResourceLoader、ResourcePatternResolver在结构上有什么联呢?    
    首先,看一下接口ApplicationContext与ResourcePatternResolver的关系:
 public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory,MessageSource,ApplicationEventPublisher,
public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory,MessageSource,ApplicationEventPublisher,

 ResourcePatternResolver
ResourcePatternResolver {
{
 ……
……
 }
}

    从代码中可以看到,任何的上下文容器都应该支持资源模式的解释的功能,即能够解释ant-style的资源定义。我们看到了应用上下文接口声明支持资源模式的解释功能,那么具体的应用上下文容器是如何实现资源的定位以及资源模式的解释的呢?
    接下来,我们看一下抽象类AbstractApplicationContext与ResourceLoader、ResourcePatternResolver的关系:
 public abstract class AbstractApplicationContext
public abstract class AbstractApplicationContext 
 extends DefaultResourceLoader
extends DefaultResourceLoader

 implements ConfigurableApplicationContext, DisposableBean
implements ConfigurableApplicationContext, DisposableBean {
{

 //意味着FileSystemXmlApplicationContext在创建时,就已经拥有resolver实例,见灰色部分
//意味着FileSystemXmlApplicationContext在创建时,就已经拥有resolver实例,见灰色部分
 pivate ResourcePatternResolver resourcePatternResolver;
pivate ResourcePatternResolver resourcePatternResolver;


 public AbstractApplicationContext(ApplicationContext parent)
public AbstractApplicationContext(ApplicationContext parent)  {
{
 this.parent = parent;
        this.parent = parent;
 this.resourcePatternResolver = getResourcePatternResolver();
        this.resourcePatternResolver = getResourcePatternResolver();
 }
}


 protected ResourcePatternResolver getResourcePatternResolver()
protected ResourcePatternResolver getResourcePatternResolver()  {
{
 return new PathMatchingResourcePatternResolver(this);
        return new PathMatchingResourcePatternResolver(this);
 }
}

 //解释返回资源的功能不是其自身实现,而是通过调用resourcePatternResolver提供
//解释返回资源的功能不是其自身实现,而是通过调用resourcePatternResolver提供

 public Resource[] getResources(String locationPattern) throws IOException
public Resource[] getResources(String locationPattern) throws IOException  {
{
 return this.resourcePatternResolver.getResources(locationPattern);
        return this.resourcePatternResolver.getResources(locationPattern);
 }
    }

    由代码可以看出,资源模式解释器在容器创建时就已经创建,资源模式解释器由PathMatchingResourcePatternResolver担当。AbstractApplicationContext继承于DefaultResourceLoader(ResourceLoader的默认实现),因此AbstractApplicationContext也具备了资源加载的功能。同时ApplicationContext扩展了ResourcePatternResolver接口,所以ApplicationContext的实现类对外表现的Loader应该为ResourcePatternResolver。通俗来讲,就是说容器具备资源模式解释的功能,并能对一资源位置进行加载,参看图-1理解一下。
     知道了容器与ResourceLoader之间的联系,我们继续loadBeanDefinitions方法的分析。
2.2.3.2 loadBeanDefinitions方法分析
    我们在上一节refreshBeanFactory方法中知道,内部工厂初始化的最后一步是加载BeanDefinition。loadBeanDefinitions方法是由抽象AbstractXmlApplicationContext
实现的。它在这里主要做了以下功能:把加载Definition(从字面上就能看出,其是对xml中的bean的定义)的工作委托给XmlBeanDefinitionReader,XmlBeanDefinitionReader来进行资源的定位,资源的加载。
    
 AbstractXmlApplicationContext.loadBeanDefinitions()代码:
AbstractXmlApplicationContext.loadBeanDefinitions()代码:

 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException  {
{

 /** *//** *//** *//**这里的beanFactory是以BeanDefinitionRegistry的角色作为参数传入到XmlBeanDefinitionReader中的,由于DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此,beanFactory具备了BeanDefination的注册功能*/
/** *//** *//** *//**这里的beanFactory是以BeanDefinitionRegistry的角色作为参数传入到XmlBeanDefinitionReader中的,由于DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此,beanFactory具备了BeanDefination的注册功能*/
 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
 //为reader设置resourceloader,参看类图DefaultListableBeanFactory继承自DefaultResourceLoader
//为reader设置resourceloader,参看类图DefaultListableBeanFactory继承自DefaultResourceLoader
 beanDefinitionReader.setResourceLoader(this);    beanDefinitionReader.setEntityResolver(newResourceEntityResolver(this));
beanDefinitionReader.setResourceLoader(this);    beanDefinitionReader.setEntityResolver(newResourceEntityResolver(this));

 initBeanDefinitionReader(beanDefinitionReader);
    initBeanDefinitionReader(beanDefinitionReader);
 loadBeanDefinitions(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
 }
}


 /** *//** *//** *//**从下段代码可以看出,虽然容器具备资源的加载的功能,但是spring并没有在容器类中直接处理资源加载的工作,而是把这项工作委托给XmlBeanDefinitionReader。XmlBeanDefinitionReader是XML bean definitions的reader,它把实际的XML文档读取任务交给了DefaultBeanDefinitionDocumentReader来完成.*/
/** *//** *//** *//**从下段代码可以看出,虽然容器具备资源的加载的功能,但是spring并没有在容器类中直接处理资源加载的工作,而是把这项工作委托给XmlBeanDefinitionReader。XmlBeanDefinitionReader是XML bean definitions的reader,它把实际的XML文档读取任务交给了DefaultBeanDefinitionDocumentReader来完成.*/

 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException  {
{
 
       
 Resource[] configResources = getConfigResources();
        Resource[] configResources = getConfigResources();

 if (configResources != null)
        if (configResources != null)  {
{
 reader.loadBeanDefinitions(configResources);
            reader.loadBeanDefinitions(configResources);
 }
        }
 String[] configLocations = getConfigLocations();
        String[] configLocations = getConfigLocations();

 if (configLocations != null)
        if (configLocations != null)  {
{
 //由XmlBeanDefinitionReader来加载beanDefinition
              //由XmlBeanDefinitionReader来加载beanDefinition
 reader.loadBeanDefinitions(configLocations);
            reader.loadBeanDefinitions(configLocations);
 }
        }
 }
}


 /** *//** *//** *//***以下方法来自于AbstractBeanDefinitionReader,该类是XmlBeanDefinitionReader的超类***/
/** *//** *//** *//***以下方法来自于AbstractBeanDefinitionReader,该类是XmlBeanDefinitionReader的超类***/
 //由一组指定的资源位置,加载资源
//由一组指定的资源位置,加载资源

 public int loadBeanDefinitions(String[] locations) throws BeanDefinitionStoreException
public int loadBeanDefinitions(String[] locations) throws BeanDefinitionStoreException  {
{
 Assert.notNull(locations, "Location array must not be null");
        Assert.notNull(locations, "Location array must not be null");
 int counter = 0;
        int counter = 0;

 for (int i = 0; i < locations.length; i++)
        for (int i = 0; i < locations.length; i++)  {
{
 counter += loadBeanDefinitions(locations[i]);
            counter += loadBeanDefinitions(locations[i]);
 }
        }
 return counter;
        return counter;
 }
}
 //加载特定资源位置下的资源
//加载特定资源位置下的资源

 public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException  {
{
 return loadBeanDefinitions(location, null);
        return loadBeanDefinitions(location, null);
 }
}


 public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException
public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException  {
{
 ResourceLoader resourceLoader = getResourceLoader();
        ResourceLoader resourceLoader = getResourceLoader();
 ……
    ……

 if (resourceLoader instanceof ResourcePatternResolver)
        if (resourceLoader instanceof ResourcePatternResolver)  {
{

 try
            try  { //这里进行资源位置解释成资源(Resource)关于资源定位解释成资源,请参看后面的“资源定位分析”
{ //这里进行资源位置解释成资源(Resource)关于资源定位解释成资源,请参看后面的“资源定位分析”
 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

 int loadCount = loadBeanDefinitions(resources);
                int loadCount = loadBeanDefinitions(resources);

 if (actualResources != null)
                if (actualResources != null)  {
{

 for (int i = 0; i < resources.length; i++)
                    for (int i = 0; i < resources.length; i++)  {
{
 actualResources.add(resources[i]);
                        actualResources.add(resources[i]);
 }
                    }
 }
                }
 return loadCount;
                return loadCount;
 }
            }

 catch (IOException ex)
            catch (IOException ex)  {
{
 …….
                …….

 }else
        }else {
{
 …….
              ……. 
 }
         }
 }
}


 /** *//** *//** *//**以下方法来自XmlBeanDefinitionReader**/
/** *//** *//** *//**以下方法来自XmlBeanDefinitionReader**/
 //加载指定的resource,由上面的方法调用,主要对resource进行编码处理
//加载指定的resource,由上面的方法调用,主要对resource进行编码处理

 public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException  {
{
 return loadBeanDefinitions(new EncodedResource(resource));
        return loadBeanDefinitions(new EncodedResource(resource));
 }
}

 //加载经过编码后的Resource
//加载经过编码后的Resource

 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException  {
{
 ……
         ……
 //谁能说说这里使用ThreadLocal的好处是什么呢?
        //谁能说说这里使用ThreadLocal的好处是什么呢?
 Set currentResources = (Set) this.resourcesCurrentlyBeingLoaded.get();
        Set currentResources = (Set) this.resourcesCurrentlyBeingLoaded.get();

 if (currentResources == null)
        if (currentResources == null)  {
{
 currentResources = new HashSet(4);
            currentResources = new HashSet(4);
 this.resourcesCurrentlyBeingLoaded.set(currentResources);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
 }
        }

 if (!currentResources.add(encodedResource))
        if (!currentResources.add(encodedResource))  {
{
 ……
            ……
 }
        }

 try
        try  {
{
 InputStream inputStream = encodedResource.getResource().getInputStream();
            InputStream inputStream = encodedResource.getResource().getInputStream();

 try
            try  {
{
 InputSource inputSource = new InputSource(inputStream);
                InputSource inputSource = new InputSource(inputStream);

 if (encodedResource.getEncoding() != null)
                if (encodedResource.getEncoding() != null)  {
{
 inputSource.setEncoding(encodedResource.getEncoding());
                inputSource.setEncoding(encodedResource.getEncoding());
 }
                }
 //真正的加载工作在这里进行
                         //真正的加载工作在这里进行
 return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
 }
            }

 finally
            finally  {
{
 inputStream.close();
                inputStream.close();
 }
            }
 }
        }

 catch (IOException ex)
        catch (IOException ex)  {
{
 ……
            ……
 }
        }

 finally
        finally  {
{
 ……
            ……
 }
        }
 }
    }



 
2.2.3.3资源定位(resource location)分析
     资源定位的定义主要包含两类:单一的资源路径和带有占位符的复合资源路径,其中后一种Spring支持ant-style样式的定义,例如classpath*:/WEF-INF/*-con.xml。无论是哪种类型的资源定位,最后都需要被解释成Resource(资源)。其中第一种由DefaultResourceLoader负责,其实现是通过资源定位尝试构造URL,然后把URL封装成URLResource;后一种由PathMatchingResourcePatternResolver负责,其主要处理ant-style样式的资源定位,其处理的资源主要包括两类:文件系统文件、jar文件(jar、zip、wsjar等),其返回的资源可能包括URLResource、FileSystemResource。
    类PathMatchingResourcePatternResolver资源定位:

 /** *//** 单独定位,即location类似于“c:/zhangxl/doc/12.txt”样式 **/
/** *//** 单独定位,即location类似于“c:/zhangxl/doc/12.txt”样式 **/

 public Resource getResource(String location)
public Resource getResource(String location)  {
{
 return getResourceLoader().getResource(location);
        return getResourceLoader().getResource(location);
 }
}


 /** *//** *//** *//** ant-style样式定位(包含单独定位),类似与classpath*:/WEF-INF/*-context.xml **/
/** *//** *//** *//** ant-style样式定位(包含单独定位),类似与classpath*:/WEF-INF/*-context.xml **/

 public Resource[] getResources(String locationPattern) throws IOException
public Resource[] getResources(String locationPattern) throws IOException  {
{
 Assert.notNull(locationPattern, "Location pattern must not be null");
        Assert.notNull(locationPattern, "Location pattern must not be null");
 //检查是否以类路径为前缀(classpath*:),例如classpath*:/WEF-INF/*-context.xml
//检查是否以类路径为前缀(classpath*:),例如classpath*:/WEF-INF/*-context.xml    

 if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX))
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX))  {
{
 // a class path resource (multiple resources for same name possible)
// a class path resource (multiple resources for same name possible)
 //定位模式是否采用了ant-style,即采用*或者?占位符的
//定位模式是否采用了ant-style,即采用*或者?占位符的
 if (getPathMatcher().isPattern(
    if (getPathMatcher().isPattern(

 locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length())))
locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
{
 // a class path resource pattern
// a class path resource pattern 
 // findPathMatchingResources处理的策略是先获取根路径,然后递归匹配各个子目录下的文件,其处理的文件类型主要有两大类:文件系统文件、jar文件(包括jar、zip、wsjar等)。其返回的Resource主要包括URLResource,FileSystemResource实例.
// findPathMatchingResources处理的策略是先获取根路径,然后递归匹配各个子目录下的文件,其处理的文件类型主要有两大类:文件系统文件、jar文件(包括jar、zip、wsjar等)。其返回的Resource主要包括URLResource,FileSystemResource实例.        
 return findPathMatchingResources(locationPattern);
            return findPathMatchingResources(locationPattern);
 }
    }

 else
else  {
{
 // all class path resources with the given name
                // all class path resources with the given name
 // findAllClassPathResources的处理策略主要是通过ClassLoader获得URL,然后构造URLResource
     // findAllClassPathResources的处理策略主要是通过ClassLoader获得URL,然后构造URLResource            
 return findAllClassPathResources(locationPattern
return findAllClassPathResources(locationPattern
 .substring(CLASSPATH_ALL_URL_PREFIX.length()));
.substring(CLASSPATH_ALL_URL_PREFIX.length()));
 }
            }
 }
        }

 else
        else  {
{
 // Only look for a pattern after a prefix here
            // Only look for a pattern after a prefix here
 // (to not get fooled by a pattern symbol in a strange prefix).
            // (to not get fooled by a pattern symbol in a strange prefix).
 int prefixEnd = locationPattern.indexOf(":") + 1;
            int prefixEnd = locationPattern.indexOf(":") + 1;
 if (getPathMatcher().isPattern(
            if (getPathMatcher().isPattern(

 locationPattern.substring(prefixEnd)))
locationPattern.substring(prefixEnd)))  {
{
 // a file pattern
                // a file pattern
 return findPathMatchingResources(locationPattern);
                return findPathMatchingResources(locationPattern);
 }
            }

 else
            else  {
{
 // a single resource with the given name
                // a single resource with the given name
 //由DefaultResourceLoader处理,返回UrlResource
                   //由DefaultResourceLoader处理,返回UrlResource

 return new Resource[]
                return new Resource[]  {getResourceLoader().getResource(locationPattern)};
{getResourceLoader().getResource(locationPattern)};
 }
}
 }
        }
 }
    }

DefaultResourceLoader资源定位:

 public Resource getResource(String location)
public Resource getResource(String location)  {
{
 Assert.notNull(location, "Location must not be null");
        Assert.notNull(location, "Location must not be null");

 if (location.startsWith(CLASSPATH_URL_PREFIX))
        if (location.startsWith(CLASSPATH_URL_PREFIX))  {
{
 return new ClassPathResource(
            return new ClassPathResource(
 location.substring(CLASSPATH_URL_PREFIX.length())
location.substring(CLASSPATH_URL_PREFIX.length())
 , getClassLoader());
, getClassLoader());
 }
        }

 else
        else  {
{

 try
            try  {
{
 // 其只是尝试把location转化为URL
                // 其只是尝试把location转化为URL
 URL url = new URL(location);
                URL url = new URL(location);
 return new UrlResource(url);
                return new UrlResource(url);
 }
            }

 catch (MalformedURLException ex)
            catch (MalformedURLException ex)  {
{
 // No URL -> resolve as resource path.
                // No URL -> resolve as resource path.
 return getResourceByPath(location);
                return getResourceByPath(location);
 }
            }
 }
        }
 }
    }

2.2.4 资源的解释以及BeanDefinition的注册
2.2.4.1 doLoadBeanDefinitions方法分析
    我们在2.2.3.2节中提到,doLoadBeanDefinitions方法真正进行了资源的加载、解释工作。下面我们看看doLoadBeanDefinitions的实现。

 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException  {
{

 try
        try  {
{
 //获取验证模式,如果未配置将采用detected mode
//获取验证模式,如果未配置将采用detected mode
 int validationMode = getValidationModeForResource(resource);            //Resource被加载为Document
            int validationMode = getValidationModeForResource(resource);            //Resource被加载为Document
 Document doc = this.documentLoader.loadDocument(
            Document doc = this.documentLoader.loadDocument(
 inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
                    inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
 //解释resource为BeanDefinition,并注册BeanDefinition
//解释resource为BeanDefinition,并注册BeanDefinition
 return registerBeanDefinitions(doc, resource);
            return registerBeanDefinitions(doc, resource);
 }
        }
 }
}


 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException  {
{
 
        

 /** *//** *//** *//**这里创建BeanDefinitionDocumentReader接口实例,该实例由DefaultBeanDefinitionDocumentReader担当,其主要依据“spring-beans”DTD和XSD来读取BeanDefinition*/
/** *//** *//** *//**这里创建BeanDefinitionDocumentReader接口实例,该实例由DefaultBeanDefinitionDocumentReader担当,其主要依据“spring-beans”DTD和XSD来读取BeanDefinition*/
 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
 int countBefore = getRegistry().getBeanDefinitionCount();
        int countBefore = getRegistry().getBeanDefinitionCount();
 documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
 return getRegistry().getBeanDefinitionCount() - countBefore;
        return getRegistry().getBeanDefinitionCount() - countBefore;
 }
    }

2.2.4.1.1 BeanDefinitionDocumentReader对加载的Document的处理以及Bean注册
    spring把解释xml,并发解释的数据转化为BeanDefinition的任务委派给BeanDefinitionDocumentReader,其解释的主要代码如下:

 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext)  {
{
 this.readerContext = readerContext;
        this.readerContext = readerContext;

 Element root = doc.getDocumentElement();
        Element root = doc.getDocumentElement();
 //由BeanDefinitionParserDelegate协助完成xml到BeanDefinition的解释工作
    //由BeanDefinitionParserDelegate协助完成xml到BeanDefinition的解释工作
 BeanDefinitionParserDelegate delegate =
        BeanDefinitionParserDelegate delegate = 
 createHelper(readerContext, root);
createHelper(readerContext, root);

 preProcessXml(root);//空函数实现
        preProcessXml(root);//空函数实现
 //把Element解释为BeanDefinition,并注册
        //把Element解释为BeanDefinition,并注册
 parseBeanDefinitions(root, delegate);
        parseBeanDefinitions(root, delegate);
 postProcessXml(root);//空函数
        postProcessXml(root);//空函数
 }
}


 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)  {
{
 //判断节点是否属于命名空间http://www.springframework.org/schema/beans
//判断节点是否属于命名空间http://www.springframework.org/schema/beans

 if (delegate.isDefaultNamespace(root.getNamespaceURI()))
        if (delegate.isDefaultNamespace(root.getNamespaceURI()))  {
{
 NodeList nl = root.getChildNodes();
            NodeList nl = root.getChildNodes();

 for (int i = 0; i < nl.getLength(); i++)
            for (int i = 0; i < nl.getLength(); i++)  {
{
 Node node = nl.item(i);
                Node node = nl.item(i);

 if (node instanceof Element)
                if (node instanceof Element)  {
{
 Element ele = (Element) node;
                    Element ele = (Element) node;
 String namespaceUri = ele.getNamespaceURI();
                    String namespaceUri = ele.getNamespaceURI();

 if (delegate.isDefaultNamespace(namespaceUri))
                    if (delegate.isDefaultNamespace(namespaceUri))  {
{
 //对xml document的解释工作在这里完成
                         //对xml document的解释工作在这里完成
 parseDefaultElement(ele, delegate);
                        parseDefaultElement(ele, delegate);
 
                         
 }
                    }

 else
                    else  {
{
 delegate.parseCustomElement(ele);
                        delegate.parseCustomElement(ele);
 }
                    }
 }
                }
 }
            }
 }
        }

 else
        else  {
{
 //解释定制元素,例如aop、context等。
            //解释定制元素,例如aop、context等。
 delegate.parseCustomElement(root);
            delegate.parseCustomElement(root);
 }
        }
 }
}


 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)  {
{
 //解释import标签
        //解释import标签

 if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT))
        if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT))  {
{
 importBeanDefinitionResource(ele);
            importBeanDefinitionResource(ele);
 }
        }

 else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT))
        else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT))  {
{
 processAliasRegistration(ele);
            processAliasRegistration(ele);
 }
        }
 //这里是真正的开始解释bean节点
        //这里是真正的开始解释bean节点

 else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT))
        else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT))  {
{
 processBeanDefinition(ele, delegate);
            processBeanDefinition(ele, delegate);
 }
        }
 }
}


 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)  {
{

 /** *//** *//** *//**把Element解释成GenericBeanDefinition(BeanDefinition的具体实现),并创建新的BeanDefinitionHolder,并把解释的definition、beanName、aliases封装进BeanDefinitionHolder*/
/** *//** *//** *//**把Element解释成GenericBeanDefinition(BeanDefinition的具体实现),并创建新的BeanDefinitionHolder,并把解释的definition、beanName、aliases封装进BeanDefinitionHolder*/
 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//实现参看后面的parseBeanDefinitionElement方法分析
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//实现参看后面的parseBeanDefinitionElement方法分析

 if (bdHolder != null)
        if (bdHolder != null)  {
{
 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);//对定制的一些配置进行装饰性解释,例如aop
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);//对定制的一些配置进行装饰性解释,例如aop

 try
            try  {
{
 //注册BeanDefinition
//注册BeanDefinition
 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,       getReaderContext().getRegistry());
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,       getReaderContext().getRegistry());
 }
            }

 catch (BeanDefinitionStoreException ex)
            catch (BeanDefinitionStoreException ex)  {
{
 ……
                ……
 }
            }
 // Send registration event.
            // Send registration event.
 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
 }
        }
 }
    }

    BeanDefinition的注册过程,主要是把解释出来的BeanDefinition、bean名称缓存到内部容器中的过程,并且维护BeanDefinition的一致性。BeanDefination注册的关键代码如下:

 /**//*解释的过程主要完成对id、name、parent、lazy-init、singleton等属性的解释,并把相关属性设置到BeanDefinition中。接下来我们看看BeanDefinition的注册,即BeanDefinitionReaderUtils.registerBeanDefinition的实现:*/
/**//*解释的过程主要完成对id、name、parent、lazy-init、singleton等属性的解释,并把相关属性设置到BeanDefinition中。接下来我们看看BeanDefinition的注册,即BeanDefinitionReaderUtils.registerBeanDefinition的实现:*/
 public static void registerBeanDefinition(
public static void registerBeanDefinition(
 BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)

 throws BeanDefinitionStoreException
            throws BeanDefinitionStoreException  {
{

 //注册BeanDefinition
        //注册BeanDefinition
 String beanName = definitionHolder.getBeanName();
        String beanName = definitionHolder.getBeanName();
 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

 //注册bean的别名
        //注册bean的别名
 String[] aliases = definitionHolder.getAliases();
        String[] aliases = definitionHolder.getAliases();

 if (aliases != null)
        if (aliases != null)  {
{

 for (int i = 0; i < aliases.length; i++)
            for (int i = 0; i < aliases.length; i++)  {
{
 registry.registerAlias(beanName, aliases[i]);
                registry.registerAlias(beanName, aliases[i]);
 }
            }
 }
        }
 }
    }

 public class DefaultListableBeanFactory
public class DefaultListableBeanFactory 
 extends AbstractAutowireCapableBeanFactory
extends AbstractAutowireCapableBeanFactory

 implements ConfigurableListableBeanFactory, BeanDefinitionRegistry
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry  {
{


 /** *//** *//** *//**Whether to allow re-registration of a different definition with the same name */
/** *//** *//** *//**Whether to allow re-registration of a different definition with the same name */
 private boolean allowBeanDefinitionOverriding = true;
    private boolean allowBeanDefinitionOverriding = true;


 /** *//** *//** *//** Whether to allow eager class loading even for lazy-init beans */
/** *//** *//** *//** Whether to allow eager class loading even for lazy-init beans */
 private boolean allowEagerClassLoading = true;
    private boolean allowEagerClassLoading = true;


 /** *//** *//** *//** Whether bean definition metadata may be cached for all beans */
/** *//** *//** *//** Whether bean definition metadata may be cached for all beans */
 private boolean configurationFrozen = false;
    private boolean configurationFrozen = false;

 /** *//** *//** *//** Map of bean definition objects, keyed by bean name *///以ConcurrentMap存储BeanDefinition
/** *//** *//** *//** Map of bean definition objects, keyed by bean name *///以ConcurrentMap存储BeanDefinition
 private final Map beanDefinitionMap =
private final Map beanDefinitionMap = 
 CollectionFactory.createConcurrentMapIfPossible(16);
CollectionFactory.createConcurrentMapIfPossible(16);


 /** *//** *//** *//** List of bean definition names, in registration order *///存储注册的beanName
/** *//** *//** *//** List of bean definition names, in registration order *///存储注册的beanName
 private final List beanDefinitionNames = new ArrayList();
    private final List beanDefinitionNames = new ArrayList();


 /** *//** *//** *//** Cached array of bean definition names in case of frozen configuration *///存储被冻结的beanName
    /** *//** *//** *//** Cached array of bean definition names in case of frozen configuration *///存储被冻结的beanName
 private String[] frozenBeanDefinitionNames;
    private String[] frozenBeanDefinitionNames;


 public void registerBeanDefinition(String beanName,
public void registerBeanDefinition(String beanName, 
 BeanDefinition beanDefinition)
BeanDefinition beanDefinition)

 throws BeanDefinitionStoreException
            throws BeanDefinitionStoreException  {
{


 if (beanDefinition instanceof AbstractBeanDefinition)
        if (beanDefinition instanceof AbstractBeanDefinition)  {
{

 try
            try  {
{
 ((AbstractBeanDefinition) beanDefinition).validate();
                ((AbstractBeanDefinition) beanDefinition).validate();
 }
            }

 catch (BeanDefinitionValidationException ex)
            catch (BeanDefinitionValidationException ex)  {
{
 ……
                ……
 }
            }
 }
        }


 synchronized (this.beanDefinitionMap)
        synchronized (this.beanDefinitionMap)  {
{
 Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
            Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);

 if (oldBeanDefinition != null)
            if (oldBeanDefinition != null)  {
{
 //如果相同名字的BeanDefinition已经存在,且不允许覆盖,抛出异常。
               //如果相同名字的BeanDefinition已经存在,且不允许覆盖,抛出异常。

 if (!this.allowBeanDefinitionOverriding)
                if (!this.allowBeanDefinitionOverriding)  {
{
 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +"': There is already [" + oldBeanDefinition + "] bound.");
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +"': There is already [" + oldBeanDefinition + "] bound.");
 }
                }

 else
                else  {
{

 if (this.logger.isInfoEnabled())
                    if (this.logger.isInfoEnabled())  {
{
 this.logger.info("Overriding bean definition for bean '" + beanName +
                        this.logger.info("Overriding bean definition for bean '" + beanName +
 "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                                "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
 }
                    }
 }
                }
 }
            }

 else
            else  {
{
 this.beanDefinitionNames.add(beanName);
                this.beanDefinitionNames.add(beanName);
 this.frozenBeanDefinitionNames = null;
                this.frozenBeanDefinitionNames = null;
 }
            }
 this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionMap.put(beanName, beanDefinition);

 resetBeanDefinition(beanName);
            resetBeanDefinition(beanName);
 }
        }
 }
    }


 protected void resetBeanDefinition(String beanName)
protected void resetBeanDefinition(String beanName)  {
{
 // Remove the merged bean definition for the given bean, if already created.
// Remove the merged bean definition for the given bean, if already created.
 clearMergedBeanDefinition(beanName);
        clearMergedBeanDefinition(beanName);

 // Remove corresponding bean from singleton cache, if any. Shouldn't usually
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
 // be necessary, rather just meant for overriding a context's default beans
// be necessary, rather just meant for overriding a context's default beans
 // (e.g. the default StaticMessageSource in a StaticApplicationContext).
// (e.g. the default StaticMessageSource in a StaticApplicationContext).

 synchronized (getSingletonMutex())
        synchronized (getSingletonMutex())  {//
{//
 destroySingleton(beanName);
            destroySingleton(beanName);
 }
        }

 // Reset all bean definitions that have the given bean as parent
        // Reset all bean definitions that have the given bean as parent
 // (recursively).
        // (recursively).

 for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();)
        for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();)  {
{
 String bdName = (String) it.next();
            String bdName = (String) it.next();

 if (!beanName.equals(bdName))
            if (!beanName.equals(bdName))  {
{
 BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(bdName);
                BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(bdName);

 if (beanName.equals(bd.getParentName()))
                if (beanName.equals(bd.getParentName()))   {
{
 resetBeanDefinition(bdName);
                    resetBeanDefinition(bdName);
 }
                }
 }
            }
 }
        }
 }
}

spring中bean标签的解释代码一览:
parseBeanDefinitionElement方法分析
 该方法主要针对bean标签进行解释处理,解释后的信息封装到GenericBeanDefinition中,然后把beanName、alias、GenericBeanDefinition封装到BeanDefinitionHolder中.  

 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)  {
{

 String id = ele.getAttribute(ID_ATTRIBUTE);//取得id属性
       String id = ele.getAttribute(ID_ATTRIBUTE);//取得id属性

 //取得name属性
//取得name属性

 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
       String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); 

 List aliases = new ArrayList();//aliase属性 例如<alias name="fromName" alias="toName"/>
       List aliases = new ArrayList();//aliase属性 例如<alias name="fromName" alias="toName"/>


 if (StringUtils.hasLength(nameAttr))
       if (StringUtils.hasLength(nameAttr))  {
{

 //如果name属性存在,则把name的值分解,存储到aliases集合中
//如果name属性存在,则把name的值分解,存储到aliases集合中

 String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
           String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);

 aliases.addAll(Arrays.asList(nameArr));
           aliases.addAll(Arrays.asList(nameArr));

 }
       }

 
 

 String beanName = id;//默认id的值作为beanName
       String beanName = id;//默认id的值作为beanName


 if (!StringUtils.hasText(beanName) && !aliases.isEmpty())
       if (!StringUtils.hasText(beanName) && !aliases.isEmpty())  {//如果id不存在,且aliases不为空,那么以aliases中的第一个作为beanName
{//如果id不存在,且aliases不为空,那么以aliases中的第一个作为beanName

 beanName = (String) aliases.remove(0);
           beanName = (String) aliases.remove(0);


 if (logger.isDebugEnabled())
           if (logger.isDebugEnabled())  {
{

 logger.debug("No XML 'id' specified - using '" + beanName +
              logger.debug("No XML 'id' specified - using '" + beanName +

 "' as bean name and " + aliases + " as aliases");
                     "' as bean name and " + aliases + " as aliases");

 }
           }

 }
       }

 
 


 if (containingBean == null)
       if (containingBean == null)  {
{


 /**//*检查在一个文件中,beanName或者alias是否有重复的,如果有重复的报告错误,无重复,则把当前的beanName与alias记录到Set中*/
           /**//*检查在一个文件中,beanName或者alias是否有重复的,如果有重复的报告错误,无重复,则把当前的beanName与alias记录到Set中*/

 checkNameUniqueness(beanName, aliases, ele);
           checkNameUniqueness(beanName, aliases, ele);

 }
       }

 
        

 //对bean的详细解释,主要包括常见的class、parent、lazy-init、singleton等属性
//对bean的详细解释,主要包括常见的class、parent、lazy-init、singleton等属性

 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
       AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);


 if (beanDefinition != null)
       if (beanDefinition != null)  {
{


 if (!StringUtils.hasText(beanName))
           if (!StringUtils.hasText(beanName))  {
{


 try
              try  {
{


 if (containingBean != null)
                  if (containingBean != null)  {
{

 beanName = BeanDefinitionReaderUtils.generateBeanName(
                     beanName = BeanDefinitionReaderUtils.generateBeanName(

 beanDefinition, this.readerContext.getRegistry(), true);
                            beanDefinition, this.readerContext.getRegistry(), true);

 }
                  }


 else
                  else  {
{


 /**//*容器生成beanName,其规则如下:
/**//*容器生成beanName,其规则如下:

 如果beanDefinition存在className,则以"className#编号"或者"className"作为beanName;
如果beanDefinition存在className,则以"className#编号"或者"className"作为beanName;

 如果beanDefinition不存在className,且beanDefinition存在parentName,则以"parentName$child#编号"或者"parentName$child"作为beanName;
如果beanDefinition不存在className,且beanDefinition存在parentName,则以"parentName$child#编号"或者"parentName$child"作为beanName;

 如果beanDefinition不存在className,且beanDefinition存在factorybeanName,则以"factoryBeanName$created#编号"或者"factoryBeanName$created"作为beanName;
如果beanDefinition不存在className,且beanDefinition存在factorybeanName,则以"factoryBeanName$created#编号"或者"factoryBeanName$created"作为beanName;

 注意,编号是通过查询容器是否包含beanName,然后累加获得的*/
注意,编号是通过查询容器是否包含beanName,然后累加获得的*/

 beanName = this.readerContext.generateBeanName(beanDefinition);
                  beanName = this.readerContext.generateBeanName(beanDefinition);

 String beanClassName = beanDefinition.getBeanClassName();
String beanClassName = beanDefinition.getBeanClassName();

 if (beanClassName != null &&
                     if (beanClassName != null &&

 beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                            beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&


 !this.readerContext.getRegistry().isBeanNameInUse(beanClassName))
                            !this.readerContext.getRegistry().isBeanNameInUse(beanClassName))  {
{

 aliases.add(beanClassName);
                         aliases.add(beanClassName);

 }
                     }

 }
                  }


 if (logger.isDebugEnabled())
                  if (logger.isDebugEnabled())  {
{

 logger.debug("Neither XML 'id' nor 'name' specified - " +
                     logger.debug("Neither XML 'id' nor 'name' specified - " +

 "using generated bean name [" + beanName + "]");
                            "using generated bean name [" + beanName + "]");

 }
                  }

 }
              }


 catch (Exception ex)
              catch (Exception ex)  {
{

 error(ex.getMessage(), ele);
                  error(ex.getMessage(), ele);

 return null;
                  return null;

 }
              }

 }
           }

 String[] aliasesArray = StringUtils.toStringArray(aliases);
           String[] aliasesArray = StringUtils.toStringArray(aliases);

 //最后封装为BeanDefinitionHoler返回
           //最后封装为BeanDefinitionHoler返回

 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
           return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

 }
       }

 
 

 return null;
       return null;

 }
}  

 public AbstractBeanDefinition parseBeanDefinitionElement(
public AbstractBeanDefinition parseBeanDefinitionElement(


 Element ele, String beanName, BeanDefinition containingBean)
           Element ele, String beanName, BeanDefinition containingBean)  {
{

 String className = null;//解释class属性
       String className = null;//解释class属性


 if (ele.hasAttribute(CLASS_ATTRIBUTE))
       if (ele.hasAttribute(CLASS_ATTRIBUTE))  {
{

 className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
           className = ele.getAttribute(CLASS_ATTRIBUTE).trim();

 }
       }

 String parent = null;
       String parent = null;


 if (ele.hasAttribute(PARENT_ATTRIBUTE))
       if (ele.hasAttribute(PARENT_ATTRIBUTE))  {//parent属性
{//parent属性

 parent = ele.getAttribute(PARENT_ATTRIBUTE);
           parent = ele.getAttribute(PARENT_ATTRIBUTE);

 }
       }

 
 


 try
       try  {
{

 //以bean的id作为参数封装到BeanEntry中;ParseState以Stack作为存储数据结构来存储Bean的解释状态
//以bean的id作为参数封装到BeanEntry中;ParseState以Stack作为存储数据结构来存储Bean的解释状态

 this.parseState.push(new BeanEntry(beanName));
           this.parseState.push(new BeanEntry(beanName)); 

 
           

 //创建了GenericBeanDefinition,并为其设置parent=='parent',beanClass=='class',beanClassName属性
//创建了GenericBeanDefinition,并为其设置parent=='parent',beanClass=='class',beanClassName属性

 AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
           AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(

 parent, className, this.readerContext.getBeanClassLoader());
                  parent, className, this.readerContext.getBeanClassLoader());

 
 


 if (ele.hasAttribute(SCOPE_ATTRIBUTE))
           if (ele.hasAttribute(SCOPE_ATTRIBUTE))  {//解释scope
{//解释scope

 bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
              bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));


 if (ele.hasAttribute(SINGLETON_ATTRIBUTE))
              if (ele.hasAttribute(SINGLETON_ATTRIBUTE))  {
{

 error("Specify either 'scope' or 'singleton', not both", ele);
                  error("Specify either 'scope' or 'singleton', not both", ele);

 }
              }

 }
           }


 else if (ele.hasAttribute(SINGLETON_ATTRIBUTE))
           else if (ele.hasAttribute(SINGLETON_ATTRIBUTE))  {//singleton
{//singleton

 bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
    bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?

 BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
                     BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);

 }
           }


 else if (containingBean != null)
           else if (containingBean != null)  {
{

 bd.setScope(containingBean.getScope());
                  bd.setScope(containingBean.getScope());

 }
           }

 
 


 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE))
           if (ele.hasAttribute(ABSTRACT_ATTRIBUTE))  {//解释abstract
{//解释abstract

 bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
              bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));

 }
           }

 
 

 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);//解释lazy-init
           String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);//解释lazy-init


 if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton())
           if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton())  {
{

 // Just apply default to singletons, as lazy-init has no meaning for prototypes.
              // Just apply default to singletons, as lazy-init has no meaning for prototypes.

 lazyInit = this.defaults.getLazyInit();
              lazyInit = this.defaults.getLazyInit();

 }
           }

 bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
           bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

 
 

 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);//解释自动装配模式
           String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);//解释自动装配模式

 bd.setAutowireMode(getAutowireMode(autowire));
           bd.setAutowireMode(getAutowireMode(autowire));

 
 

 String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
           String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);

 bd.setDependencyCheck(getDependencyCheck(dependencyCheck));//解释依赖检查
           bd.setDependencyCheck(getDependencyCheck(dependencyCheck));//解释依赖检查

 
 


 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE))
           if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE))  {
{

 String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);//解释depends-on
              String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);//解释depends-on

 bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));
              bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));

 }
           }

 
 

 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
           String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);


 if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate))
           if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate))  {
{

 String candidatePattern = this.defaults.getAutowireCandidates();
              String candidatePattern = this.defaults.getAutowireCandidates();


 if (candidatePattern != null)
              if (candidatePattern != null)  {
{

 String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
                  String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);

 bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
                  bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));

 }
              }

 }
           }


 else
           else  {
{

 bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
              bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));

 }
           }

 
 


 if (ele.hasAttribute(PRIMARY_ATTRIBUTE))
           if (ele.hasAttribute(PRIMARY_ATTRIBUTE))  {
{

 bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
              bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));

 }
           }

 
 


 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE))
           if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE))  {
{

 String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
              String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);


 if (!"".equals(initMethodName))
              if (!"".equals(initMethodName))  {
{

 bd.setInitMethodName(initMethodName);
                  bd.setInitMethodName(initMethodName);

 }
              }

 }
           }


 else
           else  {
{


 if (this.defaults.getInitMethod() != null)
              if (this.defaults.getInitMethod() != null)  {
{

 bd.setInitMethodName(this.defaults.getInitMethod());
                  bd.setInitMethodName(this.defaults.getInitMethod());

 bd.setEnforceInitMethod(false);
                  bd.setEnforceInitMethod(false);

 }
              }

 }
           }

 
 


 if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE))
           if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE))  {
{

 String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
              String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);


 if (!"".equals(destroyMethodName))
              if (!"".equals(destroyMethodName))  {
{

 bd.setDestroyMethodName(destroyMethodName);
                  bd.setDestroyMethodName(destroyMethodName);

 }
              }

 }
           }


 else
           else  {
{


 if (this.defaults.getDestroyMethod() != null)
              if (this.defaults.getDestroyMethod() != null)  {
{

 bd.setDestroyMethodName(this.defaults.getDestroyMethod());
                  bd.setDestroyMethodName(this.defaults.getDestroyMethod());

 bd.setEnforceDestroyMethod(false);
                  bd.setEnforceDestroyMethod(false);

 }
              }

 }
           }

 
 


 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE))
           if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE))  {//解释工厂方法属性
{//解释工厂方法属性

 bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
              bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));

 }
           }


 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE))
           if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE))  {//解释工厂bean属性
{//解释工厂bean属性

 bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
              bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));

 }
           }

 
 

 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
           bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

 
 

 parseMetaElements(ele, bd);
           parseMetaElements(ele, bd);


 /** *//**解释lookup-method(方法注入的一种),还记得吗,使用lookup-method能够覆盖bean标签指定的bean的抽象method(该method由method标签指定),主要针对singleton引用一个prototype的情形*/
           /** *//**解释lookup-method(方法注入的一种),还记得吗,使用lookup-method能够覆盖bean标签指定的bean的抽象method(该method由method标签指定),主要针对singleton引用一个prototype的情形*/

 parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
           parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

 //解释replace-method(方法注入的一种)
           //解释replace-method(方法注入的一种)

 parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
           parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

 
 

 parseConstructorArgElements(ele, bd);
           parseConstructorArgElements(ele, bd);


 /** *//**这里把解释出来的属性值,ref[RuntimeBeanReference]、list[ManagedList]、set[ManagedSet]、map、properties,封装到PropertyValue,
           /** *//**这里把解释出来的属性值,ref[RuntimeBeanReference]、list[ManagedList]、set[ManagedSet]、map、properties,封装到PropertyValue,

 然后把PropertyValue加入到BeanDefinition*/
       然后把PropertyValue加入到BeanDefinition*/

 parsePropertyElements(ele, bd);
           parsePropertyElements(ele, bd);

 parseQualifierElements(ele, bd);
           parseQualifierElements(ele, bd);


 bd.setResource(this.readerContext.getResource());
           bd.setResource(this.readerContext.getResource());

 bd.setSource(extractSource(ele));
           bd.setSource(extractSource(ele));

 return bd;
           return bd;

 }
}

到此为止,spring IOC容器启动中的内部容器初始化部分基本分析完成。
下一节
	posted on 2012-02-07 11:57 
zhangxl 阅读(527) 
评论(0)  编辑  收藏  所属分类: 
IOC/AOP