容器启动过程
- 第一步先调用this();构造方法,这时父类构造器会初始化容器的 beanFactory 属性,属性为DefaultListableBeanFactory,带有存储BeanDefinition 和单例 bean 的功能
- 新建一个注解Bean定义读取器 new AnnotatedBeanDefinitionReader(this); 这个读取器主要是初始化环境变量,以及注册 一些创世纪的 BeanDefinition 【例如:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory】
- 新建一个类路径扫描器ClassPathBeanDefinitionScanner
- 容器调用register(componentClasses);把启动类注册成BeanDefinition放入到容器中
- 启动Spring,调用 refresh() 方法去刷新容器
- prepareRefresh() 准备刷新方法,没有做什么重要的事情,主要是设置了下容器的启动状态
- 调用obtainFreshBeanFactory();获取到容器的工厂,DefaultListableBeanFactory
- 调用prepareBeanFactory(beanFactory)
- 设置容器的类加载器
- 设置Spring容器中需要忽略的set方法
- ResourceEditorRegistrar注册资源编辑器,当Bean初始化的时候,构造器上需要注入Spring资源相关的Bean时,由该类注入
- 注册三个BeanPostProcessor到容器中【ApplicationContextAwareProcessor (会在Bean初始化前,调用,例如ApplicationContextAware接口,会注入ApplicationContext容器到类中)、LoadTimeWeaverAwareProcessor (织入Bean后置处理器)】
- 调用postProcessBeanFactory(beanFactory);留给子类来设置BeanFactory
- 调用invokeBeanFactoryPostProcessors(beanFactory) 方法
- 第一次调用已经初始化过的 BeanDefinitionRegistryPostProcessor 类的 registryProcessor.postProcessBeanDefinitionRegistry(registry) 方法,基本上不会有,除非自己在前面步骤设置过
- 第二次调用实现了PriorityOrdered的 BeanDefinitionRegistryPostProcessor 接口的类的.postProcessBeanDefinitionRegistry(registry) 方法,一般只会有 ConfigurationClassPostProcessor 类,这个类在 1.a 步骤中被注册成BeanDefinition
- ConfigurationClassPostProcessor 去解析配置类,如果类是由 @Configuration 注解的类,则为 full 配置类,其他则为 lite 配置类【full配置类,会生成CGLib动态代理,@Bean方法只会调用一次,下次就直接获取上次的对象;Lite配置类,则生成普通类】
- 生成Configuration解析器,会去解析 @ComponentScan 注解包下所有的类,并且会循环调用,知道把所有需要解析成 BeanDefinition 的类都注册进来 (包括@Component、@Import、@ImportResource这些注解)
- 会解析配置类中有多个@Bean
- 调用实现了 Ordered 的 BeanDefinitionRegistryPostProcessor 接口的类 的 postProcessBeanDefinitionRegistry(registry) 方法
- 调用没有实现 PriorityOrdered、Ordered 的 BeanDefinitionRegistryPostProcessor 接口的类 的 postProcessBeanDefinitionRegistry(registry) 方法
- 然后调用之前所有 BeanDefinitionRegistryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法,会调用 ConfigurationClassPostProcessor 类
- ConfigurationClassPostProcessor. postProcessBeanFactory(beanFactory) 会把Full配置类的BeanDefinition 的类型设置成CGLIB的动态代理类型,初始化时,就是CGLIB动态代理
- 调用实现了PriorityOrdered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
- 调用实现了Ordered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
- 调用没有实现 PriorityOrdered、Ordered 的 BeanFactoryPostProcessor 类的 postProcessBeanFactory(beanFactory) 方法
- EventListenerMethodProcessor (会在所有Bean都实例化完成后,解析Bean中是否带有@EventListener方法,如果有,则会利用EventListenerFactory,生成一个ApplicationListener放入容器中)默认实例化出所有 EventListenerFactory 的类
- 调用registerBeanPostProcessors(beanFactory);注册Bean的后置处理器到容器中
- 主要是两个后置处理器 internalAutowiredAnnotationProcessor、internalCommonAnnotationProcessor
- 会按照优先PriorityOrdered然后Ordered,最后都没实现的BeanPostProcess类的顺序放入到容器中
- 最后放入ApplicationListenerDetector
- 调用 initMessageSource(); 初始化国际化 ,一般是DelegatingMessageSource对象
- 调用 initApplicationEventMulticaster(); 设置容器的事件多播器为 SimpleApplicationEventMulticaster
- 调用 onRefresh(); 方法,Springboot 就是调用这个方法来启动tomcat容器的
- 调用registerListeners();注册事件监听器到容器中,并且如果有早期事件类型,则在容器事件广播器未生成好之前发布事件
- 调用 finishBeanFactoryInitialization(beanFactory); 实例化非懒加载的 Bean
- 先判断是否有conversionService类型的Bean,如果有,则需要转化生成
- 实例化LoadTimeWeaverAware对象
- 实例化Bean
- 实例化之前会先调用 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法,这个时候可以自己初始化出来,返回给容器
- 实例化对象,这个时候有个策略 getInstantiationStrategy().instantiate(mbd, beanName, this); 如果是之前设置了CGLIB动态代理,这里生成的是代理后的对象
- 遍历调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法
- 这里会调用 AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或属性,为后续IOC,依赖注入做准备
- 自动注入属性
- 生成后先遍历所有的 BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName) 方法,这个方法可以重新返回一个新的Bean
- 所有的 Aware 拓展点在这里实现,通过 ApplicationContextAwareProcessor 类,实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware等类在这一步注入
- 实例化Bean,如果Bean实现了 InitializingBean 接口的Bean,会调用它的 afterPropertiesSet 方法
- 遍历所有的 BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName) 方法,这个方法可以重新返回一个新的Bean
- 所有Bean实例化完成后 便利所有bean,调用实现了 SmartInitializingSingleton 接口类的afterSingletonsInstantiated方法
- 最后调用 finishRefresh(),发布容器 publishEvent(new ContextRefreshedEvent(this)); 刷新完成事件
Spring所有拓展点以及顺序
- 实现了 BeanDefinitionRegistryPostProcessor 接口的类,调用 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 方法,可以获取到Bean定义的注册器,去注册BeanDefinition,调用会按照先调用实现了 PriorityOrdered 接口 再调用 Ordered 接口 最后再调用没有实现 PriorityOrdered 接口 、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 类
- 实现了 BeanFactoryPostProcessor 接口的类,调用 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法,可以获取到Bean定义的注册器,去注册BeanDefinition,调用会优先调用实现了BeanDefinitionRegistryPostProcessor 接口的类的 postProcessBeanFactory方法,再按照先调用实现了 PriorityOrdered 接口 再调用 Ordered 接口 最后再调用没有实现 PriorityOrdered 接口 、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 类
- 实现了 InstantiationAwareBeanPostProcessor 接口的类,调用 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法,这个方法可以直接自己初始化出来Bean
- 实现了 MergedBeanDefinitionPostProcessor 接口的类,调用 postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 方法;这个时候Bean已经初始化了,但是属性还没有注入;AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或属性,为后续IOC,依赖注入做准备
- 实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware的类,会在这一步注入相关环境变量属性
- 实现了 BeanPostProcessor 接口的类,调用 postProcessBeforeInitialization(Object bean, String beanName) 方法,这一步Bean已经实例化了,并且属性已经注入了,也可以通过这个拓展来修改对象
- 实现了 InitializingBean 接口的Bean,会调用对象的 afterSingletonsInstantiated() 方法。一般作为对象初始化完成调用的拓展点
- 实现了 BeanPostProcessor 接口的类,调用 postProcessAfterInitialization(Object bean, String beanName) 方法,这一步Bean已经实例化了,并且属性已经注入了,也可以通过这个拓展来修改对象
- 调用实现了 SmartInitializingSingleton 接口类的 afterSingletonsInstantiated() 方法;这个时候所有的Bean已经实例化完成,后续加入的Bean不会受Bean工厂的后置处理器影响
- 监听Spring容器启动事件 ContextRefreshedEvent