2.3.2 BeanDefinition的載入和解析(2).docx_第1頁
2.3.2 BeanDefinition的載入和解析(2).docx_第2頁
2.3.2 BeanDefinition的載入和解析(2).docx_第3頁
2.3.2 BeanDefinition的載入和解析(2).docx_第4頁
2.3.2 BeanDefinition的載入和解析(2).docx_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

接著就是loadBeanDefinitions調(diào)用的地方,首先得到BeanDefinition信息的Resource定位,然后直接調(diào)用XmlBeanDefinitionReader讀取,具體的載入過程是委托給BeanDefinitionReader完成的。因為這里的BeanDefinition是通過XML文件定義的,所以這里使用XmlBeanDefinitionReader來載入BeanDefinition到容器中,如代碼清單2-11所示。代碼清單2-11 XmlBeanDefinitionReader載入XmlBeanDefinitionReader1. protectedvoidloadBeanDefinitions 2. (XmlBeanDefinitionReaderreader)throws 3. BeansException,IOException 4. ResourceconfigResources=getConfigResources(); 5. if(configResources!=null) 6. reader.loadBeanDefinitions(configResources); 7. 8. StringconfigLocations=getConfigLocations(); 9. if(configLocations!=null) 10. reader.loadBeanDefinitions(configLocations); 11. 12. 13. protectedResourcegetConfigResources() 14. returnnull; 15. 16. 通過以上實現(xiàn)原理的分析,我們可以看到,在初始化FileSystmXmlApplicationContext的過程中,是通過調(diào)用IoC容器的refresh來啟動整個BeanDefinition的載入過程的,這個初始化是通過定義的XmlBeanDefinitionReader來完成的。同時,我們也知道實際使用的IoC容器是DefultListableBeanFactory,具體的Resource載入在XmlBeanDefinitionReader讀入BeanDefinition時實現(xiàn)。因為Spring可以對應不同形式的BeanDefinition。由于這里使用的是XML方式的定義,所以需要使用XmlBeanDefinitionReader。如果使用了其他的BeanDefinition方式,就需要使用其他種類的BeanDefinitionReader來完成數(shù)據(jù)的載入工作。在XmlBeanDefinitionReader的實現(xiàn)中可以看到,是在reader.loadBeanDefinitions中開始進行BeanDefinition的載入的,而這時XmlBeanDefinitionReader的父類AbstractBeanDefinitionReader已經(jīng)為BeanDefinition的載入做好了準備,如代碼清單2-12所示。代碼清單2-12 AbstractBeanDefinitionReader載入BeanDefinitions1. publicintloadBeanDefinitions(Resourceresources)throws 2. BeanDefinitionStoreException 3. /如果Resource為空,則停止BeanDefinition的載入。 4. /* 5. *然后啟動載入BeanDefinition的過程, 6. 這個過程會遍歷整個Resource集合所包含的 7. *BeanDefinition信息。 8. */9. Assert.notNull(resources,Resourcearraymustnotbenull); 10. intcounter=0; 11. for(inti=0;iresources.length;i+) 12. counter+=loadBeanDefinitions(resourcesi); 13. 14. returncounter; 15. 這里調(diào)用的是loadBeanDefinitions(Resource res)方法,然而這個方法在AbstractBeanDefinitionReader類里是沒有實現(xiàn)的,它是一個接口方法,具體的實現(xiàn)在XmlBeanDefinitionReader中。在讀取器中,需要得到代表XML文件的Resource,因為這個Resource對象封裝了對XML文件的IO操作,所以讀取器可以在打開IO流后得到XML的文件對象。有了這個Document對象以后,就可以按照Spring的Bean定義規(guī)則來對這個XML的文檔樹進行解析了,這個解析是交給BeanDefinitionParserDelegate來完成的,看起來實現(xiàn)脈絡很清楚。具體可以參考代碼實現(xiàn),如代碼清單2-13所示。代碼清單2-13 對BeanDefinition的載入實現(xiàn)1. /這里是調(diào)用的入口。 2. publicintloadBeanDefinitions(Resourceresource)throws3. BeanDefinitionStoreException 4. returnloadBeanDefinitions(new5. EncodedResource(resource); 6. 7. /這里是載入XML形式的BeanDefinition的地方。 8. publicintloadBeanDefinitions(EncodedResource 9. encodedResource)throws10. BeanDefinitionStoreException 11. Assert.notNull(encodedResource,EncodedResource 12. mustnotbenull); 13. if(logger.isInfoEnabled() 14. (LoadingXMLbeandefinitions 15. from+encodedResource. 16. getResource(); 17. 18. SetcurrentResources= 19. this.resourcesCurrentlyBeingLoaded. 20. get(); 21. if(currentResources=null) 22. currentResources=new23. HashSet(4); 24. 25. this.resourcesCurrentlyBeingLoaded.set(currentResources); 26. 27. if(!currentResources.add(encodedResource) 28. thrownewBeanDefinitionStoreException( 29. Detectedrecursiveloading 30. of+encodedResource+-check 31. yourimportdefinitions!); 32. 33. /這里得到XML文件,并得到IO的InputSource準備進行讀取 34. 。 35. try 36. InputStreaminputStream= 37. encodedResource.getResource().getInputStream(); 38. try 39. InputSourceinputSource=new40. InputSource(inputStream); 41. if(encodedResource.getEncoding()!= 42. null) 43. 44. inputSource.setEncoding(encodedResource.getEncoding(); 45. 46. return47. doLoadBeanDefinitions(inputSource, 48. encodedResource.getResource(); 49. 50. finally 51. inputStream.close(); 52. 53. 54. catch(IOExceptionex) 55. thrownewBeanDefinitionStoreException( 56. IOExceptionparsingXML 57. documentfrom+encodedResource. 58. getResource(),ex); 59. 60. finally 61. currentResources.remove(encodedResource); 62. if(currentResources.isEmpty() 63. 64. this.resourcesCurrentlyBeingLoaded.set(null); 65. 66. 67. 68. /具體的讀取過程可以在doLoadBeanDefinitions方法中找到。 69. /這是從特定的XML文件中實際載入BeanDefinition的地方。 70. protectedintdoLoadBeanDefinitions(InputSourceinputSource, 71. Resourceresource) 72. throwsBeanDefinitionStoreException 73. try 74. intvalidationMode= 75. getValidationModeForResource(resource); 76. /* 77. 78. *這里取得XML文件的Document對象,這個解析過程是由 79. documentLoader完成的, 80. 81. *這個documentLoader是DefaultDocumentLoader,在定義documentLoa 82. der的地方創(chuàng)建。 83. */84. Documentdoc= 85. this.documentLoader.loadDocument( 86. inputSource, 87. getEntityResolver(),this.errorHandler,validationMode, 88. isNamespaceAware(); 89. /* 90. 91. *這里啟動的是對BeanDefinition解析的詳細過程,這個解析會使用 92. 到Spring的Bean 93. *配置規(guī)則,是我們下面需要詳細關注的地方。 94. */95. returnregisterBeanDefinitions(doc, 96. resource); 97. 98. catch(BeanDefinitionStoreExceptionex) 99. throwex; 100. 101. catch(SAXParseExceptionex) 102. thrownew103. XmlBeanDefinitionStoreException(resource.getDescription(), 104. Line+ex.getLineNumber() 105. +inXMLdocumentfrom+ 106. resource+isinvalid,ex); 107. 108. catch(SAXExceptionex) 109. thrownew110. XmlBeanDefinitionStoreException(resource.getDescription(), 111. XMLdocumentfrom+ 112. resource+isinvalid,ex); 113. 114. catch(ParserConfigurationExceptionex) 115. thrownew116. BeanDefinitionStoreException(resource.getDescription(), 117. Parserconfiguration 118. exceptionparsingXMLfrom+resource, 119. ex); 120. 121. catch(IOExceptionex) 122. thrownew123. BeanDefinitionStoreException(resource.getDescription(), 124. IOExceptionparsingXML 125. documentfrom+resource,ex); 126. 127. catch(Throwableex) 128. thrownew129. BeanDefinitionStoreException(resource.getDescription(), 130. Unexpectedexception 131. parsingXMLdocumentfrom+resource, 132. ex); 133. 134. 感興趣的讀者,可以到DefaultDocumentLoader中去看看是怎樣得到Document對象的,這里就不詳細分析了。我們關心的是Spring的BeanDefinion是怎樣按照Spring的Bean語義要求進行解析并轉化為容器內(nèi)部數(shù)據(jù)結構的,這個過程是在registerBeanDefinitions (doc, resource)中完成的。具體的過程是由BeanDefinitionDocumentReader來完成的,這個registerBeanDefinition還對載入的Bean的數(shù)量進行了統(tǒng)計。具體的過程如代碼清單2-14所示。代碼清單2-14 registerBeanDefinition的代碼實現(xiàn)1. publicintregisterBeanDefinitions(Documentdoc,Resource 2. resource)throws3. BeanDefinitionStoreException 4. /Readdocumentbasedonnew 5. BeanDefinitionDocumentReaderSPI. 6. /這里得到 7. BeanDefinitionDocumentReader來對xml的BeanDefinition進行解析 8. 。 9. BeanDefinitionDocumentReaderdocumentReader= 10. createBeanDefinitionDocumentReader(); 11. intcountBefore= 12. getRegistry().getBeanDefinitionCount(); 13. / 14. 具體的解析過程在這個registerBeanDefinitions中完成。 15. documentReader.registerBeanDefinitions(doc, 16. createReaderContext(resource); 17. returngetRegistry().getBeanDefinitionCount()- 18. countBefore; 19. BeanDefinition的載入包括兩部分,首先是通過調(diào)用XML的解析器得到document對象,但這些document對象并沒有按照Spring的Bean規(guī)則進行解析。在完成通用的XML解析以后,才是按照Spring的Bean規(guī)則進行解析的地方,按照Spring的Bean規(guī)則進行解析的過程是在documentReader中實現(xiàn)的。這里使用的documentReader是默認設置好的DefaultBeanDe-finitionDocumentReader。這個DefaultBeanDefinitionDocumentReader的創(chuàng)建是在以下的方法里完成的,然后再完成BeanDefinition的處理,處理的結果由BeanDefinition-Holder對象來持有。這個BeanDefinitionHolder除了持有BeanDefinition對象外,還持有了其他與BeanDefinition的使用相關的信息,比如Bean的名字、別名集合等。這個Bean-DefinitionHolder的生成是通過對Document文檔樹的內(nèi)容進行解析來完成的,可以看到這個解析過程是由BeanDefinitionParserDelegate來實現(xiàn)(具體在processBeanDefinition方法中實現(xiàn))的,同時這個解析是與Spring對BeanDefinition的配置規(guī)則緊密相關的。具體的實現(xiàn)原理如代碼清單2-15所示。代碼清單2-15 創(chuàng)建BeanDefinitionDocumentReader1. protectedBeanDefinitionDocumentReader 2. createBeanDefinitionDocumentReader() 3. return4. BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiat 5. eClass 6. (this.documentReaderClass); 7. 8. /這樣,得到了documentReader以后,為具體的Spring 9. Bean的解析過程準備好了數(shù)據(jù)。 10. /* 11. *這里是處理BeanDefinition的地方,具體的處理是委托給 12. BeanDefinitionParserDelegate 13. *來完成的,ele對應于我們的Spring 14. BeanDefinition中定義的xml元素。 15. */16. protectedvoidprocessBeanDefinition(Elementele, 17. BeanDefinitionParserDelegate 18. delegate) 19. /* 20. BeanDefinitionHolder是BeanDefinition對象的封裝類,封裝了Bean 21. Definiti

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論