宏观上看Spring创建对象的过程
宏观上看Spring创建对象的过程
对于对象而言,可以分为简单对象和复杂对象;
-
简单对象
简单对象指可以直接new的对象; Spring在创建这些对象时,是基于反射来完成的。 -
复杂对象
复杂对象指不能直接new的对象。 比如:要得到接口类型的对象,是不能直接new的,需要使用其实现类来创建。但是有的其实现类也是不能直接new的,比如Connection对象。 对于这种对象,可以使用实现FactoryBean接口的方式来创建;需要实现三个方法:getObject() ------> 书写位置 -----> Spring工厂 回调 getObject()获得对象getObjectType()isSingleton() 也可以使用静态工厂或者实例工厂来创建; 静态工厂:MyFactory{public static Object getObject(){xxxxxxxxx}}<bean id="" class="xxx.MyFactory" factory-method="getObject"/> 实例工厂:MyFactory{public Object getObject(){}}<bean id="myFactory" class="xxx.MyFactory"/><bean id="product" factory-bean="myFactory" factory-method="getObject"/>这仅仅完成了对象的创建。我们还要考虑为对象属性进行赋值(也称为属性的注入)。
Spring为创建的对象注入属性
注入的方式:
-
set注入
<bean id="u" class=""><property > ----------set注入 </bean>会有两种注入的形式
-
程序员自己完成的注入
可以注入8种基本类型、自建类型(通过ref=)的bean;
-
Spring容器自己的注入(aware)
实现BeanNameAware接口,实现void setBeanName(String name)方法,Spring容器自动调用它【谁调用谁就会传参】,可以获取当前对象在工厂中的id(beanName),定义一个变量把它存起来就可以了; 实现BeanFactoryAware接口,实现void setBeanFactory(BeanFactory beanFactory)方法,Spring容器自动调用它,可以获取创建当前对象的工厂对象,定义一个变量把它存起来就可以了。BeanFactoryAware接口的应用场景:可以解决scope=prototype在注入过程中失效的问题。比如类A是单例的,类B是多例的,类A中有类B的成员变量b,如果用set注入,每一次获取都是一样的地址,因为类A对象已经被创建出来,并存储到容器里了,再获取成员变量b时,没有为其重新赋值。我们可以获取到工厂,每次在a中使用b时,都从容器中获取一次。 scope=prototype在注入过程中失效的解决方式还有一个,lookup-method = ,但是用的少这两种方式先后顺序是怎样的呢?——用户自己设置的set注入在前,容器的注入在后。
-
-
构造注入
<bean id="u" class=""><constructor-arg >——————构造注入 </bean> -
autowire自动注入
如果在beans配置,beans管理的所有bean都会自动注入

如果在bean配置,此bean的属性会自动注入;

工厂创建对象的完整流程

