首页 > 其他分享 >自编概念补充容器启动流程

自编概念补充容器启动流程

时间:2024-04-11 22:55:19浏览次数:25  
标签:容器 beanFactory Spring 自编 初始化 bean context 流程

1、初始化流程

 

①:如果我想生成 bean 对象,那么就需要一个 beanFactory 工厂(DefaultListableBeanFactory);

②:如果我想对加了特定注解(如 @Service@Repository)的类进行读取转化成 BeanDefinition 对象(BeanDefinition 是 Spring 中极其重要的一个概念,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等),那么就需要一个注解配置读取器(AnnotatedBeanDefinitionReader);

③:如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器(ClassPathBeanDefinitionScanner)。

 

2、刷新流程

 

看完流程图,我们也先思考一下:在 3.1 中我们知道了如何去初始化一个 IOC 容器,那么接下来就是让这个 IOC 容器真正起作用的时候了:即先扫描出要放入容器的 bean,将其包装成 BeanDefinition 对象,然后通过反射创建 bean,并完成赋值操作,这个就是 IOC 容器最简单的功能了。但是看完上图,明显 Spring 的初始化过程比这个多的多,下面我们就详细分析一下这样设计的意图:

如果用户想在扫描完 bean 之后做一些自定义的操作:假设容器中包含了 a 和 b,那么就动态向容器中注入 c,不满足就注入 d,这种骚操作 Spring 也是支持的,得益于它提供的 BeanFactoryPostProcessor 后置处理器,对应的是上图中的 invokeBeanFactoryPostProcessors 操作。

如果用户还想在 bean 的初始化前后做一些操作呢?比如生成代理对象,修改对象属性等,Spring 为我们提供了 BeanPostProcessor 后置处理器,实际上 Spring 容器中的大多数功能都是通过 Bean 后置处理器完成的,Spring 也是给我们提供了添加入口,对应的是上图中的 registerBeanPostProcessors 操作。

整个容器创建过程中,如果用户想监听容器启动、刷新等事件,根据这些事件做一些自定义的操作呢?Spring 也早已为我们考虑到了,提供了添加监听器接口和容器事件通知接口,对应的是上图中的 registerListeners 操作。

此时再看上图,是不是就觉得简单很多呢,下面就一些重要代码进行分析。

 

②、核心代码剖析

org.springframework.context.support.AbstractApplicationContext#refresh

这个方法是对上图中的具体代码实现,可划分为12个步骤,其中比较重要的步骤下面会有详细说明。

