1、具体的 Spring BeanDefinition 的解析是在 BeanDefinitionParserDelegate 中完成的。这个类里包含了各种 Spring Bean 定义规则的处理,感兴趣的读者可以仔细研究。比如我们最熟悉的对 Bean 元素的处理是怎样完成的,也就是在 XML 定义文件中出现的 这个最常见的元素信息是怎样处理的。在这里,我们会看到那些熟悉的 BeanDefinition 定义的处理,比如 id、name、aliase 等属性元素。把这些元素的值从 XML 文件相应的元素的属性中读取出来以后,会被设置到生成的 BeanDefinitionHolder 中去。这些属性的
2、解析还是比较简单的。对于其他元素配置的解析,比如各种 Bean 的属性配置,通过一个较为复杂的解析过程,这个过程是由 parseBeanDefinitionElement 来完成的。解析完成以后,会把解析结果放到 BeanDefinition 对象中并设置到 BeanDefinitionHolder 中去,如代码清单 2-16 所示。代码清单 2-16 BeanDefinitionParserDelegate 对 bean 元素定义的处理1. public BeanDefinitionHolder 2. parseBeanDefinitionElement(Element ele, BeanD
3、efinition 3. containingBean) 4. 5. /这里取得在元素中定义的 id、name 和 aliase 属性的值。 6. String id = ele.getAttribute(ID_ATTRIBUTE); 7. String nameAttr = 8. ele.getAttribute(NAME_ATTRIBUTE); 9. List aliases = new 10.ArrayList(); 11. if (StringUtils.hasLength(nameAttr) 12. String nameArr = 13.StringUtils.tokenizeTo
4、StringArray(nameAttr, BEAN_NAME_ 14.DELIMITERS); 15. 16.aliases.addAll(Arrays.asList(nameArr); 17. 18. String beanName = id; 19. if (!StringUtils.hasText(beanName) 22. if (logger.isDebugEnabled() 23. logger.debug(“No XML id 24.specified - using “ + beanName + 25. “ as bean 26.name and “ + aliases +
5、“ as aliases“); 27. 28. 29. if (containingBean = null) 30. checkNameUniqueness(beanName, 31.aliases, ele); 32. 33. /这个方法会引发对 bean 元素的详细解析。 34.AbstractBeanDefinition beanDefinition = 35.parseBeanDefinitionElement(ele, 36.beanName,containingBean); 37. if (beanDefinition != null) 38. if (!StringUtils.h
6、asText(beanName) 39. 40. try 41. if (containingBean 42.!= null) 43. beanName = 44.BeanDefinitionReaderUtils.generateBeanName( 45. 46.beanDefinition, this.readerContext.getRegistry(), 47. 48.true); 49. 50. else 51. beanName = 52. 53.this.readerContext.generateBeanName(beanDefinition); 54. /* 55. *Reg
7、ister an 56.alias for the plain bean class name, if still 57. *possible,if 58.the generator returned the class name plus a 59. *suffix.This 60.is expected for Spring 1.2/2.0 backwards 61. 62.*compatibility. 63. */ 64. String 65.beanClassName = beanDefinition.getBeanClassName(); 66. if 67.(beanClassN
8、ame != null 76. 77. 78. if 79.(logger.isDebugEnabled() 80. 81.logger.debug(“Neither XML id nor name specified - “ + 82. 83.“using generated bean name “ + beanName + “); 84. 85. 86. catch (Exception ex) 87. 88.error(ex.getMessage(), ele); 89. return null; 90. 91. 92. String aliasesArray = 93.StringUt
9、ils.toStringArray(aliases); 94. return new 95.BeanDefinitionHolder(beanDefinition, beanName, 96.aliasesArray); 97. 98. return null; 99. 我们看到了对 Bean 元素进行解析的过程,也就是 BeanDefinition 依据 XML 的定义被创建的过程。这个 BeanDefinition 可以看成是定义的抽象,如图 2-7 所示。这个数据对象里封装的数据大多都是与定义相关的,也有很多就是我们在定义 Bean时看到的那些 Spring 标记,比如我们熟悉的 ini
10、t-method、destroy-method、factory-method,等等,这个 BeanDefinition 数据类型是非常重要的,它封装了很多基本数据。有了这些基本数据,IoC 容器才能对 Bean 配置进行处理,才能实现相应的容器特性。看起来很熟悉吧,beanClass 、description、lazyInit 这些属性都是在配置 Bean 时经常碰到的,原来都跑到这里来了。这个 BeanDefinition 是 IoC 容器体系中非常重要的核心数据结构。通过解析以后,这些数据已经做好在 IoC 容器里大显身手的准备了。对BeanDefinition 的元素的处理如代码清单 2
11、-17 所示,在这个过程中可以看到对 Bean 定义的相关处理,比如对元素 attribute 值的处理,对元素属性值的处理,对构造函数设置的处理,等等。代码清单 2-17 对 BeanDefinition 定义元素的处理1. public AbstractBeanDefinition 2. parseBeanDefinitionElement( 3. Element ele, String beanName, 4. BeanDefinition containingBean) 5. this.parseState.push(new 6. BeanEntry(beanName); 7. /*
12、8. 9. *这里只读取定义的中设置的 class 名字,然后载入到 BeanDefi 10.nition 中去, 11. 12.*只是做个记录,并不涉及对象的实例化过程,对象的实例化实际上 13.是在依赖注入时完成的。 14. */ 15. String className = null; 16. if (ele.hasAttribute(CLASS_ATTRIBUTE) 17. className = 18.ele.getAttribute(CLASS_ATTRIBUTE).trim(); 19. 20. try 21. String parent = null; 22. if 23.(e
13、le.hasAttribute(PARENT_ATTRIBUTE) 24. parent = 25.ele.getAttribute(PARENT_ATTRIBUTE); 26. 27. 28./这里生成需要的 BeanDefinition 对象,为 Bean 定义信息的载入做准 29.备。 30. AbstractBeanDefinition bd = 31.createBeanDefinition(className, parent); 32. 33./这里对当前的 Bean 元素进行属性解析,并设置 description 的信息 34.。 35. parseBeanDefinition
14、Attributes(ele, 36.beanName, containingBean, bd); 37. 38.bd.setDescription(DomUtils.getChildElementValueByTagName(ele 39., 40.DESCRIPTION_ELEMENT); 41. 42./从名字可以清楚地看到,这里是对各种元素的信息进行解析 43.的地方。 44. parseMetaElements(ele, bd); 45. parseLookupOverrideSubElements(ele, 46.bd.getMethodOverrides(); 47. parse
15、ReplacedMethodSubElements(ele, 48.bd.getMethodOverrides(); 49. /解析的构造函数设置。 50. parseConstructorArgElements(ele, 51.bd); 52. /解析的 property 设置。 53. parsePropertyElements(ele, bd); 54. parseQualifierElements(ele, bd); 55. 56.bd.setResource(this.readerContext.getResource(); 57. bd.setSource(extractSourc
16、e(ele); 58. return bd; 59. 60./* 61.*下面这些异常是我们在配置 bean 出现问题时经常可以看到的,原来 62.是在这里抛出的,这些检查是在 63.*createBeanDefinition 时进行的,会检查 bean 的 class 设置是否正确 64.,比如这个类是不是能找到。 65.*/ 66. catch (ClassNotFoundException ex) 67. error(“Bean class “ + className + 68.“ not found“, ele, ex); 69. 70. catch (NoClassDefFoundError err) 71. error(“Class that bean class “ + 72.className + “ depends on not found“, 73. ele, err); 74. 75. catch (Throwable ex) 76. error(“Unexpected failure during 77.bean definition parsing“, ele, ex); 78. 79. finally 80. this.parseState.pop(); 81. 82. return null; 83.