当前位置: 首页 > news >正文

Spring容器的启动流程

1、扫描并注册BeanDefinition:

  1. Spring 会开始扫描指定的包,查找带有 @Component、@Service、@Repository 和 @Controller 等注解的类。
  2. 发现的类会被处理,创建相应的 BeanDefinition 对象,封装类名、作用域、依赖关系等元数据。
  3. 这些 BeanDefinition 对象会被注册到 BeanDefinitionRegistry 中,构建容器对应用组件的理解。

2、解析配置和Bean装配:

  1. Spring 也会处理带有 @Configuration 注解的配置类,识别带有 @Bean 注解的方法。
  2. 这些方法的返回值被视为 bean 定义,类似于扫描到的组件一样进行处理。
  3. 这一步确保通过 Java 配置定义的 bean 也会被注册到容器中。

3、创建非懒加载的单例Bean:

  1. 容器开始创建非懒加载的单例 bean,包括实例化和依赖注入。
  2. 依赖关系通过构造函数注入、setter 方法或字段注入来解析,确保每个 bean 都正确注入了依赖。

4、Bean的创建生命周期:

  1. Bean 的创建包括多个步骤,如合并 bean 定义、推断构造函数、实例化、属性填充、预初始化、初始化和后初始化。
  2. 初始化后,面向切面编程(AOP)框架开始起作用,允许横切关注点被编织到 bean 中。

5、发布容器启动事件:

  1. 一旦非懒加载的单例 bean 被创建和初始化,Spring 会发布 ContextRefreshedEvent 事件。
  2. 此事件表示容器已完全初始化,允许其他组件在启动后执行操作。
  3. 其中会调用Refresh()方法:
    	// 1. 刷新前的预处理prepareRefresh();// 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3. 预处理 beanFactory,向容器中添加一些组件prepareBeanFactory(beanFactory);try {// 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置postProcessBeanFactory(beanFactory);// 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册 BeanPostProcessors,bean 后置处理器registerBeanPostProcessors(beanFactory);// 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)initMessageSource();// 8. 初始化事件派发器,在注册监听器时会用到initApplicationEventMulticaster();// 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用onRefresh();// 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)registerListeners();// 11. 初始化所有的非单实例 beanfinishBeanFactoryInitialization(beanFactory);// 12. 发布容器刷新完成事件finishRefresh();

6、延迟加载的Bean创建:带有 @Lazy 标记的 bean 不会在初始启动过程中创建,而是在首次请求时创建。这有助于优化启动时间。

7、处理应用关闭:

  1. Spring 注册了一个关闭钩子,在应用关闭时优雅地释放资源。
  2. 发布 ContextClosedEvent 并执行清理任务,确保正确处理单例 bean。

8、Spring 启动完成:所有这些步骤完成后,Spring 容器已完全初始化,并准备好处理来自应用程序的请求。启动过程结束,应用程序处于运行状态。

9、处理其他注解:在Spring启动过程中,还会处理其他注解,比如@Import等,这些注解可能会引入其他配置或者Bean到应用程序上下文中。

ps:以下是我整理的java面试资料,密码是obht,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》 

相关文章:

  • 如何在Word里一次性给全部汉字加拼音?
  • 艺术与科技的结合,AI绘画图生图怎么样?
  • 【ros2 control 机器人驱动开发】双关节多控制器机器人学习-example 4
  • JavaWeb环境配置 IDE2022版
  • nginx作为tcp的负载均衡
  • 从mysql 数据库表导入数据到elasticSearch的几种方式
  • [动态规划][蓝桥杯 2022 省 B] 李白打酒加强版 -- 代码注释含详解
  • gdb 调试,给 scanf 传入不可见字符
  • https 加密解密过程是什么?
  • 上位机图像处理和嵌入式模块部署(上、下位机通信的三个注意点)
  • 计算机等级考试:信息安全技术 知识点一
  • SpringCloud微服务-SpringAMQP(RabbitMQ)
  • 计算机体系结构:VLIW
  • Python爬虫:设置随机 User-Agent
  • github双因子认证
  • 2017-08-04 前端日报
  • Android 控件背景颜色处理
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Android组件 - 收藏集 - 掘金
  • axios 和 cookie 的那些事
  • css选择器
  •  D - 粉碎叛乱F - 其他起义
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java 内存分配及垃圾回收机制初探
  • maven工程打包jar以及java jar命令的classpath使用
  • MD5加密原理解析及OC版原理实现
  • MobX
  • PermissionScope Swift4 兼容问题
  • Redux 中间件分析
  • vue的全局变量和全局拦截请求器
  • 动态规划入门(以爬楼梯为例)
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 如何学习JavaEE,项目又该如何做?
  • 深入浏览器事件循环的本质
  • 数组大概知多少
  • 在Unity中实现一个简单的消息管理器
  • 阿里云服务器如何修改远程端口?
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (五)Python 垃圾回收机制
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .libPaths()设置包加载目录
  • .Net core 6.0 升8.0
  • .NET Core跨平台微服务学习资源
  • .NET Framework杂记
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET导入Excel数据
  • .NET应用架构设计:原则、模式与实践 目录预览