0%

源码加载并解析xml文件

模板

加载并解析xml文件

相关的类和方法。

使用spring

1.新建spring项目

image-20200707152842482

2.编写book类和配置文件

Book类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Book {
private String bookName;

private String author;

public String getBookName() {
return bookName;
}

public void setBookName(String bookName) {
this.bookName = bookName;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public void printBookInfo() {
System.out.println("Book Name:" + this.bookName + ",Author:" + this.author);
}
}

配置文件

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="Book">
<property name="bookName" value="平凡的世界"/>
<property name="author" value="路遥"/>
</bean>
</beans>

3.Test方法:

1
2
3
ApplicationContext  applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
Book book = applicationContext.getBean("book",Book.class);
book.printBookInfo();

spring加载并解析xml文件的过程

1-5准备工作

6-9要获取xml资源时的处理,资源定位,多配置循环处理,资源编码处理

10-11获取资源流,使用工具初步解析

12定义注册流程统计BeanDefinition数量

13获取初步解析的资源,跳转

14-20实际解析

  • 14处理命名空间
  • 15默认标签,自定义标签分别处理
  • 16默认标签中的不同标签处理,bean、import、alias、beans
  • 17解析bean标签和注册BeanDefinition的流程
  • 18跳转
  • 19-20解析bean标签

  1. ClassPathXmlApplicationContext类的构造方法

    1
    2
    3
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[]{configLocation}, true, (ApplicationContext)null);
    }
  2. 构造方法内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
    //刷新,即执行spring流程
    this.refresh();
    }

    }
  3. AbstractApplicationContext类规定了refresh()的流程内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // Prepare this context for refreshing.
    // STEP 1: 刷新预处理
    prepareRefresh();

    // Tell the subclass to refresh the internal bean factory.
    // STEP 2:
    // a) 创建IoC容器(DefaultListableBeanFactory)
    // b) 加载解析XML文件(最终存储到Document对象中)
    // c) 读取Document对象,并完成BeanDefinition的加载和注册工作
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // Prepare the bean factory for use in this context.
    // STEP 3: 对IoC容器进行一些预处理(设置一些公共属性)
    prepareBeanFactory(beanFactory);

    try {
    // Allows post-processing of the bean factory in context subclasses.
    // STEP 4:
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    // STEP 5: 调用BeanFactoryPostProcessor后置处理器对BeanDefinition处理
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    // STEP 6: 注册BeanPostProcessor后置处理器
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    // STEP 7: 初始化一些消息源(比如处理国际化的i18n等消息源)
    initMessageSource();

    // Initialize event multicaster for this context.
    // STEP 8: 初始化应用事件广播器
    initApplicationEventMulticaster();

    // Initialize other special beans in specific context subclasses.
    // STEP 9: 初始化一些特殊的bean
    onRefresh();

    // Check for listener beans and register them.
    // STEP 10: 注册一些监听器
    registerListeners();

    // Instantiate all remaining (non-lazy-init) singletons.
    // STEP 11: 实例化剩余的单例bean(非懒加载方式)
    // 注意事项:Bean的IoC、DI和AOP都是发生在此步骤
    finishBeanFactoryInitialization(beanFactory);

    // Last step: publish corresponding event.
    // STEP 12: 完成刷新时,需要发布对应的事件
    finishRefresh();
    }

    catch (BeansException ex) {
    if (logger.isWarnEnabled()) {
    logger.warn("Exception encountered during context initialization - " +
    "cancelling refresh attempt: " + ex);
    }

    // Destroy already created singletons to avoid dangling resources.
    destroyBeans();

    // Reset 'active' flag.
    cancelRefresh(ex);

    // Propagate exception to caller.
    throw ex;
    }

    finally {
    // Reset common introspection caches in Spring's core, since we
    // might not ever need metadata for singleton beans anymore...
    resetCommonCaches();
    }
    }
    }
  4. obtainFreshBeanFactory()方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 主要是通过该方法完成IoC容器的刷新
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
    logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
    }
  5. AbstractRefreshableApplicationContext类refreshBeanFactory()方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    protected final void refreshBeanFactory() throws BeansException {
    // 如果之前有IoC容器,则销毁
    if (hasBeanFactory()) {
    destroyBeans();
    closeBeanFactory();
    }
    try {
    // 创建IoC容器,也就是DefaultListableBeanFactory
    DefaultListableBeanFactory beanFactory = createBeanFactory();
    beanFactory.setSerializationId(getId());
    // 设置工厂的属性:是否允许BeanDefinition覆盖和是否允许循环依赖
    customizeBeanFactory(beanFactory);
    // 调用载入BeanDefinition的方法,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
    loadBeanDefinitions(beanFactory);//钩子方法
    synchronized (this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
    }
    }
    catch (IOException ex) {
    throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
    }
  6. AbstractXmlApplicationContext类的loadBeanDefinitions()的方法

    准备工作完成。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    // 创建一个BeanDefinition阅读器,通过阅读XML文件,真正完成BeanDefinition的加载和注册
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);

    // 委托给BeanDefinition阅读器去加载BeanDefinition
    loadBeanDefinitions(beanDefinitionReader);
    }
  7. loadBeanDefinitions(XmlBeanDefinitionReader reader)方法

    对资源的其他处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    // 获取资源的定位
    // 这里getConfigResources是一个空实现,真正实现是调用子类的获取资源定位的方法
    // 比如:ClassPathXmlApplicationContext中进行了实现
    // 而FileSystemXmlApplicationContext没有使用该方法
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
    // XML Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的资源
    reader.loadBeanDefinitions(configResources);
    }
    // 如果子类中获取的资源定位为空,则获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
    // XML Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的资源
    reader.loadBeanDefinitions(configLocations);
    }
    }
  8. AbstractBeanDefinitionReader的loadBeanDefinitions(configResources)方法

    1
    2
    3
    4
    5
    6
    7
    8
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int counter = 0;
    for (Resource resource : resources) {
    counter += loadBeanDefinitions(resource);
    }
    return counter;
    }
  9. XmlBeanDefinitionReader的loadBeanDefinitions(resource);

    资源编码处理

    1
    2
    3
    4
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException 	  {
    // 将读入的XML资源进行特殊编码处理
    return loadBeanDefinitions(new EncodedResource(resource));
    }
  10. loadBeanDefinitions的具体实现

    获取xml资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (logger.isInfoEnabled()) {
    logger.info("Loading XML bean definitions from " + encodedResource.getResource());
    }

    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
    currentResources = new HashSet<>(4);
    this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    if (!currentResources.add(encodedResource)) {
    throw new BeanDefinitionStoreException(
    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }
    try {
    // 将资源文件转为InputStream的IO流
    InputStream inputStream = encodedResource.getResource().getInputStream();
    try {
    // 从InputStream中得到XML的解析源
    InputSource inputSource = new InputSource(inputStream);
    if (encodedResource.getEncoding() != null) {
    inputSource.setEncoding(encodedResource.getEncoding());
    }
    // 这里是具体的读取过程
    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    finally {
    inputStream.close();
    }
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(
    "IOException parsing XML document from " + encodedResource.getResource(), ex);
    }
    finally {
    currentResources.remove(encodedResource);
    if (currentResources.isEmpty()) {
    this.resourcesCurrentlyBeingLoaded.remove();
    }
    }
    }

  11. 具体的读取xml过程 doLoadBeanDefinitions(inputSource, encodedResource.getResource());

    用工具初步解析获取的xml资源流

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {
    try {
    // 通过DOM4J加载解析XML文件,最终形成Document对象
    Document doc = doLoadDocument(inputSource, resource);
    // 通过对Document对象的操作,完成BeanDefinition的加载和注册工作
    return registerBeanDefinitions(doc, resource);
    }
    catch (BeanDefinitionStoreException ex) {
    throw ex;
    }
    catch (SAXParseException ex) {
    throw new XmlBeanDefinitionStoreException(resource.getDescription(),
    "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
    }
    catch (SAXException ex) {
    throw new XmlBeanDefinitionStoreException(resource.getDescription(),
    "XML document from " + resource + " is invalid", ex);
    }
    catch (ParserConfigurationException ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "Parser configuration exception parsing XML from " + resource, ex);
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "IOException parsing XML document from " + resource, ex);
    }
    catch (Throwable ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "Unexpected exception parsing XML document from " + resource, ex);
    }
    }

  12. registerBeanDefinitions(doc, resource);

    注册bean流程,统计BeanDefinition数量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    // 创建BeanDefinitionDocumentReader来解析Document对象,完成BeanDefinition解析
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    // 获得容器中已经注册的BeanDefinition数量
    int countBefore = getRegistry().getBeanDefinitionCount();
    //解析过程入口,BeanDefinitionDocumentReader只是个接口,具体的实现过程在DefaultBeanDefinitionDocumentReader完成
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    // 统计新的的BeanDefinition数量
    return getRegistry().getBeanDefinitionCount() - countBefore;
    }

  13. DefaultBeanDefinitionDocumentReader类registerBeanDefinitions(doc, createReaderContext(resource));

    1
    2
    3
    4
    5
    6
    7
    8
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext)    {
    this.readerContext = readerContext;
    logger.debug("Loading bean definitions");
    // 获得Document的根元素<beans>标签
    Element root = doc.getDocumentElement();
    // 真正实现BeanDefinition解析和注册工作
    doRegisterBeanDefinitions(root);
    }
  14. doRegisterBeanDefinitions(root);

    处理命名空间,并将解析工作委托给了其他类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    protected void doRegisterBeanDefinitions(Element root) {
    // Any nested <beans> elements will cause recursion in this method. In
    // order to propagate and preserve <beans> default-* attributes correctly,
    // keep track of the current (parent) delegate, which may be null. Create
    // the new (child) delegate with a reference to the parent for fallback purposes,
    // then ultimately reset this.delegate back to its original (parent) reference.
    // this behavior emulates a stack of delegates without actually necessitating one.

    // 这里使用了委托模式,将具体的BeanDefinition解析工作交给了BeanDefinitionParserDelegate去完成
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    // 判断该根标签是否包含http://www.springframework.org/schema/beans默认命名空间
    if (this.delegate.isDefaultNamespace(root)) {
    String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    if (StringUtils.hasText(profileSpec)) {
    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
    if (logger.isInfoEnabled()) {
    logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
    "] not matching: " + getReaderContext().getResource());
    }
    return;
    }
    }
    }
    // 在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性
    preProcessXml(root);
    // 委托给BeanDefinitionParserDelegate,从Document的根元素开始进行BeanDefinition的解析
    parseBeanDefinitions(root, this.delegate);
    // 在解析Bean定义之后,进行自定义的解析,增加解析过程的可扩展性
    postProcessXml(root);

    this.delegate = parent;
    }

  15. parseBeanDefinitions(root, this.delegate);

    默认标签和自定义标签有不同的流程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // 加载的Document对象是否使用了Spring默认的XML命名空间(beans命名空间)
    if (delegate.isDefaultNamespace(root)) {
    // 获取Document对象根元素的所有子节点(bean标签、import标签、alias标签和其他自定义标签context、aop等)
    NodeList nl = root.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
    Node node = nl.item(i);
    if (node instanceof Element) {
    Element ele = (Element) node;
    // bean标签、import标签、alias标签,则使用默认解析规则
    if (delegate.isDefaultNamespace(ele)) {
    parseDefaultElement(ele, delegate);
    }
    else {//像context标签、aop标签、tx标签,则使用用户自定义的解析规则解析元素节点
    delegate.parseCustomElement(ele);
    }
    }
    }
    }
    else {
    // 如果不是默认的命名空间,则使用用户自定义的解析规则解析元素节点
    delegate.parseCustomElement(root);
    }
    }

  16. parseDefaultElement(ele, delegate);

    默认的标签中各个不同的标签解析不同

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析<import>标签
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
    importBeanDefinitionResource(ele);
    }
    // 解析<alias>标签
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
    processAliasRegistration(ele);
    }
    // 解析<bean>标签
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    processBeanDefinition(ele, delegate);
    }
    // 解析内置<beans>标签
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    // recurse
    // 递归调用
    doRegisterBeanDefinitions(ele);
    }
    }
  17. DefaultListableBeanFactory。processBeanDefinition(ele, delegate);

    解析bean标签,注册BeanDefinition到IoC容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析<bean>标签,获取BeanDefinition
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
    // 如果需要,则装饰BeanDefinition对象
    bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    try {
    // Register the final decorated instance.
    // 注册最终的BeanDefinition到BeanDefinitionRegistry(DefaultListableBeanFactory)
    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    }
    catch (BeanDefinitionStoreException ex) {
    getReaderContext().error("Failed to register bean definition with name '" +
    bdHolder.getBeanName() + "'", ele, ex);
    }
    // Send registration event.
    getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
    }
  18. BeanDefinitionParserDelegate的parseBeanDefinitionElement(ele);

    1
    2
    3
    4
    5
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    // 解析<bean>标签,获取BeanDefinition对象
    return parseBeanDefinitionElement(ele, null);
    }

  19. parseBeanDefinitionElement(ele, null);

    做bean标签的解析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
    // 获取bean的id
    String id = ele.getAttribute(ID_ATTRIBUTE);
    // 获取bean的name
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    List<String> aliases = new ArrayList<>();
    if (StringUtils.hasLength(nameAttr)) {
    String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    aliases.addAll(Arrays.asList(nameArr));
    }

    String beanName = id;
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
    beanName = aliases.remove(0);
    if (logger.isDebugEnabled()) {
    logger.debug("No XML 'id' specified - using '" + beanName +
    "' as bean name and " + aliases + " as aliases");
    }
    }

    if (containingBean == null) {
    // 检查bean的id或者name是否唯一
    checkNameUniqueness(beanName, aliases, ele);
    }
    // 解析<bean>标签,获取BeanDefinition对象
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
    if (!StringUtils.hasText(beanName)) {
    try {
    if (containingBean != null) {
    beanName = BeanDefinitionReaderUtils.generateBeanName(
    beanDefinition, this.readerContext.getRegistry(), true);
    }
    else {
    beanName = this.readerContext.generateBeanName(beanDefinition);
    // Register an alias for the plain bean class name, if still possible,
    // if the generator returned the class name plus a suffix.
    // This is expected for Spring 1.2/2.0 backwards compatibility.
    String beanClassName = beanDefinition.getBeanClassName();
    if (beanClassName != null &&
    beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
    !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
    aliases.add(beanClassName);
    }
    }
    if (logger.isDebugEnabled()) {
    logger.debug("Neither XML 'id' nor 'name' specified - " +
    "using generated bean name [" + beanName + "]");
    }
    }
    catch (Exception ex) {
    error(ex.getMessage(), ele);
    return null;
    }
    }
    String[] aliasesArray = StringUtils.toStringArray(aliases);
    // 将BeanDefinition对象和BeanName封装到BeanDefinitionHolder对象中
    return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
    }
  20. parseBeanDefinitionElement(ele, beanName, containingBean);

    解析获取到的资源中的其他属性和bean的子标签,id,name已解析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, @Nullable BeanDefinition containingBean) {

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

    String className = null;
    // 获取bean标签的class属性
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
    className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }
    String parent = null;
    // 获取bean标签的parent属性
    if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
    parent = ele.getAttribute(PARENT_ATTRIBUTE);
    }

    try {
    // 创建BeanDefinition对象GenericBeanDefinition
    AbstractBeanDefinition bd = createBeanDefinition(className, parent);

    // 解析<bean>标签的属性
    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
    /** 解析<bean>标签的子标签 --- begin**/
    // 解析<description>标签
    bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    // 解析<meta>标签
    parseMetaElements(ele, bd);
    // 解析<lookup-method>标签
    parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
    // 解析<replaced-method>标签
    parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

    // 解析<constructor-arg>标签
    parseConstructorArgElements(ele, bd);
    // 解析<property>标签
    parsePropertyElements(ele, bd);
    // 解析<qualifier>标签
    parseQualifierElements(ele, bd);
    /** 解析<bean>标签的子标签 --- end**/

    bd.setResource(this.readerContext.getResource());
    bd.setSource(extractSource(ele));

    return bd;
    }
    catch (ClassNotFoundException ex) {
    error("Bean class [" + className + "] not found", ele, ex);
    }
    catch (NoClassDefFoundError err) {
    error("Class that bean class [" + className + "] depends on not found", ele, err);
    }
    catch (Throwable ex) {
    error("Unexpected failure during bean definition parsing", ele, ex);
    }
    finally {
    this.parseState.pop();
    }

    return null;
    }