39. finally {
40. currentResources.remove(encodedResource); 41. if (currentResources.isEmpty()) {
42. this.resourcesCurrentlyBeingLoaded.set(null); 43. } 44. } 45. }
46.//具体的读取过程可以在doLoadBeanDefinitions方法中找到: 47. //这是从特定的XML文件中实际载入BeanDefinition的地方 48. protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
49. throws BeanDefinitionStoreException { 50. try {
51. int validationMode = getValidationModeForResource(resource);
52. //这里取得XML文件的Document对象,这个解析过程是由 documentLoader完成的,这个documentLoader是
DefaultDocumentLoader,在定义documentLoader的地方创建 53. Document doc = this.documentLoader.loadDocument( 54. inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
55. //这里启动的是对BeanDefinition解析的详细过程,这个解析会使用到Spring的Bean配置规则,是我们下面需要详细关注的地方。
56. return registerBeanDefinitions(doc, resource); 57. }
58. catch (BeanDefinitionStoreException ex) { 59. throw ex; 60. }
61. catch (SAXParseException ex) {
62. throw new XmlBeanDefinitionStoreException(resource.getDescription(),
63. %ument from \64. }
65. catch (SAXException ex) {
66. throw new XmlBeanDefinitionStoreException(resource.getDescription(),
67. \lid\68. }
69. catch (ParserConfigurationException ex) {
70. throw new BeanDefinitionStoreException(resource.getDescription(),
71. \ from \72. }
73. catch (IOException ex) {
74. throw new BeanDefinitionStoreException(resource.getDescription(),
75. \resource, ex); 76. }
77. catch (Throwable ex) {
78. throw new BeanDefinitionStoreException(resource.getDescription(),
79. \from \
80. } 81. }
关于具体的Spring BeanDefinition的解析,是在
BeanDefinitionParserDelegate中完成的。这个类里包含了各种Spring Bean定义规则的处理,感兴趣的同学可以仔细研究。我们举一个例子来分析这个处理过程,比如我们最熟悉的对Bean元素的处理是怎样完成的,也就是我们 在XML定义文件中出现的
1. public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
2. //这里取得在
3. String id = ele.getAttribute(ID_ATTRIBUTE);
4. String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); 5.
6. List
8. String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
9. aliases.addAll(Arrays.asList(nameArr));
10. } 11.
12. String beanName = id;
13. if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
14. beanName = aliases.remove(0); 15. if (logger.isDebugEnabled()) {
16. logger.debug(\+ beanName +
17. \aliases\18. } 19. } 20.
21. if (containingBean == null) {
22. checkNameUniqueness(beanName, aliases, ele); 23. } 24.
25. //这个方法会引发对bean元素的详细解析
26.AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); 27. if (beanDefinition != null) {
28. if (!StringUtils.hasText(beanName)) { 29. try {
30. if (containingBean != null) {
31. beanName = BeanDefinitionReaderUtils.generateBeanName(
32. beanDefinition, this.readerContext.getRegistry(), true);
33. } 34. else {
35. beanName = this.readerContext.generateBeanName(beanDefinition);
36. // Register an alias for the plain bean class name, if still possible,
37. // if the generator returned the class name plus a suffix.
38. // This is expected for Spring 1.2/2.0 backwards compatibility.
39. String beanClassName = beanDefinition.getBeanClassName();
40. if (beanClassName != null && 41. beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && 42. !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
43. aliases.add(beanClassName); 44. } 45. }
46. if (logger.isDebugEnabled()) {
47. logger.debug(\e' specified - \
48. \ beanName + \49. } 50. }
51. catch (Exception ex) {
52. error(ex.getMessage(), ele);