Spring IOC初始化源碼跟蹤小記

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/qq_34560242/article/details/80929853
  • 1、初始化入口 ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[]{configLocation}, true, (ApplicationContext)null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
    // 初始化上下文環境
    super(parent);
    // 保存配置信息到configLocations
    this.setConfigLocations(configLocations);
    if (refresh) {
        // 刷新
        this.refresh();
    }

}
  • 2、AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {  
       synchronized (this.startupShutdownMonitor) {  
           //調用容器準備刷新的方法,獲取 容器的當時時間,同時給容器設置同步標識  
           prepareRefresh();  
           //告訴子類啓動refreshBeanFactory()方法,Bean定義資源文件的載入從子類的refreshBeanFactory()方法啓動
           ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
           //爲BeanFactory配置容器特性,例如類加載器、事件處理器等  
           prepareBeanFactory(beanFactory);  
           try {  
               //爲容器的某些子類指定特殊的BeanPost事件處理器  
               postProcessBeanFactory(beanFactory);  
               //調用所有註冊的BeanFactoryPostProcessor的Bean  
               invokeBeanFactoryPostProcessors(beanFactory);  
               //爲BeanFactory註冊BeanPost事件處理器.  
               //BeanPostProcessor是Bean後置處理器,用於監聽容器觸發的事件  
               registerBeanPostProcessors(beanFactory);  
               //初始化信息源,和國際化相關.  
               initMessageSource();  
               //初始化容器事件傳播器.  
               initApplicationEventMulticaster();  
               //調用子類的某些特殊Bean初始化方法  
               onRefresh();  
               //爲事件傳播器註冊事件監聽器.  
               registerListeners();  
               //初始化所有剩餘的單態Bean.  
               finishBeanFactoryInitialization(beanFactory);  
               //初始化容器的生命週期事件處理器,併發布容器的生命週期事件  
               finishRefresh();  
           }  
           catch (BeansException ex) {  
               //銷燬以創建的單態Bean  
               destroyBeans();  
               //取消refresh操作,重置容器的同步標識.  
               cancelRefresh(ex);  
               throw ex;  
           }  
       }  
   }
  • 3、AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新BeanFactory
    this.refreshBeanFactory();
    // 獲取BeanFactory
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
    }

    return beanFactory;
}
  • 4、AbstractRefreshableApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
    // 保證是一個全新的BeanFactory
    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);
    }
}
  • 5、AbstractXmlApplicationContext#loadBeanDefinitions
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 爲給定的BeanFactory創建一個新的XmlBeanDefinitionReader
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    // 初始化XmlBeanDefinitionReader
    this.initBeanDefinitionReader(beanDefinitionReader);
    // 加載BeanDefinition
    this.loadBeanDefinitions(beanDefinitionReader);
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
    String[] configLocations = this.getConfigLocations();
    if (configLocations != null) {
        String[] arr$ = configLocations;
        int len$ = configLocations.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            String configLocation = arr$[i$];
            // XmlBeanDefinitionReader根據配置信息加載BeanDefinition
            reader.loadBeanDefinitions(configLocation);
        }
    }

}
  • 6、AbstractBeanDefinitionReader#loadBeanDefinitions()
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return this.loadBeanDefinitions(location, (Set)null);
}

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = this.getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    } else {
        // ... ...
        } else {
            try {
                Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                // 這裏
                loadCount = this.loadBeanDefinitions(resources);
                // ... ...
            } catch (IOException var10) {
                throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);
            }
        }
    }
}
  • 7、XmlBeanDefinitionReader#loadBeanDefinitions
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return this.loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    // ... ...
    if (!((Set)currentResources).add(encodedResource)) {
        // ... ...
    } else {
        int var5;
        try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                // ... ...
                // 這裏呀
                var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            } finally {
                inputStream.close();
            }
        } catch (IOException var15) {
            // ... ...
        } finally {
            // ... ...
        }
        return var5;
    }
}

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
    try {
        int validationMode = this.getValidationModeForResource(resource);
        Document doc = this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, validationMode, this.isNamespaceAware());
        // 註冊
        return this.registerBeanDefinitions(doc, resource);
    } catch (Throwable var10) {
        // catchs ... ...
    }
}

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

    BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
    documentReader.setEnvironment(this.getEnvironment());
    int countBefore = this.getRegistry().getBeanDefinitionCount();
    // 準備解析
    documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
    return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
  • 8、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions()
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
     // ... ...
     this.doRegisterBeanDefinitions(root);
 }

protected void doRegisterBeanDefinitions(Element root) {
    String profileSpec = root.getAttribute("profile");
    if (StringUtils.hasText(profileSpec)) {
        Assert.state(this.environment != null, "environment property must not be null");
        String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
        if (!this.environment.acceptsProfiles(specifiedProfiles)) {
            return;
        }
    }

    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = this.createHelper(this.readerContext, root, parent);
    this.preProcessXml(root);
    // 解析
    this.parseBeanDefinitions(root, this.delegate);
    this.postProcessXml(root);
    this.delegate = parent;
}

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)) {
                    // 在這
                    this.parseDefaultElement(ele, delegate);
                } else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    } else {
        delegate.parseCustomElement(root);
    }
}

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")) {
        // 這裏
        this.processBeanDefinition(ele, delegate);
    } else if (delegate.nodeNameEquals(ele, "beans")) {
        this.doRegisterBeanDefinitions(ele);
    }

}

// 最終的解析和註冊
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析:將XML的元素解析爲BeanDefinition,保存到BeanDefinitionHolder
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 註冊:通過BeanDefinitionHolder將BeanDefinition進行註冊
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
        } catch (BeanDefinitionStoreException var5) {
            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
        }

        this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }

}
  • 9、解析過程 BeanDefinitionParserDelegate#parseBeanDefinitionElement()
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return this.parseBeanDefinitionElement(ele, (BeanDefinition)null);
}

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 繼續
    AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
    // ... ...
}

// 解析元素
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
    // ... ...
    try {
        String parent = null;
        if (ele.hasAttribute("parent")) {
            parent = ele.getAttribute("parent");
        }
        // 創建beanDefinition
        AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
        // 解析屬性
        this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
        this.parseMetaElements(ele, bd);
        this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
        // 解析Constructor
        this.parseConstructorArgElements(ele, bd);
        // 解析Property
        this.parsePropertyElements(ele, bd);
        this.parseQualifierElements(ele, bd);
        bd.setResource(this.readerContext.getResource());
        bd.setSource(this.extractSource(ele));
        AbstractBeanDefinition var7 = bd;
        return var7;
    } catch (ClassNotFoundException var13) {
        // ... ...
    }
    return null;
}

// 解析Property
public void parsePropertyElement(Element ele, BeanDefinition bd) {
    String propertyName = ele.getAttribute("name");
    if (!StringUtils.hasLength(propertyName)) {
        this.error("Tag 'property' must have a 'name' attribute", ele);
    } else {
        this.parseState.push(new PropertyEntry(propertyName));

        try {
            if (!bd.getPropertyValues().contains(propertyName)) {
                // 解析Property value
                Object val = this.parsePropertyValue(ele, bd, propertyName);
                PropertyValue pv = new PropertyValue(propertyName, val);
                this.parseMetaElements(ele, pv);
                pv.setSource(this.extractSource(ele));
                bd.getPropertyValues().addPropertyValue(pv);
                return;
            }

            this.error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
        } finally {
            this.parseState.pop();
        }

    }
}

// 具體解析Property value
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
    // ... ...
    // 處理引用
    if (hasRefAttribute) {
        String refName = ele.getAttribute("ref");
        if (!StringUtils.hasText(refName)) {
            this.error(elementName + " contains empty 'ref' attribute", ele);
        }

        RuntimeBeanReference ref = new RuntimeBeanReference(refName);
        ref.setSource(this.extractSource(ele));
        return ref;
    // 處理值
    } else if (hasValueAttribute) {
        TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute("value"));
        valueHolder.setSource(this.extractSource(ele));
        return valueHolder;
    // 處理其它子類型, 如:array list set map等
    } else if (subElement != null) {
        return this.parsePropertySubElement(subElement, bd);
    } else {
        this.error(elementName + " must specify a ref or value", ele);
        return null;
    }
}
  • 10、註冊:BeanDefinitionReaderUtils.registerBeanDefinition()
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    String beanName = definitionHolder.getBeanName();
    // 看重點
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        // ... ...
    }
}
  • 11、DefaultListableBeanFactory#registerBeanDefinition

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap();

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
    // ... ...
    if (beanDefinition instanceof AbstractBeanDefinition) {
        // ... ...
    }

    Map var3 = this.beanDefinitionMap;
    synchronized(this.beanDefinitionMap) {
        Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            // ... ...
        } else {
            // ... ...
        }
        // 實質:以beanName爲key, beanDefinition爲value, 把BeanDefinition的實例put進BeanFactory中
        this.beanDefinitionMap.put(beanName, beanDefinition);
        this.resetBeanDefinition(beanName);
    }
}

引用這篇文章的總結:https://blog.csdn.net/yujin753/article/details/47065211

總結:

1、setConfigLocations方法

2、初始化的入口在容器實現中的 refresh()調用來完成

3、AbstractRefreshableApplicationContext實現的 refreshBeanFactory()方法

4、創建DefaultListableBeanFactory,並調用loadBeanDefinitions(beanFactory)裝載bean定義

5、轉到XmlBeanDefinitionReader中的loadBeanDefinitions。

6、XmlBeanDefinitionReader通過調用其父類DefaultResourceLoader的getResource方法獲取要加載的資源

7 、DocumentLoader將Bean定義資源轉換成Document對象

8、doLoadBeanDefinitions中進入registerBeanDefinitions 解析Document對象

9、DefaultListableBeanFactory中使用一個HashMap的集合對象存放IoC容器中註冊解析的BeanDefinition

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章