- spring 啟動類 SpringApplication.run(PpApplication.class,args)
- AnnotationConfigEmbeddedWebApplicationContext context = createAndRefreshContext(listeners, applicationArguments);context里面默認帶有一個beanFactory,而這個beanFactory的類型為DefaultListableBeanFactory
- refresh
-
該方法中,我們這次需要注意的地方有兩個:
1、invokeBeanFactoryPostProcessors(beanFactory);
2、finishBeanFactoryInitialization(beanFactory);
兩處傳入的beanFactory為上面的context中的DefaultListableBeanFactory。 -
1 @Override 2 public void refresh() throws BeansException, IllegalStateException { 3 synchronized (this.startupShutdownMonitor) { 4 // 刷新前准備工作,包括設置啟動時間,是否激活標識位,初始化屬性源(property source)配置 5 prepareRefresh(); 6 7 // 創建beanFactory(過程是根據xml為每個bean生成BeanDefinition並注冊到生成的beanFactory 8 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 9 10 //准備創建好的beanFactory(給beanFactory設置ClassLoader,設置SpEL表達式解析器,設置類型轉化器【能將xml String類型轉成相應對象】, 11 //增加內置ApplicationContextAwareProcessor對象,忽略各種Aware對象,注冊各種內置的對賬對象【BeanFactory,ApplicationContext】等, 12 //注冊AOP相關的一些東西,注冊環境相關的一些bean 13 prepareBeanFactory(beanFactory); 14 15 try { 16 // 模板方法,為容器某些子類擴展功能所用(工廠后處理器)這里可以參考BeanFactoryPostProcessor接口的postProcessBeanFactory方法 17 postProcessBeanFactory(beanFactory); 18 19 // 調用所有BeanFactoryPostProcessor注冊為Bean 20 invokeBeanFactoryPostProcessors(beanFactory); 21 22 // 注冊所有實現了BeanPostProcessor接口的Bean 23 registerBeanPostProcessors(beanFactory); 24 25 // 初始化MessageSource,和國際化相關 26 initMessageSource(); 27 28 // 初始化容器事件傳播器 29 initApplicationEventMulticaster(); 30 31 // 調用容器子類某些特殊Bean的初始化,模板方法 32 onRefresh(); 33 34 // 為事件傳播器注冊監聽器 35 registerListeners(); 36 37 // 初始化所有剩余的bean(普通bean) 38 finishBeanFactoryInitialization(beanFactory); 39 40 // 初始化容器的生命周期事件處理器,並發布容器的生命周期事件 41 finishRefresh(); 42 } 43 catch (BeansException ex) { 44 if (logger.isWarnEnabled()) { 45 logger.warn("Exception encountered during context initialization - " + 46 "cancelling refresh attempt: " + ex); 47 } 48 // 銷毀已創建的bean 49 destroyBeans(); 50 // 重置`active`標志 51 cancelRefresh(ex); 52 throw ex; 53 } 54 finally { 55 //重置一些緩存 56 resetCommonCaches(); 57 } 58 } 59 }
- 在這里我想說一下,這個refresh()方法其實是一個模板方法, 很多方法都讓不同的實現類去實現,但該類本身也實現了其中一些方法,並且這些已經實現的方法是不允許子類重寫的,比如:prepareRefresh()方法。
-
1 protected void prepareRefresh() { 2 this.startupDate = System.currentTimeMillis();//設置容器啟動時間 3 this.closed.set(false);//容器關閉標志,是否關閉? 4 this.active.set(true);//容器激活標志,是否激活? 5 6 if (logger.isInfoEnabled()) {//運行到這里,控制台就會打印當前容器的信息 7 logger.info("Refreshing " + this); 8 } 9 10 // 空方法,由子類覆蓋實現,初始化容器上下文中的property文件 11 initPropertySources(); 12 13 //驗證標記為必需的所有屬性均可解析,請參閱ConfigurablePropertyResolver#setRequiredProperties 14 getEnvironment().validateRequiredProperties(); 15 16 //允許收集早期的ApplicationEvents,一旦多播器可用,即可發布... 17 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); 18 }
-
- invokeBeanFactoryPostProcessors.invokeBeanDefinitionRegistryPostProcessors 注冊bean
- postProcessor.postProcesBeanDefinitionRegistry(registry),內部方法,解析日常注解
- processConfigurationClass.componentScanParser 將帶有@bean注解的類進行registry
- componentScanParser.parse,結尾的scanner.doScan,掃描basepackages,並將掃描到的bean生成一個個BeanDefinitionHolder;並執行后續的registerBeanDefinition,將其添加到beanFactory
- registry.registerBeanDefinition,將掃描到的bean存放到一個beanname為key、beanDefinition為value的map內
-
getBean => getBeanFactory.getBean => doGetBean
doCreateBean => createBeanInstance => autowireConstructor => autowireConstructor => instantiate => instantiateClass => newInstanceAbstractBeanFactory
- 屬性注入 doCreateBean方法,填充Bean(populateBean)
借鑒:https://segmentfault.com/a/1190000012887776#articleHeader5