Spring源码分析之一:容器始化

这里只讲一下主线。初始化容器。整理了一小天,比较乱。先对付看。求鼓励:

IOC容器,初始化

ApplicationContext ctx = newFileSystemXmlApplicationContext(“classpath:bean.xml”);

首先去加载 xml文件中写义的类,但是如何加载的呢?

跟踪进入FileSystemXmlApplicationContext.java类中的

public FileSystemXmlApplicationContext(StringconfigLocation) throwsBeansException {

      this(new String[]{configLocation}, true, null);

   }

继续跟踪

public FileSystemXmlApplicationContext(String[]configLocations, boolean refresh, ApplicationContext parent)

         throws BeansException {

 

      super(parent);

      setConfigLocations(configLocations);

      if (refresh) {

         refresh();//此外为关键,ioc其实在此方法中完成。

      }

   }

继续跟踪AbstractApplicationContext.java类中的方法

publicvoidrefresh() throws BeansException,IllegalStateException {

      synchronized (this.startupShutdownMonitor){

         // Prepare this context for refreshing.

         prepareRefresh();

 

         // Tell the subclass to refresh the internal beanfactory.

//子类中启动refreshBeanFactory()的地方

         ConfigurableListableBeanFactorybeanFactory = obtainFreshBeanFactory();

 

         // Prepare the bean factory for use in this context.

         prepareBeanFactory(beanFactory);

 

         try {

            // Allows post-processing of the bean factory in contextsubclasses.

            postProcessBeanFactory(beanFactory);

 

            // Invoke factory processors registered as beans in thecontext.

            invokeBeanFactoryPostProcessors(beanFactory);

 

            // Register bean processors that intercept bean creation.

            registerBeanPostProcessors(beanFactory);

 

            // Initialize message source for this context.

            initMessageSource();

 

            // Initialize event multicaster for this context.

            initApplicationEventMulticaster();

 

            // Initialize other special beans in specific contextsubclasses.

            onRefresh();

 

            // Check for listener beans and register them.

            registerListeners();

 

            // Instantiate all remaining (non-lazy-init) singletons.

            finishBeanFactoryInitialization(beanFactory);

 

            // Last step: publish corresponding event.

            finishRefresh();

         }

 

         catch (BeansException ex) {

            // Destroy already created singletons to avoid danglingresources.

            destroyBeans();

 

            // Reset ‘active’ flag.

            cancelRefresh(ex);

 

            // Propagate exception to caller.

            throw ex;

         }

      }

   }

继续跟踪AbstractRefreshableApplicationContext.java类中的

protectedfinalvoidrefreshBeanFactory()throwsBeansException {

      if (hasBeanFactory()) {

         destroyBeans();

         closeBeanFactory();

      }

      try {

//创建IOC容器,使用的是DefaultListableBeanFactory

         DefaultListableBeanFactorybeanFactory = createBeanFactory();

         beanFactory.setSerializationId(getId());

         customizeBeanFactory(beanFactory);

//启动对BeanDefinition的载入       

loadBeanDefinitions(beanFactory);

         synchronized (this.beanFactoryMonitor){

            this.beanFactory = beanFactory;

         }

      }

      catch (IOException ex) {

         thrownew ApplicationContextException(“I/O error parsing bean definition source for “ + getDisplayName(), ex);

      }

   }

继续跟踪AbstractXmlApplicationContext.java类中的

此方法的作用是读xml文件中的类,并进行载入

protectedvoidloadBeanDefinitions(DefaultListableBeanFactorybeanFactory) throwsBeansException, IOException {

      // Create a new XmlBeanDefinitionReader for the givenBeanFactory.

      XmlBeanDefinitionReaderbeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

 

      // Configure the bean definition reader with thiscontext’s

      // resource loading environment.

      beanDefinitionReader.setResourceLoader(this);

      beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

 

      // Allow a subclass to provide custom initialization ofthe reader,

      // then proceed with actually loading the beandefinitions.

//启动bean定义信息载入的过程

      initBeanDefinitionReader(beanDefinitionReader);

      loadBeanDefinitions(beanDefinitionReader);

   }

protectedvoidloadBeanDefinitions(XmlBeanDefinitionReaderreader) throwsBeansException, IOException {

      Resource[]configResources = getConfigResources();

      if (configResources != null) {

         reader.loadBeanDefinitions(configResources);

      }

      String[]configLocations = getConfigLocations();

      if (configLocations != null) {

         reader.loadBeanDefinitions(configLocations);

      }

   }

