運行環境:jdk8,springboot-2.2.2java
Spring IOC容器的初始化核心在於AbstractApplicationContext
的refresh
方法spring
refresh方法執行的大致流程緩存
- 獲取到
BeanFactory
並作一些BeanFactory
的準備工做 - 執行
BeanFactory
的後置處理器 - 建立並註冊其餘的後置處理器
- 初始化MessageSource組件(作國際化功能;消息綁定,消息解析)
- 初始化事件派發器,註冊監聽器
- 建立剩餘的非懶加載的單實例bean
- 收尾工做。發佈容器建立完成,清理一些緩存等
SpringBoot
下執行refresh()
方法的ApplicationContext
的實際類型是AnnotationConfigServletWebServerApplicationContext
springboot
關於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
設置一個序列化IDpostrefreshBeanFactory(); this.beanFactory.setSerializationId(getId());
-
返回子類
GenericApplicationContext
類的成員變量private final DefaultListableBeanFactory beanFactory
this返回類型爲
ConfigurableListableBeanFactory
.netreturn getBeanFactory();
GenericApplicationContext
的beanFactory
是在建立上下文對象時就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);
補充:
-
ApplicationListenerDetector
的postProcessAfterInitialization(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());
執行順序
BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
BeanDefinitionRegistryPostProcessor
的postProcessBeanFactory
BeanFactoryPostProcessor
的postProcessBeanFactory
其中包含建立BeanDefinition的流程:
ConfigurationClassPostProcessor
的postProcessBeanDefinitionRegistry
方法會爲主啓動類所在包和子包中全部組件建立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)
關於BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
和BeanFactoryPostProcessor
的postProcessBeanFactory
兩個方法的區別
執行時機不不一樣。這兩個方法上的註釋是這樣說的
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()
作一些收尾工做