中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Spring IOC初始化執行流程是什么

發布時間:2021-11-01 14:21:47 來源:億速云 閱讀:137 作者:iii 欄目:編程語言

這篇文章主要介紹“Spring IOC初始化執行流程是什么”,在日常操作中,相信很多人在Spring IOC初始化執行流程是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring IOC初始化執行流程是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

運行環境:jdk8,springboot-2.2.2

Spring IOC容器的初始化核心在于AbstractApplicationContextrefresh方法

refresh方法執行的大體流程

  1. 獲取到BeanFactory并做一些BeanFactory的準備工作

  2. 執行BeanFactory的后置處理器

  3. 創建并注冊其他的后置處理器

  4. 初始化MessageSource組件(做國際化功能;消息綁定,消息解析)

  5. 初始化事件派發器,注冊監聽器

  6. 創建剩余的非懶加載的單實例bean

  7. 收尾工作。發布容器創建完成,清理一些緩存等

SpringBoot下執行refresh()方法的ApplicationContext的實際類型是AnnotationConfigServletWebServerApplicationContext

關于AnnotationConfigServletWebServerApplicationContext的結構請看這里

Spring IOC初始化執行流程是什么

prepareRefresh()

  • 激活容器

this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
  • 創建早期的事件監聽器和早期的事件

this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
this.earlyApplicationEvents = new LinkedHashSet<>();

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

  • 為 子類GenericApplicationContext類的成員變量private final DefaultListableBeanFactory beanFactory設置一個序列化ID

    refreshBeanFactory();
    	this.beanFactory.setSerializationId(getId());


  • 返回子類GenericApplicationContext類的成員變量private final DefaultListableBeanFactory beanFactory

    返回類型為ConfigurableListableBeanFactory

    return getBeanFactory();


GenericApplicationContextbeanFactory是在創建上下文對象時就new了出來的

prepareBeanFactory(beanFactory)

beanFactory進行了一些準備工作

  • 設置了beanFactory使用的類加載器,設置了用于解析表達式解析器(比如解析${}或#{}表達式的解析器)

    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));


  • 添加了一些后置處理器

    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));


  • 設置了一些不能被自動裝配的接口

    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    ...
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);


  • 注冊了一些能被自動裝配的接口

    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    ...
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);


補充:

  • ApplicationListenerDetectorpostProcessAfterInitialization(Object bean, String beanName)在bean被創建實例化對象后執行

    作用:如果此bean是ApplicationListener,就執行this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);

  • beanFactory.ignoreDependencyInterface指定自動裝配時忽略的接口

  • beanFactory.registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue)指定自動裝配的默認對象。

    作用有點像@Primary 注解。

postProcessBeanFactory(beanFactory)

此方法為空方法,留給子類做實現。

invokeBeanFactoryPostProcessors(beanFactory)

  • 執行兩種后置處理器

    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());


執行順序

  1. BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry

  2. BeanDefinitionRegistryPostProcessorpostProcessBeanFactory

  3. BeanFactoryPostProcessorpostProcessBeanFactory

其中包含創建BeanDefinition的流程:

ConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry方法會為主啟動類所在包和子包中所有組件創建BeanDefinition并 添加到DefaultListableBeanFactory成員變量this.BeanDefinitionMap中。

下面是掃描并獲取到組件的方法棧

// 你可以在doScan方法中看到你basePackages(主啟動類所在的包)下所有將要被創建BeanDefinition的組件
doScan:292, ClassPathBeanDefinitionScanner (org.springframework.context.annotation)
parse:132, ComponentScanAnnotationParser (org.springframework.context.annotation)
doProcessConfigurationClass:290, ConfigurationClassParser (org.springframework.context.annotation)
processConfigurationClass:245, ConfigurationClassParser (org.springframework.context.annotation)
parse:202, ConfigurationClassParser (org.springframework.context.annotation)
parse:170, ConfigurationClassParser (org.springframework.context.annotation)
processConfigBeanDefinitions:325, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:242, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support)
refresh:532, AbstractApplicationContext (org.springframework.context.support)

關于BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistryBeanFactoryPostProcessorpostProcessBeanFactory兩個方法的區別

執行時機不不同。這兩個方法上的注釋是這樣說的

postProcessBeanDefinitionRegistry方法是在容器標準初始化完成后,bean定義信息(BeanDefinition對象)未被加載,且未實例化任何bean時調用的。此時還可以向容器中添加新的或覆蓋舊的bean定義信息

postProcessBeanFactory方法是在容器標準初始化完成后,所有bean的定義信息已經被加載 ,但是還未實例化溫和bean時調用的。執行時機要晚于postProcessBeanDefinitionRegistry方法

registerBeanPostProcessors(beanFactory)

向容器中添加后置處理器

PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
  • 向容器中添加一個后置處理器

    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));


  • 分四類注冊自定義的后置處理器

    // 實現了PriorityOrdered接口
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 實現了PriorityOrdered接口,且是MergedBeanDefinitionPostProcessor類型
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // 實現了Ordered接口的
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 沒有實現PriorityOrdered或Ordered接口的
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();


    先將后置處理器根據上述規則分類添加到不同的List中,再排序

    再創建后置處理器的實例對象

    再將實例對象添加到容器中(AbstractBeanFactory的成員變量private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

  • 向容器中添加一個后置處理器

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));