XmlBeanDefinitionReader.java类中的

publicintloadBeanDefinitions(EncodedResource encodedResource) throwsBeanDefinitionStoreException {

      Assert.notNull(encodedResource,“EncodedResource must not benull”);

      if (logger.isInfoEnabled()) {

         logger.info(“Loading XML bean definitions from “ + encodedResource.getResource());

      }

 

      Set<EncodedResource>currentResources = this.resourcesCurrentlyBeingLoaded.get();

      if (currentResources == null) {

         currentResources= newHashSet<EncodedResource>(4);

         this.resourcesCurrentlyBeingLoaded.set(currentResources);

      }

      if(!currentResources.add(encodedResource)) {

         thrownewBeanDefinitionStoreException(

                “Detected cyclic loading of “ + encodedResource + ” – check yourimport definitions!”);

      }

//这里得到xml文件、并得到IOInputSource准备进行读取

      try {

         InputStreaminputStream = encodedResource.getResource().getInputStream();

         try {

            InputSourceinputSource = newInputSource(inputStream);

            if(encodedResource.getEncoding() != null) {

                inputSource.setEncoding(encodedResource.getEncoding());

            }

            return doLoadBeanDefinitions(inputSource,encodedResource.getResource());

         }

         finally {

            inputStream.close();

         }

      }

      catch (IOException ex) {

         thrownewBeanDefinitionStoreException(

                “IOException parsing XML document from “ + encodedResource.getResource(), ex);

      }

      finally {

         currentResources.remove(encodedResource);

         if(currentResources.isEmpty()) {

            this.resourcesCurrentlyBeingLoaded.remove();

         }

      }

   }

 

//取得xml文件,实际载入BeanDefinitions的地方       

protectedintdoLoadBeanDefinitions(InputSource inputSource, Resource resource)

         throwsBeanDefinitionStoreException {

      try {

         int validationMode =getValidationModeForResource(resource);

Document doc = this.documentLoader.loadDocument(

                inputSource,getEntityResolver(), this.errorHandler,validationMode, isNamespaceAware());

//BeanDefinition的解析过程。        

return registerBeanDefinitions(doc,resource);

      }

      catch(BeanDefinitionStoreException ex) {

         throw ex;

      }

      catch (SAXParseException ex){

         thrownewXmlBeanDefinitionStoreException(resource.getDescription(),

                “Line “+ ex.getLineNumber() + ” in XML documentfrom “ + resource + ” is invalid”, ex);

      }

      catch (SAXException ex) {

         thrownewXmlBeanDefinitionStoreException(resource.getDescription(),

                “XML document from “+ resource + ” is invalid”, ex);

      }

      catch(ParserConfigurationException ex) {

         thrownewBeanDefinitionStoreException(resource.getDescription(),

                “Parser configuration exception parsing XML from” + resource, ex);

      }

      catch (IOException ex) {

         thrownewBeanDefinitionStoreException(resource.getDescription(),

                “IOException parsing XML document from “ + resource, ex);

      }

      catch (Throwable ex) {

         thrownewBeanDefinitionStoreException(resource.getDescription(),

                “Unexpected exception parsing XML document from” + resource, ex);

      }

   }

 

publicintregisterBeanDefinitions(Documentdoc, Resource resource) throws BeanDefinitionStoreException {

      // Read document based on newBeanDefinitionDocumentReader SPI.

//这里得到 BeanDefinitionDocumentReader来对XMLBeanDefinition进行解析   

BeanDefinitionDocumentReaderdocumentReader = createBeanDefinitionDocumentReader();

      int countBefore =getRegistry().getBeanDefinitionCount();

//具体的解析过程在registerBeanDefinitions中完成 

documentReader.registerBeanDefinitions(doc,createReaderContext(resource));

      return getRegistry().getBeanDefinitionCount()- countBefore;

   }

继续跟踪DefaultBeanDefinitionDocumentReader.java类中的

publicvoidregisterBeanDefinitions(Documentdoc, XmlReaderContext readerContext) {

      this.readerContext = readerContext;

 

      logger.debug(“Loading bean definitions”);

      Elementroot = doc.getDocumentElement();

 

      BeanDefinitionParserDelegatedelegate = createHelper(readerContext, root);

 

      preProcessXml(root);

//交给BeanDefinitionParserDelegate来处理

      parseBeanDefinitions(root,delegate);

      postProcessXml(root);

   }

 

