1. 程式人生 > >Spring原始碼——BeanFactory 註冊bean

Spring原始碼——BeanFactory 註冊bean

XmlBeanFactory
繼承DefaultListableBeanFactory,實現通過XML讀取的方式來獲取Bean的定義。 XmlBeanFactory維護一個XmlbeanDefinitionReader來載入需要的resource解析出的BeanDefinition。 XmlBeanFactory構造方法如下:
  1. /**
  2. * Create a new XmlBeanFactory with the given resource,
  3. * which must be parsable using DOM.
  4. * @param resource XML resource to load bean definitions from
  5. * @throws BeansException in case of loading or parsing errors
  6. */
  7. publicXmlBeanFactory(Resource resource) throws BeansException{
  8. this(resource, null);
  9. }
  10. /**
  11. * Create a new XmlBeanFactory with the given input stream,
  12. * which must be parsable using DOM.
  13. * @param resource XML resource to load bean definitions from
  14. * @param parentBeanFactory parent bean factory
  15. * @throws BeansException in case of loading or parsing errors
  16. */
  17. publicXmlBeanFactory(Resource resource,BeanFactory parentBeanFactory) throws BeansException{
  18. super(parentBeanFactory);
  19. this.reader.loadBeanDefinitions(resource);
  20. }
構造方法,通過reader和resource來載入對應的BeanDefinition。
loadBeanDefinitions
XmlBeanDefinitionReader中的loadBeanDefinition方法,主要載入了對應的Resource和解析Bean做了準備。
  1. /**
  2. * Load bean definitions from the specified XML file.
  3. * @param encodedResource the resource descriptor for the XML file,
  4. * allowing to specify an encoding to use for parsing the file
  5. * @return the number of bean definitions found
  6. * @throws BeanDefinitionStoreException in case of loading or parsing errors
  7. */
  8. publicint loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException{
  9. Assert.notNull(encodedResource,"EncodedResource must not be null");
  10. if(logger.isInfoEnabled()){
  11. logger.info("Loading XML bean definitions from "+ encodedResource.getResource());
  12. }
  13. Set<EncodedResource> currentResources =this.resourcesCurrentlyBeingLoaded.get();
  14. if(currentResources == null){
  15. currentResources =newHashSet<EncodedResource>(4);
  16. this.resourcesCurrentlyBeingLoaded.set(currentResources);
  17. }
  18. if(!currentResources.add(encodedResource)){
  19. thrownewBeanDefinitionStoreException(
  20. "Detected cyclic loading of "+ encodedResource +" - check your import definitions!");
  21. }
  22. try{
  23. InputStream inputStream = encodedResource.getResource().getInputStream();
  24. try{
  25. InputSource inputSource =newInputSource(inputStream);
  26. if(encodedResource.getEncoding()!= null){
  27. inputSource.setEncoding(encodedResource.getEncoding());
  28. }
  29. return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
  30. }
  31. finally {
  32. inputStream.close();
  33. }
  34. }
  35. catch(IOException ex){
  36. thrownewBeanDefinitionStoreException(
  37. "IOException parsing XML document from "+ encodedResource.getResource(), ex);
  38. }
  39. finally {
  40. currentResources.remove(encodedResource);
  41. if(currentResources.isEmpty()){
  42. this.resourcesCurrentlyBeingLoaded.remove();
  43. }
  44. }
  45. }
方法中校驗對應的資原始檔,校驗完成後獲取輸入流,最後在進行Load。
  1. /**
  2. * Actually load bean definitions from the specified XML file.
  3. * @param inputSource the SAX InputSource to read from
  4. * @param resource the resource descriptor for the XML file
  5. * @return the number of bean definitions found
  6. * @throws BeanDefinitionStoreException in case of loading or parsing errors
  7. * @see #doLoadDocument
  8. * @see #registerBeanDefinitions
  9. */
  10. protectedint doLoadBeanDefinitions(InputSource inputSource,Resource resource)
  11. throws BeanDefinitionStoreException{
  12. try{
  13. Document doc = doLoadDocument(inputSource, resource);
  14. return registerBeanDefinitions(doc, resource);
  15. }
  16. catch(BeanDefinitionStoreException ex){
  17. throw ex;
  18. }
  19. catch(SAXParseException ex){
  20. thrownewXmlBeanDefinitionStoreException(resource.getDescription(),
  21. "Line "+ ex.getLineNumber()+" in XML document from "+ resource +" is invalid", ex);
  22. }
  23. catch(SAXException ex){
  24. thrownewXmlBeanDefinitionStoreException(resource.getDescription(),
  25. "XML document from "+ resource +" is invalid", ex);
  26. }
  27. catch(ParserConfigurationException ex){
  28. thrownewBeanDefinitionStoreException(resource.getDescription(),
  29. "Parser configuration exception parsing XML from "+ resource, ex);
  30. }
  31. catch(IOException ex){
  32. thrownewBeanDefinitionStoreException(resource.getDescription(),
  33. "IOException parsing XML document from "+ resource, ex);
  34. }
  35. catch(Throwable ex){
  36. thrownewBeanDefinitionStoreException(resource.getDescription(),
  37. "Unexpected exception parsing XML document from "+ resource, ex);
  38. }
  39. }
獲取對應的Document,然後註冊BeanDefinition.
  1. protectedDocument doLoadDocument(InputSource inputSource,Resource resource) throws Exception{
  2. returnthis.documentLoader.loadDocument(inputSource, getEntityResolver(),this.errorHandler,
  3. getValidationModeForResource(resource), isNamespaceAware());
  4. }
doLoadDocument中會對資原始檔進行校驗。 校驗完成後,註冊。
  1. publicint registerBeanDefinitions(Document doc,Resource resource) throws BeanDefinitionStoreException{
  2. BeanDefinitionDocumentReader documentReader =