Spring IOC初始化執行流程

運行環境:jdk8,springboot-2.2.2java

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

refresh方法執行的大致流程緩存

  1. 獲取到BeanFactory並作一些BeanFactory的準備工做
  2. 執行BeanFactory的後置處理器
  3. 建立並註冊其餘的後置處理器
  4. 初始化MessageSource組件(作國際化功能;消息綁定,消息解析)
  5. 初始化事件派發器,註冊監聽器
  6. 建立剩餘的非懶加載的單實例bean
  7. 收尾工做。發佈容器建立完成,清理一些緩存等

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

關於AnnotationConfigServletWebServerApplicationContext的結構請看這裏app

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設置一個序列化IDpost

    refreshBeanFactory();
    	this.beanFactory.setSerializationId(getId());
  • 返回子類GenericApplicationContext類的成員變量private final DefaultListableBeanFactory beanFactorythis

    返回類型爲ConfigurableListableBeanFactory .net

    return getBeanFactory();

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

prepareBeanFactory(beanFactory)

beanFactory進行了一些準備工做code

  • 設置了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();

finishRefresh()

作一些收尾工做

相關文章
相關標籤/搜索