protectedvoidparseBeanDefinitions(Elementroot, BeanDefinitionParserDelegate delegate) {

      if(delegate.isDefaultNamespace(root)) {

         NodeListnl = root.getChildNodes();

         for (int i = 0; i <nl.getLength(); i++) {

            Nodenode = nl.item(i);

            if (node instanceof Element) {

                Elementele = (Element) node;

                if(delegate.isDefaultNamespace(ele)) {

//跟踪               

parseDefaultElement(ele, delegate);

                }

                else {

                   delegate.parseCustomElement(ele);

                }

            }

         }

      }

      else {

         delegate.parseCustomElement(root);

      }

   }

 

privatevoidparseDefaultElement(Elementele, BeanDefinitionParserDelegate delegate) {

      if(delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {

         importBeanDefinitionResource(ele);

      }

      elseif(delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {

         processAliasRegistration(ele);

      }

      elseif(delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {

//跟踪      

processBeanDefinition(ele,delegate);

      }

   }

//处理BeanDefinition的地方

protectedvoidprocessBeanDefinition(Elementele, BeanDefinitionParserDelegate delegate) {

      BeanDefinitionHolderbdHolder = delegate.parseBeanDefinitionElement(ele);

      if (bdHolder != null) {

         bdHolder= delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

         try {

            // Register the final decorated instance.这里向ioc容器注册解析得到的BeanDefinition

            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(newBeanComponentDefinition(bdHolder));

      }

   }

BeanDefinitionReaderUtils.java

publicstaticvoidregisterBeanDefinition(

         BeanDefinitionHolderdefinitionHolder, BeanDefinitionRegistry registry)

         throws BeanDefinitionStoreException{

 

      // Register bean definition under primary name.

      StringbeanName = definitionHolder.getBeanName();

//进行注册

      registry.registerBeanDefinition(beanName,definitionHolder.getBeanDefinition());

 

      // Register aliases for bean name, if any.

      String[] aliases =definitionHolder.getAliases();

      if (aliases != null) {

         for (String aliase :aliases) {

            registry.registerAlias(beanName,aliase);

         }

      }

   }

 

DefaultListableBeanFactory.java类中

publicvoidregisterBeanDefinition(String beanName, BeanDefinition beanDefinition)

         throwsBeanDefinitionStoreException {

 

      Assert.hasText(beanName,“Bean name must not be empty”);

      Assert.notNull(beanDefinition,“BeanDefinition must not be null”);

 

      if (beanDefinition instanceofAbstractBeanDefinition) {

         try {

            ((AbstractBeanDefinition)beanDefinition).validate();

         }

         catch(BeanDefinitionValidationException ex) {

            thrownewBeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,

                   “Validation of bean definition failed”, ex);

         }

      }

 

      synchronized (this.beanDefinitionMap){

         ObjectoldBeanDefinition =this.beanDefinitionMap.get(beanName);

         if (oldBeanDefinition != null) {

            if (!this.allowBeanDefinitionOverriding){

                thrownewBeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,

                      “Cannot register bean definition [“ + beanDefinition + “] for bean'” + beanName +

                      “‘: There is already [“+ oldBeanDefinition+ “] bound.”);

            }

            else {

                if (this.logger.isInfoEnabled()) {

                   this.logger.info(“Overriding bean definition for bean ‘” + beanName +

                         “‘: replacing [“+ oldBeanDefinition+ “] with [“ + beanDefinition + “]”);

                }

            }

         }

         else {

            this.beanDefinitionNames.add(beanName);

            this.frozenBeanDefinitionNames= null;

         }

//放到ioc容器,ioc容器底层是一个map        

this.beanDefinitionMap.put(beanName,beanDefinition);

 

         resetBeanDefinition(beanName);

      }

讲到这里,大家对流程比较清楚,到bean是哪里生成实例的呢?

我们回过头来看这个方法

//处理BeanDefinition的地方

protectedvoidprocessBeanDefinition(Elementele, BeanDefinitionParserDelegate delegate) {

 

/* BeanDefinitionHolder BeanDefinition对象的封装类,封装了BeanDefinitionBean的名子和别名。用它来完成向IoC容器注册。得到了这个BeanDefinitionHolder就意味着BeanDefinition是通过BeanDefinitionParserDelegatexml元素的信息按照SpringBean规则进行解析得到的。*/

BeanDefinitionHolder bdHolder =delegate.parseBeanDefinitionElement(ele);//完成了bean的实例化。

     

 

if (bdHolder != null) {

         bdHolder= delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

         try {

            // Register the final decorated instance.这里向ioc容器注册解析得到的BeanDefinition

            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(newBeanComponentDefinition(bdHolder));

      }

   }

 

跟踪进入:

BeanDefinitionParserDelegate.java类中

   public BeanDefinitionHolder parseBeanDefinitionElement(Elementele) {

      returnparseBeanDefinitionElement(ele, null);

   }

public BeanDefinitionHolder parseBeanDefinitionElement(Elementele, BeanDefinition containingBean) {

      Stringid = ele.getAttribute(ID_ATTRIBUTE);

      StringnameAttr = ele.getAttribute(NAME_ATTRIBUTE);

 

      List<String>aliases = newArrayList<String>();

      if (StringUtils.hasLength(nameAttr)){

         String[]nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);

         aliases.addAll(Arrays.asList(nameArr));

      }

 

      StringbeanName = 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) {

         checkNameUniqueness(beanName,aliases, ele);

      }

 

//进行实例化

      AbstractBeanDefinitionbeanDefinition = 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, ifstill possible,

                   // if the generator returned the class name plus asuffix.

                   // This is expected for Spring 1.2/2.0 backwardscompatibility.

                   StringbeanClassName = 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);

                returnnull;

            }

         }

         String[]aliasesArray = StringUtils.toStringArray(aliases);

         returnnewBeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

      }

 

      returnnull;

   }

 