補充:

  • MergedBeanDefinitionPostProcessor接口是用來在創建bean時做依賴注入的

initMessageSource()

初始化MessageSource組件(做國際化功能;消息綁定,消息解析)

  • 檢查容器中是否有beanName == "messageSource"的bean。如果沒有就new一個,并賦值給this.messageSource,再將其添加到容器中

以后可注入此bean,執行其getMessage方法獲取到國際化配置文件中的內容

initApplicationEventMulticaster()

初始化事件派發器

  • 檢查容器中是否有beanName == "applicationEventMulticaster"的bean。如果沒有就new一個,并賦值給this.applicationEventMulticaster,再將其添加到容器中

onRefresh()

此方法為空方法,留給子類做實現。

registerListeners()

  • AbstractApplicationContext的成員變量this.applicationListeners事件監聽器添加到事件派發器中

    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }


  • 將容器中的事件監聽器的名字添加到事件派發器中

    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }


  • 發布this.earlyApplicationEvents早期事件,并清理掉早期事件

    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }


finishBeanFactoryInitialization(beanFactory)

==創建剩下的非懶加載的單實例bean==

// 創建剩余的非懶加載單實例bean
finishBeanFactoryInitialization(beanFactory);
	
	// 調用beanFactory創建剩余的非懶加載單實例bean
	beanFactory.preInstantiateSingletons();
		
		// 獲取并遍歷beanNames,用beanName獲取BeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		
		getBean(beanName);
			
			doGetBean(name, null, null, false);
			
				// 嘗試從容器中獲取bean,如果獲取不到再自行創建bean。getSingleton方法為DefaultSingletonBeanRegistry的方法
				Object sharedInstance = getSingleton(beanName);
				// sharedInstance==null 執行以下流程創建bean
				// 獲取bean的定義信息
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 獲取此bean所依賴的其他bean
				String[] dependsOn = mbd.getDependsOn();
				// 如果dependsOn不為空,遍歷dependsOn,執行getBean(dep)。即,先創建此bean所依賴的bean。
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						getBean(dep);
					}
				}
				// 如果此bean是單實例,執行以下方法創建bean
				sharedInstance = getSingleton(beanName, () -> {
							return createBean(beanName, mbd, args);
				});
					// 調用上面創建的匿名類實現的方法
					singletonObject = singletonFactory.getObject();
						
						// 調用上述的createBean(beanName, mbd, args);方法。創建bean						
						Object beanInstance = doCreateBean(beanName, mbdToUse, args);
							
							// 創建并接收bean的實例對象
							instanceWrapper = createBeanInstance(beanName, mbd, args);
							// 執行MergedBeanDefinitionPostProcessor類型的后置處理器。其中包含將@Autowired,@Value等信息放到injectionMetadataCache中的邏輯,之后執行的populateBean會從中取值,完成依賴注入
							applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
							// 賦值。其中包括依賴注入,為此bean的成員變量完成賦值
							populateBean(beanName, mbd, instanceWrapper);
								
								// 遍歷調用InstantiationAwareBeanPostProcessor類型的后置處理器
								ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName);
								...
                                // 此過程包含AutowiredAnnotationBeanPostProcessor將@Autowired注解的對象注入到當前bean中
								ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
							// 初始化。執行Aware接口方法,執行后置處理器,執行初始化方法
							exposedObject = initializeBean(beanName, exposedObject, mbd);
								
								// 如果實現了以下接口就執行BeanNameAware\BeanClassLoaderAware\BeanFactoryAware的接口方法
								invokeAwareMethods(beanName, bean);
								// 執行后置處理器的postProcessBeforeInitialization方法。其中包含執行@PostConstruct指定的初始化方法
								wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
								// 執行初始化方法。先執行實現了InitializingBean接口的方法再執行@Bean指定的初始化方法
								invokeInitMethods(beanName, wrappedBean, mbd);
								// 執行后置處理器的applyBeanPostProcessorsAfterInitialization方法。其中包含創建并返回aop代理對象的后置處理器
							// 注冊銷毀方法
							registerDisposableBeanIfNecessary(beanName, bean, mbd);

					// 將bean添加到容器中
					addSingleton(beanName, singletonObject);
		所有Bean都利用getBean創建完成以后:
        檢查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就執行afterSingletonsInstantiated();

到此,關于“Spring IOC初始化執行流程是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

开封县| 甘南县| 富川| 辽源市| 盐源县| 灵璧县| 孟村| 南丰县| 桂阳县| 临武县| 金坛市| 吉水县| 嘉祥县| 新巴尔虎左旗| 海门市| 高邑县| 灵山县| 岳阳市| 甘泉县| 三亚市| 临潭县| 汉阴县| 临夏县| 六安市| 莫力| 贡嘎县| 布拖县| 壤塘县| 布尔津县| 菏泽市| 双鸭山市| 道孚县| 农安县| 长治县| 科技| 阿坝县| 习水县| 兰考县| 马边| 永福县| 依安县|