spring启动流程

prepareRefresh();

1、设置客器启动时间
2、设置一些状态位标识,如active,closed
3、初始化占位符属性资源容器
4、创建环境对象,校验必填属性是否可解析
5、初始化一些成员变量,如earlyApplicationListeners、.earlyApplicationEvents

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 基于注解的spring加载方式在前面的构造方法中就已经创建BeanFactory对象了,
// 如果是基于xml配置的加载方式,在这里会创建BeanFactory,并且会根据xml的配置configLocations
// 扫描@Service @Repository @Component等组件(ClassPathBeanDefinitionScanner),加载BeanDefinition

1、创建bean工厂,类型是DefaultListableBeanFactory
2.设置bean工厂的序列化lD
3.定制化bean工厂,其实也是设置-些属性,如allowBeanDefinitionOverriding、allowCircularReferences
4、加bean定义信息,初始化BeanDef行nitionReaderi读取器,将配置文件转换成输入流对像,通过sAX解折XML文件中的默认标签以及自定义标签内容,
封装成BeanDefinition,注册到DefaultListableBeanFactory#beanDefinitionMap中

prepareBeanFactory(beanFactory);
// 配置BeanFactory,注册Environment、SystemProperties、SystemEnvironment实例
// 添加一些BeanPostProcessor如:ApplicationContextAwareProcessor(用于解析Aware)

1、设置bean类加载器信息
2.添加一些BeanPostProcessor增强器
3.忽路一些接口的自动装配依赖
4.注册一些bean对象到容器中,如environment,systemProperties等

// 钩子回调
postProcessBeanFactory(beanFactory);

模板方法、留给子类实现


invokeBeanFactoryPostProcessors(beanFactory);
// 执行各种BeanFactoryPostProcessor回调处理,通过beanFactory.getBean创建 BeanFactoryPostProcessor实例
// 这里有个非常重要的类:ConfigurationClassPostProcessor
// 通过执行这个类的回调 对@Configuration、@ComponentScan、@Component、@Import、@ImportSource、@Bean、@PropertySource、@Conditional等注解进行解析
// 完成Spring注解方式注册BeanDefinition

1、调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
2、调用实现了Orderec接口的BeanDefinitionRegistryPostProcessors
3、其它BeanDefinitionRegistryPostProcessors
4、调用实现了PriorityOrdered接口的BeanFactoryPostProcessor
5、调用实现了Ordered接口的BeanFactoryPostProcessor
6、调用其它BeanFactoryPostProcessor

registerBeanPostProcessors(beanFactory);
// 同过beanFactory.getBean提前创建BeanPostProcessor实例,保存在容器中

1、注册实现了PriorityOrdered接口的BeanPostProcessor
2、注册实现了Ordered接口的BeanPostProcessor
3、注册其它BeanPostProcessor

// 资源国际化
initMessageSource();

1、初始化messageSource
初始化MessageSource,国际化处理

// 初始化事件广播器ApplicationEventMulticaster
initApplicationEventMulticaster();

1、如果容器中存在applicationEventMulticaster,则直接获取,否则创建一个新的SimpleApplicationEventMulticaster,并注册到容器中

onRefresh();

模板方法、留给子类实现

// 注册ApplicationListener,将ApplicationListener添加到ApplicationEventMulticaster中
registerListeners();

1、往applicationEventMulticastera事件多播器中注册一系列监听器

// 实例化剩下所有非懒加载的单实例Bean
finishBeanFactoryInitialization(beanFactory);

1、循环遍历之前解折后的BeanDefinition定义信息
2、通过反射创建hean对象
3、bean的属性填充
4.调用Aware接口相关方法,如BeanNameAware、BeanFactoryAware等
5、执行BeanPostProcessor的postProcessBeforelnitialization()前置增强方法
6.、执行InitializingBean的afterPropertiesSet()方法
7、执行自定义的初始化方法,如init-method等
8.执行BeanPostProcessor的oostProcessAfterlnitialization()后百增强方法
9、执行DisposableBean的destroy()销毁方法
10、执行自定义的销毁方法,如destroy-method等

