Spring之IOC容器的加載過程


1.IOC容器的加載

1)Resource定位(容器尋找數據的過程)

2)載入(把用戶定義好的bean表示成IOC容器內部的數據結構即:BeanDefinition)

3)注冊(把載入的BeanDefinition注冊到IOC容器) 

 

 

 

 

1.1Bean的創建 

bean是什么時候創建的?第一次getBean的時候

 

1)檢查bean是否已經存在,根據beanName獲取BeanDefinition,遞歸獲取依賴bean,根據不同屬性的bean調用方法創建bean(如Singleton的,Scope的,Property的)

  doGetBean

2)檢查循環引用,設置bean的屬性

  createBean

3)通過不同的方式創建bean,策略模式,默認SimpleInstantiationStrategy,提供兩種實例化方式,一種是BeanUtils(使用JVM的反射功能),另外一種是Cglib(字節碼生成類庫)

  createBeanInstance

4)屬性注入如@Autowired等

  屬性注入populateBean

 

1.2 實例化Bean的策略

1.Cglib

 

1.3Bean創建流程

 

 

 

 

 

 

 

 

  

 <bean id="testSpringBean" class="com.bkjk.cf.receivablesfinancing.service.TestSpringBean" init-method="init"
          destroy-method="destory">
        <property name="propertyAge" value="343434"/>
        <property name="propertyName" value="zhanfdifjidfj"/>

    </bean>
bean.xml
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }

    }
容器啟動入口
 public void refresh() throws BeansException, IllegalStateException {
         Object var1 = this.startupShutdownMonitor;
         synchronized(this.startupShutdownMonitor) {
             this.prepareRefresh();
             //這里在子類中啟動refreshBeanFactory 的地方
             ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
             this.prepareBeanFactory(beanFactory);
 
             try {
                   // 設置beanFactory的后置處理
                 this.postProcessBeanFactory(beanFactory);
                  //bean注冊容器
                 this.invokeBeanFactoryPostProcessors(beanFactory);
                  //注冊bean的后處理,在bean創建過程中調用
                 this.registerBeanPostProcessors(beanFactory);
                  //對上下文消息進行初始化
                 this.initMessageSource();
                     //初始化上線文的事件機制
                 this.initApplicationEventMulticaster();
                  //初始化其他的特殊的bean
                 this.onRefresh();
                   //檢查監聽bean,並向容器注冊
                 this.registerListeners();
                    //實例化所有的(non-lazy-init)單件
                 this.finishBeanFactoryInitialization(beanFactory);
                   //發布容器時間,結束Refresh過程
                 this.finishRefresh();
             } catch (BeansException var9) {
                 if (this.logger.isWarnEnabled()) {
                     this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                 }
                  //為防止容器占用資源,在異常中銷毀前面已經生成的單件bean
                 this.destroyBeans();
                 //重置‘active’標簽
                 this.cancelRefresh(var9);
                 throw var9;
             } finally {
                 this.resetCommonCaches();
             }
 
         }
     }
refresh()方法
//創建 BeanFactory 並載入BeanDefinition
 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }
 protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
             //創建beanFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            //載入bean入口
             this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }
載入BeanDefinition入口
 //AbstractXmlApplicationContext 
// XmlBeanDefinitionReader 定位resource,XmlBeanDefinitionReader 
  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        this.loadBeanDefinitions(beanDefinitionReader);
    }
定位resource
//IOC 容器加載的核心方法
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
                 try {
                InputStream inputStream = encodedResource.getResource().getInputStream();
                try {
                    //一:讀取xml文件
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }
                     //二:加載 beanefinition
                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } 

            return var5;
        }
    }


protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
             //一 1) 將xml文件轉換為document
            Document doc = this.doLoadDocument(inputSource, resource);
            return this.registerBeanDefinitions(doc, resource);
}
}

           //一 2) 開始執行
  public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        this.logger.debug("Loading bean definitions");
        Element root = doc.getDocumentElement();
        this.doRegisterBeanDefinitions(root);
    }

 protected void doRegisterBeanDefinitions(Element root) {
       
        this.preProcessXml(root);
      //三 解析Element 獲取xml內容
        this.parseBeanDefinitions(root, this.delegate);
        this.postProcessXml(root);
        this.delegate = parent;
    }
    //解析Element 得到node 判斷node內容
 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes(); 
            for(int i = 0; i < nl.getLength(); ++i) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element)node;
                    if (delegate.isDefaultNamespace(ele)) {
                      //讀取document的內容
                        this.parseDefaultElement(ele, delegate);
                    } else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {
            delegate.parseCustomElement(root);
        }

    }

      //四 判斷xml中(document中節點的類型)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        } else if (delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        } else if (delegate.nodeNameEquals(ele, "bean")) {
             /* 五 載入beanDefinition  這里只是讀取<bean>中的設置的class的name, 然后載入到BeanDefinition中,只是做個記錄,並不設計對象的實例化,對象的實例化是在依賴注入時完成的*/
            this.processBeanDefinition(ele, delegate);
        } else if (delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }
          //五 載入BeanDefinition 這里得到documentReader后,為具體的spring bean 解析准備了數據 
