springboot-自動(dòng)裝配-源碼解讀解析ImportSelector接口-02

前面我們閱讀到了springboot 通過讀取META-INF/spring.factories 配置文件中的類壁却,并通過ImportSelector 接口返回給spring 容器批狱,達(dá)到 加載Bean 的目的,現(xiàn)在我們來(lái)閱讀spring 部分源碼展东,看看 ImportSelector 接口返回的數(shù)據(jù)在spring 中是如何處理的赔硫。

  • springboot 啟動(dòng)源碼
    為了解決上面這個(gè)問題,我們必須閱讀部分springboot 源碼盐肃,我們可以從啟動(dòng)類開始:
SpringApplication.run(FastCodingApplication.class, args);
  • SpringApplication
/**
     * Static helper that can be used to run a {@link SpringApplication} from the
     * specified source using default settings.
     * @param primarySource the primary source to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link ApplicationContext}
     */
    public static ConfigurableApplicationContext run(Class<?> primarySource,
            String... args) {
        return run(new Class<?>[] { primarySource }, args);
    }

/**
     * Static helper that can be used to run a {@link SpringApplication} from the
     * specified sources using default settings and user supplied arguments.
     * @param primarySources the primary sources to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link ApplicationContext}
     */
    public static ConfigurableApplicationContext run(Class<?>[] primarySources,
            String[] args) {
        return new SpringApplication(primarySources).run(args);
    }

/**    啟動(dòng)爪膊,最后會(huì)到這個(gè)方法
     * Run the Spring application, creating and refreshing a new
     * {@link ApplicationContext}.
     * @param args the application arguments (usually passed from a Java main method)
     * @return a running {@link ApplicationContext}
     */
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            refreshContext(context); // 前面的我們暫時(shí)不管权悟,不是本次的重點(diǎn)务蝠,從這個(gè)方法進(jìn)去
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }
  • refreshContext(context);
private void refreshContext(ConfigurableApplicationContext context) {
        refresh(context); // 繼續(xù)進(jìn)去
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
    }
  • refresh(context);
/**
     * Refresh the underlying {@link ApplicationContext}.
     * @param applicationContext the application context to refresh
     */
    protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext) applicationContext).refresh(); // 進(jìn)去這里
    }

// ((AbstractApplicationContext) applicationContext).refresh();

  • AbstractApplicationContext
    // 如果你以前閱讀過spring的源碼的話弱卡,一點(diǎn)很熟悉這個(gè)方法,當(dāng)然抛姑,如果沒有閱讀過耘成,也沒有關(guān)系榔昔,我們不需要每個(gè)方法的知道是干啥,我們只關(guān)心這里有沒有方法是和我們問題有關(guān)的:加載ImportSelector 接口返回的 Bean 瘪菌。
      @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 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();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撒会,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子师妙,更是在濱河造成了極大的恐慌诵肛,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件默穴,死亡現(xiàn)場(chǎng)離奇詭異怔檩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壁顶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門珠洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人若专,你說我怎么就攤上這事许蓖。” “怎么了调衰?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵膊爪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我嚎莉,道長(zhǎng)米酬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任趋箩,我火速辦了婚禮赃额,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叫确。我一直安慰自己跳芳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布竹勉。 她就那樣靜靜地躺著飞盆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吓歇,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天孽水,我揣著相機(jī)與錄音,去河邊找鬼城看。 笑死女气,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的析命。 我是一名探鬼主播主卫,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鹃愤!你這毒婦竟也來(lái)了簇搅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤软吐,失蹤者是張志新(化名)和其女友劉穎瘩将,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凹耙,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姿现,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肖抱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片备典。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖意述,靈堂內(nèi)的尸體忽然破棺而出提佣,到底是詐尸還是另有隱情,我是刑警寧澤荤崇,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布拌屏,位于F島的核電站,受9級(jí)特大地震影響术荤,放射性物質(zhì)發(fā)生泄漏倚喂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一瓣戚、第九天 我趴在偏房一處隱蔽的房頂上張望端圈。 院中可真熱鬧,春花似錦子库、人聲如沸枫笛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至喧兄,卻和暖如春无畔,著一層夾襖步出監(jiān)牢的瞬間啊楚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工浑彰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恭理,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓郭变,卻偏偏與公主長(zhǎng)得像颜价,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诉濒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344