// Spring容器完成刷新,发布事件:ContextRefreshedEvent,执行LifecycleProcessor.onRefresh()
finishRefresh();

1、清除资源缓存
2、初始化生命周期处理器,调用onRefresh()刷新方法
3、发布容器已刷新事件

总结表达

Spring中的lOC容器启动主要是在
AbstractApplicationContext#refresh0方法实现
的。大体过程如下:

  1. 第一步,首先会执行一些容器刷新前的准备工 作,如设置容器启动时间、一些状态标志位等
  2. 第二步,创建容器对象,其实就是实例化 DefaultListableBeanFactory对象,这一步包含了
    bean定义信息的解析,解析后的属性都封装到 DefaultListableBeanFactory的成员属性中了,如
    我们常见的beanDefinition Map、 beanDefinitionNames;
  3. 第三步,准备Bean工厂,实际上就是设置 beanFactory的一些属性;
  4. 第四步,Spring提供了 postProcessBeanFactory0方法给我们去扩展,例
    如我们可以注册一些特殊的BeanPostProcessor后 置处理器等操作;
  5. 第五步,执行BeanFactoryPostProcessor后置 处理器的postProcessBeanFactory(增强方法,使
    用三个不同的集合分别存放实现了PriorityOrdered 接口、实现了Ordered接口、普通的
    BeanFactoryPostProcessor,经过排序后,执行 BeanFactoryPostProcessor的回调
    postProcessBeanFactory0;
  6. 第六步,注册BeanPostProcessorj后置处理器, 注意,这里还不会执行BeanPostProcessor>对应的
    增强方法;同样的,使用三个不同的集合分别存放 实现了PriorityOrderedi接口、实现了Ordered接
    口、普通的BeanPostProcessor,.依次调用 beanFactory.addBeanPostProcessor(
    postProcessor)方法往bean工厂中添加 BeanPostProcessor;
  7. 第七步,为上下文初始化MessageSource,即 国际化处理;
  8. 第八步,初始化事件多播器,即 ApplicationEventMulticaster,为后面的事件发 布-监听做准备;
  9. 第九步,提供了一个模板方法onRefresh0,留 给子类初始化其他的bean;
  10. 第十步,注册Listener监听器
  11. 实例化剩下所有非懒加载的单实例Bean
  12. Spring容器完成刷新,发布事件:ContextRefreshedEvent
  • 14
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring启动过程可以分为以下几个步骤[^1]: 1. 创建Spring容器:通过创建一个ApplicationContext对象来启动Spring容器。可以使用不同的ApplicationContext实现类,如AnnotationConfigApplicationContext、ClassPathXmlApplicationContext等。 2. 解析配置类:如果使用AnnotationConfigApplicationContext启动容器,会解析配置类,将配置类中的Bean定义注册到容器中。 3. 准备启动:在容器准备启动之前,会执行一些准备工作,如初始化消息源、初始化事件广播器等。 4. 注册Bean后置处理器:在容器启动之前,会注册一些Bean后置处理器,用于在Bean实例化和初始化过程中进行一些额外的处理。 5. 初始化BeanFactory:在容器启动之前,会对BeanFactory进行一些初始化操作,如设置类加载器、设置Bean的后置处理器等。 6. 完成容器初始化:在容器启动之前,会完成BeanFactory的初始化工作,包括实例化和初始化所有的单例Bean。 7. 容器启动完成通知:在容器启动完成后,可以通过创建一个实现SmartLifecycle接口的类来监听容器启动完成的通知。 以下是一个示例代码,演示了Spring启动过程中的一些关键步骤: ```java import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.SmartLifecycle; import org.springframework.stereotype.Component; @Component public class Beanfinish implements SmartLifecycle { @Override public void start() { System.out.println("容器启动完成通知..."); } @Override public void stop() { } @Override public boolean isRunning() { return false; } @Override public boolean isAutoStartup() { return true; } } public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); context.start(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值