在这里,我们需要记住:Spring 中的每一个容器都会调用 refresh 方法进行刷新,无论是 Spring 的父子容器,还是 Spring Cloud Feign 中的 feign 隔离容器,每一个容器都会调用这个方法完成初始化。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public void refresh() throws BeansException, IllegalStateException {     synchronized (this.startupShutdownMonitor) {         // Prepare this context for refreshing.         // 1. 刷新前的预处理         prepareRefresh();           // Tell the subclass to refresh the internal bean factory.         // 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();           // Prepare the bean factory for use in this context.         // 3. 预处理 beanFactory,向容器中添加一些组件         prepareBeanFactory(beanFactory);           try {             // Allows post-processing of the bean factory in context subclasses.             // 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置             postProcessBeanFactory(beanFactory);               // Invoke factory processors registered as beans in the context.             // 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器             invokeBeanFactoryPostProcessors(beanFactory);               // Register bean processors that intercept bean creation.             // 6. 注册 BeanPostProcessors,bean 后置处理器             registerBeanPostProcessors(beanFactory);               // Initialize message source for this context.             // 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)             initMessageSource();               // Initialize event multicaster for this context.             // 8. 初始化事件派发器,在注册监听器时会用到             initApplicationEventMulticaster();               // Initialize other special beans in specific context subclasses.             // 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用             onRefresh();               // Check for listener beans and register them.             // 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)             registerListeners();               // Instantiate all remaining (non-lazy-init) singletons.             // 11. 初始化所有的非单实例 bean             finishBeanFactoryInitialization(beanFactory);               // Last step: publish corresponding event.             // 12. 发布容器刷新完成事件             finishRefresh();         }           ...               }

标签:容器,beanFactory,Spring,自编,初始化,bean,context,流程
From: https://www.cnblogs.com/itqinls/p/18130208

相关文章

  • Qt 如何遍历序列容器(QVector|QMap|...)
    QT提供了两种风格的遍历器:Java和STL一、Java风格遍历器Java风格的遍历器是Qt首先推荐使用的形式。这种风格比起STL风格的遍历器更方便。方便的代价就是不如后者高效。Java风格的遍历器指向的是两个元素之间的位置,而不是指向元素本身。因此,它们可能会指向集合第一......
  • 不同虚拟机之间的docker容器互相访问
    虚拟机平台VMwareWrokStationPro16虚拟机环境Unbuntu22.04目标:在VM2中创建1个bridge虚拟网络,在VM2中,创建容器x,并能访问VM1中的容器,在两个虚拟机中创建birdge网络,虚拟机中的容器可以互相访问解决方案:使用overlay来实现不同虚拟机中的容器的互相访问在虚拟机1使用命令do......
  • 深入了解 Docker:革命性的容器化技术
    简介在当今软件开发和部署的世界中,Docker已经成为一种不可或缺的技术。它的出现极大地改变了软件交付和部署的方式。本文将带您深入了解Docker,从它的起源、历史发展,到它所能做的事情以及为什么它如此受欢迎。Docker的出现背景Docker的出现源于解决传统软件开发和部署过程......
  • tracer ftrace笔记(23)—— 上层trace打印流程-TODO
    1.ATRACE_INT打印不出来分析#defineATRACE_INT(name,value)atrace_int(ATRACE_TAG,name,value)///system/core/libcutils/include/cutils/trace.hstaticinlinevoidatrace_int(uint64_ttag,constchar*name,int32_tvalue){ if(CC_UNLIKELY(atrace_is_tag_enabl......
  • IOS开发——构建版本发布到TestFlight后邀请人员安装App测试流程
    关于打包上传TestFlight详见: IOS开发Archives打包后构建版本发布到TestFlight全流程。这里详细说明发布到TestFlight后邀请人员安装App进行测试。1.创建测试组:登录上AppStoreConnect之后,选择App,切换到TestFlight界面,点击左侧导航中”内部测试“栏目右边蓝色的添加图标......
  • 新建微服务工程并形成jar包,部署到docker容器
    流程:1.创建微服务使用springcloud  2.打jar包:  3.把jar包上传到linux服务器中。4.编写dockerfile文件vimdockerfiledockerfile文件内容: 5.构建镜像 dockerbuild-tzzyy_docker:1.6. 6.运行容器dockerrun-d-p6001:6001容器Id  7.访问测......
  • 172号卡分销系统代理如何向用户推广号卡流程?以及如何提高首充率?
    代理在推广流量号卡时,需要明确的策略和方法。作为172号卡分销系统的代理,了解如何有效地向用户推广是关键。下面将为您提供一个详细的推广流程以及如何提高首充率的建议。1. 推广号卡流程:a. 代理在开始推广号卡前,代理需要深入研究每一个套餐的详情页内容。这有助于你熟知每......
  • 加拿大基金会注册流程
         区块链项目如今依旧是如日中天,开展区块链项目注册海外基金会作为主体公司依然是很多项目的首要选择,可以申请注册海外基金会的国家也比较多,但目前市场上蕞受欢迎的基金会有:新加坡基金会、美国基金会、英国基金会、开曼基金会、加拿大基金会等。虽然新加坡基金会是......
  • Dubbo源码解读-Consumer消费端@Reference服务端引用流程
    上篇我们介绍了Provider端监听注册中心动态配置原理,地址如下Dubbo源码解析-Provider端监听注册中心动态配置原理-CSDN博客    本文主要针Dubbo消费端@Reference服务端引用流程原理,从dubbo源码角度进行解析。    大家可以好好仔细读一下本文。有疑问欢迎留言......
  • Zabbix全流程监控详解(一):Zabbix监控概述和安装
    一、监控的选型以前用的监控:Nagios+Cacti现在使用监控:Zabbix+Grafana,OpenFalcon,Prometheus二、Zabbix监控架构1.Zabbix生命周期LTS:Longtimesupport长期维护版本2.Zabbix的监控架构Zabbix是一个CS(服务端/客户端)架构的服务Zabbix-agent(客户端)获取数据—>......