您好,登錄后才能下訂單哦!
這篇文章主要介紹“Spring IOC初始化執行流程是什么”,在日常操作中,相信很多人在Spring IOC初始化執行流程是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring IOC初始化執行流程是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
運行環境:jdk8,springboot-2.2.2
Spring IOC容器的初始化核心在于AbstractApplicationContext
的refresh
方法
refresh方法執行的大體流程
獲取到BeanFactory
并做一些BeanFactory
的準備工作
執行BeanFactory
的后置處理器
創建并注冊其他的后置處理器
初始化MessageSource組件(做國際化功能;消息綁定,消息解析)
初始化事件派發器,注冊監聽器
創建剩余的非懶加載的單實例bean
收尾工作。發布容器創建完成,清理一些緩存等
SpringBoot
下執行refresh()
方法的ApplicationContext
的實際類型是AnnotationConfigServletWebServerApplicationContext
關于AnnotationConfigServletWebServerApplicationContext
的結構請看這里
激活容器
this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true);
創建早期的事件監聽器和早期的事件
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); this.earlyApplicationEvents = new LinkedHashSet<>();
為 子類GenericApplicationContext
類的成員變量private final DefaultListableBeanFactory beanFactory
設置一個序列化ID
refreshBeanFactory(); this.beanFactory.setSerializationId(getId());
返回子類GenericApplicationContext
類的成員變量private final DefaultListableBeanFactory beanFactory
返回類型為ConfigurableListableBeanFactory
return getBeanFactory();
GenericApplicationContext
的beanFactory
是在創建上下文對象時就new了出來的
為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);
補充:
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)
此方法為空方法,留給子類做實現。
執行兩種后置處理器
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
方法
向容器中添加后置處理器
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()
此方法為空方法,留給子類做實現。
將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); } }
==創建剩下的非懶加載的單實例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初始化執行流程是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。