public AbstractBeanDefinition parseBeanDefinitionElement(

         Elementele, String beanName, BeanDefinition containingBean) {

 

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

 

      StringclassName = null;

      if (ele.hasAttribute(CLASS_ATTRIBUTE)){

         className= ele.getAttribute(CLASS_ATTRIBUTE).trim();

      }

 

      try {

         Stringparent = null;

         if (ele.hasAttribute(PARENT_ATTRIBUTE)){

            parent= ele.getAttribute(PARENT_ATTRIBUTE);

         }

//实例化

         AbstractBeanDefinitionbd = createBeanDefinition(className, parent);

 

         parseBeanDefinitionAttributes(ele,beanName, containingBean, bd);

         bd.setDescription(DomUtils.getChildElementValueByTagName(ele,DESCRIPTION_ELEMENT));

 

         parseMetaElements(ele,bd);

         parseLookupOverrideSubElements(ele,bd.getMethodOverrides());

         parseReplacedMethodSubElements(ele,bd.getMethodOverrides());

 

         parseConstructorArgElements(ele,bd);

         parsePropertyElements(ele,bd);

         parseQualifierElements(ele,bd);

 

         bd.setResource(this.readerContext.getResource());

         bd.setSource(extractSource(ele));

 

         return bd;

      }

      catch (ClassNotFoundExceptionex) {

         error(“Bean class [“+ className + “] not found”, ele, ex);

      }

      catch (NoClassDefFoundErrorerr) {

         error(“Class that bean class [“ + className + “] depends on not found”, ele, err);

      }

      catch (Throwable ex) {

         error(“Unexpected failure during bean definitionparsing”, ele, ex);

      }

      finally {

         this.parseState.pop();

      }

 

      returnnull;

   }

 

protected AbstractBeanDefinition createBeanDefinition(StringclassName, String parentName)

         throws ClassNotFoundException{

//工具类实例化

      returnBeanDefinitionReaderUtils.createBeanDefinition(

            parentName,className, this.readerContext.getBeanClassLoader());

   }

 

publicstaticAbstractBeanDefinition createBeanDefinition(

         StringparentName, String className, ClassLoader classLoader) throws ClassNotFoundException{

 

      GenericBeanDefinitionbd = newGenericBeanDefinition();

      bd.setParentName(parentName);

      if (className != null) {

         if (classLoader != null) {

//例用类加载器,进行反射实例化         

bd.setBeanClass(ClassUtils.forName(className,classLoader));

         }

         else {

            bd.setBeanClassName(className);

         }

      }

      return bd;

   }

 

从以上分析可以看出,实例化bean是一个一个对象进行行的。实例化出一个对象,就把这个对象放在ioc容器中。

 

 

 

 

 

    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/jeffzhli/article/details/75232858
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