- Spring工厂创建对象;
- 对属性进行set注入(用户的set注入在前,实现Aware接口容器的set注入在后);
- set注入完成后得到的对象交给BeanPostProcessor中的postProcessBeforeInitialization(Object bean, String beanName)方法为对象进行加工(参数bean就是待加工的bean,返回值为加工好的bean);
- 为postProcessBeforeInitialization方法加工后的对象进行初始化,有两种方式: 第一种方式实现InitializingBean接口(在前)、第二种方式 指定init-method方法(在后);
- 初始化后的对象,交给BeanPostProcessor中的postProcessAfterInitialization(Object bean, String beanName)方法为对象进行加工(参数bean就是待加工的bean,返回值为加工好的bean);
- 最后得到加工好的对象,用户可以进行使用;
- 工厂调用destroySingletons()方法,工厂关闭,销毁对象。
问题:为什么还需要实现BeanPostProcessor接口为其增加功能,不能在创建对象时,直接写好呢?
答案:BeanPostProcessor接口中的方法,可以为多个对象增加功能,代码可以复用,减少代码的冗余;
加功能是可有可无的功能,如果需要可以加上,如果不需要就取消掉,可以解决代码的耦合。
问题:一般在BeanPostProcessor接口的哪个方法为对象增加功能呢?
答案:postProcessAfterInitialization方法,因为前面已经初始化完成了,后续没有在对bean的操作了;如果在postProcessBeforeInitialization中为对象进行加工,后续可能还会改。
注意:BeanPostProcessor的功能,只有在高级的工厂(比如ApplicationContext)才有。
注意:第5步的初始化操作,和BeanPostProcessor的方法,在开发中我们一般不用。
Spring BeanFactory源码中是如何创建对象的
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(""));
beanFactory.getBean("id");
第一行代码的作用:
读取xml文件,解析bean标签,封装成BeanDefinition对象,并以id为key,BeanDefinition对象为value存储到map中;
第二行代码的作用:
1.基于BeanDefinition创建对象;
2.创建对象的过程,包括前文生命周期中除销毁的步骤;
3.创建对象的过程中,需要按照scope进行讨论:scope=singleton——单例对象,Spring中使用map结构(key为bean的id,value为bean)来保证永远只创建一次;scope=prototype——每次都走一遍创建对象的流程。
相关文章:
宏观上看Spring创建对象的过程
宏观上看Spring创建对象的过程 对于对象而言,可以分为简单对象和复杂对象; 简单对象 简单对象指可以直接new的对象; Spring在创建这些对象时,是基于反射来完成的。复杂对象 复杂对象指不能直接new的对象。 比如:要得到…...
Jtti:linux如何配置dns域名解析服务器
要配置Linux上的DNS域名解析服务器,您可以按照以下步骤进行操作: 1. 安装BIND软件包:BIND是Linux上最常用的DNS服务器软件,您可以使用以下命令安装它: sudo apt-get install bind9 2. 配置BIND:BIND的配置…...
上网速度慢解决方案
方法 1:手动设置 Proxy 服务器 假如你是使用宽带的用户,使用宽带路由器后可能会发觉无法浏览一些网页,其中一个原因是一些 ISP 商 在后台使用了隐形的代理服务器,使部分网页无法正常显示。假如你多次按“F5”键也无法刷新网页&…...
解决 “fatal: Could not read from remote repository.
问题描述: 在使用Git将本地仓库推送到远程仓库或将远程仓库克隆到本地的时候,发生了如下错误:“fatal: Could not read from remote repository.” 原因分析: 出现这错误一般是以下两种原因: 客户端与服务端未生成 …...
TypeScript知识点总结
typescript是js的超集,目前很多前端框架都开始使用它来作为项目的维护管理的工具,还在不断地更新,添加新功能中,我们学习它,才能更好的在的项目中运用它,发挥它的最大功效 let b: null nulllet c: null …...
Map简单介绍
Map 是 Java 中用于存储键值对的接口,它是一个抽象类,有多个实现类,如 HashMap、TreeMap、LinkedHashMap 等。我将为你提供一些关于 Map 接口的源码解读。 首先,Map 接口的定义如下: public interface Map<K, V&g…...
Linux文本处理工具和正则表达式
Linux文本处理工具和正则表达式 一.查看、截取和修改文本的工具 1.查看文本的工具 cat 最常用的文件查看命令;当不指明文件或者文件名为一杠’-时,读取标准输入。 cat [OPTION]... [FILE]... -A:显示所有控制符(tab键:^I;行结束符:$) -…...
【WebRTC---源码篇】(二十三)JitterBuffer
PacketBuffer packetbuffer类中重要的一些变量 // buffer_.size() and max_size_ must always be a power of two.const size_t max_size_;//能存储的最大元素个数// The fist sequence number currently in the buffer.uint16_t first_seq_num_ RTC_GUARDED_BY(crit_);//这个…...
基于SpringBoot+Vue的在线考试系统设计与实现(源码+LW+部署文档等)
博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…...
用Rust实现23种设计模式之 外观模式
关注我,学习Rust不迷路!! 外观模式是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。以下是外观模式的优点和使用场景: 优点: 简化客户端代码:外观模式…...
使用一个python脚本抓取大量网站【1/3】
一、说明 您是否曾经想过抓取网站,但又不想为像Octoparse这样的抓取工具付费?或者,也许您只需要从网站上抓取几页,并且不想经历设置抓取脚本的麻烦。在这篇博文中,我将向您展示我如何创建一个工具,该工具能…...
Session与Cookie的区别(五)
储存状态的方式 小明的故事说完了,该来把上面这一段变成网络的实际案例了。其实在网络世界中问题也是一样的。 前面已经提到过我们会把状态存在 Cookie 里面,让 Request 之间能够变得有关联。 假设我们今天要来做一个会员系统,那我要怎么知道…...
【Linux】网络编程套接字
目录 1 预备知识 1.1 IP地址 1.2 端口号 1.3 TCP协议和UDP协议 1.4 网络字节序 2 socket 编程接口 2.0 socket 常见 API 2.1 socket 系统调用 2.2 bind 系统调用 2.3 recvfrom 系统调用 2.4 sendto 系统调用 2.5 listen 系统调用 2.6 accept 系统调用 2.7 con…...
【C++】语法小课堂 --- auto关键字 typeid查看实际类型 范围for循环 空指针nullptr
文章目录 🍟一、auto关键字(C11)🍩1、auto的简介🍩2、auto的使用细则🚩auto与指针和引用结合起来使用🚩 在同一行定义多个变量 🍩3、auto不能推导的场景1️⃣auto不能作为函数的参数…...
Vercel 部署的项目发现APIkeys过期了怎么办
好不容易部署的Vercel,发现APIkeys过期了显示,查了查资料发现只要更新下新的apikeys,然后再重新部署下就好了。 重新设置APIkeys 1.1. 进去 Vercel 项目内部控制台,点击顶部的 Settings 按钮; 1.2 点击环境变量Enviorn…...
【HMS Core】推送报错907135701、分析数据查看
【关键字】 HMS、推送服务、分析服务 【问题描述1】 集成推送服务,获取Token时报错 907135701: scope list empty 【解决方案】 907135701OpenGW没有配置Scope 1、您可以检查下网络是否有问题,手机是否可以正常连接互联网 2、查看推送服务开关是否正…...
Air32 | 合宙Air001单片机内部FLASH读写示例
Air32 | 合宙Air001单片机内部FLASH读写示例 代码已经通过测试,开发环境KEIL-MDK 5.36。 测试代码 void FLASH_RdWrTest(void) {uint32_t Address;uint32_t PageReadBuffer[FLASH_PAGE_SIZE >> 2];uint32_t PageWriteBuffer[FLASH_PAGE_SIZE >> 2];mem…...
C语言基本语法-第一章
C 语言基本语法 语句 C 语言的代码由一行行语句(statement)组成。语句就是程序执行的一个操作命令。C 语言规定,语句必须使用分号结尾,除非有明确规定可以不写分号。 int x 1;上面就是一个变量声明语句,声明整数变…...
八、Spring 整合 MyBatis
文章目录 一、Spring 整合 MyBatis 的关键点二、Spring 整合 MyBatis 的步骤2.1 创建 Maven 项目,并导入相关依赖2.2 配置 Mybatis 部分2.3 配置 Spring 部分2.3 配置测试类 一、Spring 整合 MyBatis 的关键点 1、 将 Mybatis 的 DataSource (数据来源)的创建和管理…...
Flutter Flar动画实战
在Flare动面出现之前,Flare动画大体可以分为使用AnimationController控制的基础动画以及使用Hero的转场动画,如果遇到一些复杂的场景,使用这些动画方案实现起来还是有难度的。不过,随着Flutter开始支持Flare矢量动面,Flutter的动画开发也变得越来越简单。事实上,Flare动画…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
