Spring源碼分析(一) - 概述以及Bean的創(chuàng)建

應用上下文創(chuàng)建流程概覽

spring1.png

源碼剖析

  1. 創(chuàng)建Spring應用程序上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  1. 進入ClassPathXmlApplicationContext構造函數(shù)
public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

(1)調(diào)用父類構造方法,創(chuàng)建Reslover,解析配置文件
(2)設置配置文件路徑到當前應用程序中
(3)開始調(diào)用refresh(),進行容器的創(chuàng)建

  1. 進入refresh()方法
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                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 context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

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

                // Last step: publish corresponding event.
                finishRefresh();
            }

(1) prepareRefresh:做前期準備

  • 設置容器的啟動時間
  • 設置活躍狀態(tài)為true
  • 設置關閉狀態(tài)為false
  • 獲取Environment對象,并加載當前系統(tǒng)的屬性值到Environment對象中
  • 準備監(jiān)聽器和事件對象的集合

(2) obtainFreshBeanFactory
創(chuàng)建容器并完成配置文件加載

(3) prepareBeanFactory
通過一系列的add, set, ignore, register開頭的方法,給容器對象進行賦值

(4) postProcessBeanFactory: 默認沒有實現(xiàn),留給子類去實現(xiàn)

(5) invokeBeanFactoryPostProcessors
可進行自由擴展,修改BeanFactory的相關信息。比如:ConfigurationClassPostProcessor, PropertySourcePlaceHolderConfigurer

(6) registerBeanPostProcessors
注冊BeanPostProcessor,完成spring自帶的或者用戶自定義的BeanPostProcessor的解析

(7) initMessageSource
進行國際化相關的操作

(8) initApplicationEventMulticaster
初始化事件廣播器

(9) onRefresh: 默認沒有實現(xiàn),由子類去定義

(10) registerListener: 注冊監(jiān)聽器,接收廣播的事件

(11) finishBeanFactoryInitialization:完成對象的實例化操作
從此方法開始進行對象的創(chuàng)建,包含實例化,初始化,循環(huán)依賴,AOP等核心邏輯的處理過程。

(12) finishRefresh
完成整個容器的啟動,所有對象都準備完成。清除上下午緩存,初始化生命周期處理器,并發(fā)送刷新完成事件。

Bean的創(chuàng)建

前面說到了在finishBeanFactoryInitialization()方法中會進行對象的創(chuàng)建。下面來進一步看下Bean是如何創(chuàng)建的:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        // Allow for caching all bean definition metadata, not expecting further changes.
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }

(1)setConversionService:設置類型轉換服務
(2)addEmbeddedValueResolver:設置內(nèi)置的值處理器
(3)freezeConfiguration:凍結BeanDefinition
(4)preInstantiateSingletons(關鍵步驟):
開始對象的實例化:

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }

從容器中獲取所有的BeanDefinitionNames集合,從每個集合中獲取每一個元素,來進行對象的創(chuàng)建。

根據(jù)BeanName來獲取完整的BeanDefinition對象。再通過getBean()來獲取Bean對象,里面調(diào)用的doGetBean()。

這其中涉及到整個Bean的創(chuàng)建,屬性填充,實例化等一些列操作,大致流程如下:


bean.png

這其中涉及到spring對Bean對象的三級緩存,后面會再來詳細說下這個問題。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容