溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java Spring Bean Container的啟動(dòng)加載初始化流程是什么

發(fā)布時(shí)間:2021-11-17 11:44:38 來源:億速云 閱讀:163 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“java Spring Bean Container的啟動(dòng)加載初始化流程是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1. DESC

Spring對(duì)beanFactory的處理

2. CODE

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();
        }
    }
}

3. 從上往下RUSH

3.1 prepareRefresh()

這里不用細(xì)看就是自身進(jìn)行些配置和參數(shù)校驗(yàn)什么的

3.2 obtainFreshBeanFactory()

  1. 加載NameSpacehandler

  2. 使用各個(gè)NameSpcaceHandler生成Beandifinitions并注冊到beanfactory里面去

3.2.1 加載NameSpaceHandler

  1. NameSpaceHandler加載過程的解析已經(jīng)寫過就不再寫了; 參看前面的文章

3.2.2 NameSpaceHandler處理生成bean的定義(注意只是生成beanDefinition而不是生成具體的bean而且相關(guān)的Class文件也沒有加載)

  1. NamespaceHandlerSupport

//返回也沒用,應(yīng)該定義為void的,parserContext的registry就是beanFactory
public BeanDefinition parse(Element element, ParserContext parserContext) {
    //獲取具體的BeanDefinitionParser,比如說ComponentScanBeanDefinitionParser
    return findParserForElement(element, parserContext).parse(element, parserContext);
}
  1. ComponentScanBeanDefinitionParser 這是個(gè)樣板例子,一看就知道怎么回事

public BeanDefinition parse(Element element, ParserContext parserContext) {
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);//獲取basepackage設(shè)定的包名
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);//有可能使用了$
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);//解析出全部的package
    // Actually scan for bean definitions and register them.
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);//配置掃描器
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);//掃包
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);//向beanFactory注冊
    return null;
}

3.3 prepareBeanFactory(beanFactory)

主要是完成BeanFactoryPostProcessors的初始化

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	...
	 //注意這是LTW,加載時(shí)代碼織入進(jìn)行增強(qiáng)AOP
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
	}
	...
}

3.4 invokeBeanFactoryPostProcessors(beanFactory) 執(zhí)行BeanFactoryPostProcessors,

對(duì)BeanFactory啟動(dòng)處理流程

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); //需要注意的有個(gè)AspectJWeavingEnabler比較特殊,這個(gè)類的目的在于啟用ClassLoader級(jí)別的Aop,和以前的Instrument In Jvm 有點(diǎn)類似,
	// 檢測是否有LTW支持,
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

“java Spring Bean Container的啟動(dòng)加載初始化流程是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI