溫馨提示×

溫馨提示×

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

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

Spring IOC初始化執(zhí)行流程是什么

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

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

運行環(huán)境:jdk8,springboot-2.2.2

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

refresh方法執(zhí)行的大體流程

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

  2. 執(zhí)行BeanFactory的后置處理器

  3. 創(chuàng)建并注冊其他的后置處理器

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

  5. 初始化事件派發(fā)器,注冊監(jiān)聽器

  6. 創(chuàng)建剩余的非懶加載的單實例bean

  7. 收尾工作。發(fā)布容器創(chuàng)建完成,清理一些緩存等

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

關于AnnotationConfigServletWebServerApplicationContext的結構請看這里

Spring IOC初始化執(zhí)行流程是什么

prepareRefresh()

  • 激活容器

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

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是在創(chuàng)建上下文對象時就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被創(chuàng)建實例化對象后執(zhí)行

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

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

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

    作用有點像@Primary 注解。

postProcessBeanFactory(beanFactory)

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

invokeBeanFactoryPostProcessors(beanFactory)

  • 執(zhí)行兩種后置處理器

    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());


執(zhí)行順序

  1. BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry

  2. BeanDefinitionRegistryPostProcessorpostProcessBeanFactory

  3. BeanFactoryPostProcessorpostProcessBeanFactory

其中包含創(chuàng)建BeanDefinition的流程:

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

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

// 你可以在doScan方法中看到你basePackages(主啟動類所在的包)下所有將要被創(chuàng)建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兩個方法的區(qū)別

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

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

postProcessBeanFactory方法是在容器標準初始化完成后,所有bean的定義信息已經被加載 ,但是還未實例化溫和bean時調用的。執(zhí)行時機要晚于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<>();


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

    再創(chuàng)建后置處理器的實例對象

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

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

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));


補充:

  • MergedBeanDefinitionPostProcessor接口是用來在創(chuàng)建bean時做依賴注入的

initMessageSource()

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

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

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

initApplicationEventMulticaster()

初始化事件派發(fā)器

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

onRefresh()

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

registerListeners()

  • AbstractApplicationContext的成員變量this.applicationListeners事件監(jiān)聽器添加到事件派發(fā)器中

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


  • 將容器中的事件監(jiān)聽器的名字添加到事件派發(fā)器中

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


  • 發(fā)布this.earlyApplicationEvents早期事件,并清理掉早期事件

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


finishBeanFactoryInitialization(beanFactory)

==創(chuàng)建剩下的非懶加載的單實例bean==

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

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

到此,關于“Spring IOC初始化執(zhí)行流程是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

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

AI