Spring 启动 Bean加载流程
- 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
各位看官大佬,不足之处,多多批评指正,不胜感激!