protected void processBeanDefinition(Element ele, eanDefinitionParserDelegate delegate) {
              //具體處理了BeanDefinition交給 BeanDefinitionParserDelegate
           /* 具體將<bean>的內容進行解析,解析為spring 的BeanDefinition
           BeanDefinitionHolder是BeanDefinition對象的封裝,封裝了bean的名稱和別 
      名,用他來完成   向IOC容器注冊,得到的BeanDefinitionHolder是通過beanDefinitionParserDelegate 對 XML的元素的信息按照spring 的bean規則進行解析得到的*/
  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); 
       if (bdHolder != null) {  
          bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);  
        try {  
             BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());  
             } catch (BeanDefinitionStoreException var5) {  
             this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);  
             }  
            // BeanDefinition向IOC容器注冊之后,發送消息
            this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));   
              }  
             } 


//載入BeanDefinition 
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        String id = ele.getAttribute("id");
        String nameAttr = ele.getAttribute("name");
        List<String> aliases = new ArrayList();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
            aliases.addAll(Arrays.asList(nameArr));
        }

        String beanName = id;
        if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
            beanName = (String)aliases.remove(0);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            this.checkNameUniqueness(beanName, aliases, ele);
        }
       //將xml的內置轉換為spring的bean信息
        AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
       }


    //對<bean>的內容進行解析,轉換為spring的bean
    public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
        this.parseState.push(new BeanEntry(beanName));
        String className = null;
        if (ele.hasAttribute("class")) {
            className = ele.getAttribute("class").trim();
        }

        String parent = null;
        if (ele.hasAttribute("parent")) {
            parent = ele.getAttribute("parent");
        }

        try {
             //生成需要的BeanDefinition對象,為BeanDefinition的載入做准備
            AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
             //設置<bean>的attribute scope,init,destory 等
            this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
            //設置元數據 如 key ,value這樣的
            this.parseMetaElements(ele, bd);
            this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
              //解析<bean>構造函數 
            this.parseConstructorArgElements(ele, bd);
             //設置<bean>property元素
            this.parsePropertyElements(ele, bd);
            this.parseQualifierElements(ele, bd);
            bd.setResource(this.readerContext.getResource());
            bd.setSource(this.extractSource(ele));
            AbstractBeanDefinition var7 = bd;
            return var7;
        } 
        } finally {
            this.parseState.pop();
        }

        return null;
    }
 
載入BeanDefinition的核心實現
/注冊 BeanDefinition
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        //獲取bean的 名稱
     String beanName = definitionHolder.getBeanName();
       //注冊bean 並將bean放入到ioc容器里面 
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                //注冊其他信息 是否是單例,是否允許重載 是否是abstract 類
                registry.registerAlias(beanName, alias);
            }
        }

    }

//DefaultListableBeanFactory 具體執行注冊的
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
            }
        }
              //bean 已經存在
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
           //不允許覆蓋 報異常
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + existingDefinition + "] bound.");
            }     
            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                Map var4 = this.beanDefinitionMap;
                     //synchronized,保證數據一致性
                synchronized(this.beanDefinitionMap) {
                   //將bean放入容器
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }
        
        if (existingDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }
向IOC容器注冊

 

2.BeanDefinition是什么?

是一個接口,里面定義了一些bean的元數據,如beanName,score等,是對xml中<bean>的抽象

 

3.類圖

 

  

 

 

  

 

 

 4.面試題

BeanFactoryPostProcessor

修改BeanDefinition信息,修改bean的元信息,此時Bean還未初始化

  

  自定義BeanFactoryPostProcessor

MyBeanFactoryPostProcessor

 

BeanPostProcessor

是在Bean創建完成,屬性填充完之后執行的

 

  

initializeBean中調用BeanPostProcessor

自定義BeanPostProcessor

MyBeanPostProcessor

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM