spring源码 bean的生命周期

news2024/11/28 19:52:19

问:谈谈对spring的理解

答:总分思想,先说对spring的总体认知,再说小一点的比如:IOC,AOP,IOC如何实现,生命周期,循环依赖等

IOC:控制反转

xml和注解创建对象的流程

xm文件通过IO流读取到内存,再通过SAX和dom4j解析成一个document对象,里面有很多node节点,每个节点包含很多key和value值,将这些kv分别放到某个具体对象中去

注解,通过反射获得class对象,如果是@service等注解就直接创建bean

创建bean完整过程

通过xml或者注解获取到的bean的定义信息放进容器中的BeanDefinitionMap,

BeanDefinitionReader,用来读取xml和注解,对格式进行规范和约束,读取Bean定义信息后存进BeanDefinition。通过BeanFactoryPostProcessor来对BeanFactory进行修改(如进行占位符的替换,将配置文件中的具体值替换掉bean参数中的占位符),此时拥有了更加完整的BeanDefinition对象,可以进行创建bean,然后使用bean,销毁bean。

反射创建对象的步骤

PostProcessor 增强器

作用:提供额外的扩展功能,

常用的是BeanFactoryPostProcessor(针对Bean工厂)和BeanPostProcessor(针对Bean),用来解析BeanDefinition对象,使得变成一个完整的BD对象

BeanFactory

通过BeanFactory能对容器中的BeanDefinition进行修改

Spring工厂最底层的类就是这个BeanFactory接口,他定义了工厂的基本操作,也就是存取,也就是getBean这些操作都是这个接口而生

BeanDefinitionRegistryPostProcessor

注册bean

bean的生命周期

概念:从对象的创建到使用到销毁的过程

实例化和初始化的区别

bean对象分为自定义对象和容器对象(容器对象如BeanFactory,ApplicateContest等)两种,

实例化是在堆空间中申请空间,对象的属性值一般是默认值,用反射创建对象的过程(由createBeanInstance这个方法实现)

初始化:先对自定义属性赋值(populateBean方法内用set方法进行赋值),再对容器对象属性赋值(检测aware相关接口并设置依赖),这里aware的作用是提供一个统一判断的标记:即没实现aware接口的对象就是属性都是自己定义的,实现了aware接口的属性值是容器对象,需要调用容器的getset方法来设置属性(invokeAwareMethods里面做统一判断)。如果不设计这样一个aware接口,就需要在每个属性被赋值时都判断一下 当前属性是否是容器对象。

至此,对象的创建和属性赋值已完成,已经得到了一个普通对象,但是对象还不能使用,因为spring要考虑扩展性。

BeanPostProcessor接口包含2个方法

1.

前置处理方法

2.

后置处理方法

从方法名字可以看出,这里的前置和后置是针对initialization初始化方法来说的,这个初始化方法叫invokeInitMethods,他会判断bean是否实现了initalizingBean接口,实现了就会调用这个接口的afterPropertesSet方法进行一些初始化操作

BeanPostProcessor接口用途:AOP

AOP底层实现原理:动态代理(2种实现方式:jdk和cglib)

BeanPostProcessor接口的一个重要实现类:AbstractAutoProxyCreator,用来创建代理对象。

在这个实现类中,前置方法中直接return bean了,没做其他操作

但是在其后置方法中是有逻辑处理的

进入这个wrapIfNecessary方法,在方法尾部找到一句有关创建代理的代码:

进去这个createProxy方法,找到真正创建代理对象的代码:

getProxy方法:

再进入getProxy方法:发现是AopProxy接口的抽象方法,所以点击查看实现:

可以选择一种代理方式创建代理对象。

注意:AOP是IOC整体流程中的一个扩展点

此时,Bean对象已经创建好了,可以使用bean对象了

销毁bean对象

时机:关闭容器时才会销毁

学习源码的方法论

BeanFactory和FactoryBean的区别

BeanFactory:不指根接口,而是bean对象创建的整体流程,Bean的生命周期是一个完整的标准化的流程,相对比很麻烦

Factorybean :私人定制

静态代理和动态代理

代理的目的是在调用被代理对象的方法时,能在方法执行前后加上自定义操作

静态代理

分为抽象主题对象、真实主题对象、代理主题对象。

作用

在调用被代理对象的方法时,能在方法执行前后加上自定义操作

缺点

由于一个代理主题对象可能需要代理多个真实主题对象,所以要从真实主题对象中抽取出抽象接口,所以偶联程度太高,要在真实主题对象中加一个方法,就要在抽象主题对象中定义这个方法,并且代理主题对象都要实现这个方法。

当代理对象同时代理多个真实主题对象,由于多个真实主题对象中会有大量不同的方法,都必须在抽象接口声明,并且每个真实主题对象都要实现所有的方法,十分臃肿。

动态代理

造成静态代理代码臃肿的原因是:抽象主题对象调用真实主题对象中的方法时,利用的是多态性,在调用前,给代理对象传的是哪个子类,调用的方法就调用的是哪个子类中实现的。这样需要从所有被代理的类中抽象出一个公共接口,包含所有方法,即所有被代理类都要实现这个接口。

???为什么代理对象也要实现这个抽象接口?

动态代理通过Proxy.newProxyInstance 来创建代理对象

使用反射的方式来调用被代理类的方法,动态代理分3个角色: 抽象主题角色真实主题角色增强主题角色

其中的增强主题角色就是实现了使用反射来调用被代理角色的方法。

增强主题角色只需要实现InvocationHandler,使用其中的invoke方法调用被代理者的方法。只需要将被代理对象的方法和方法参数传递给invoke方法即可

类层次结构

UserService是公共接口

UserServiceImpl是被代理类

LogHandler是实现在代理对象的方法的前后添加自定义操作的类,实现了InvocationHandler接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961364.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RVC-AI声音克隆-你的声音不再是唯一

RVC是一个基于Hubert模型的AI语音转换工具,可以实现男女声的互换和降噪。 本文将要介绍RVC的安装和使用方法 首先感谢花儿不哭大佬带来的RVC声音克隆 花儿不哭: 花儿不哭的个人空间-花儿不哭个人主页-哔哩哔哩视频 (bilibili.com) RVC下载地址&#xff…

Elastic 线下 Meetup 将于 2024 年 8 月 25 号在南京举办

2024 Elastic Meetup 南京站活动,由 Elastic、华博集团、新智锦绣联合举办,现诚邀广大技术爱好者及开发者参加。 时间地点 2024 年 8 月 25 日 13:30-18:00 活动地点 南京雨花台区花神大道 17 号 华博智慧园 7 楼 智慧岛会议厅 报名地址 2024 Elasti…

稳态准直太阳光模拟器仪器光伏电池组件IV测试

太阳能模拟器电池IV测试仪、单体测试仪,配备匹配标准的AAA Class稳态太阳能模拟器及相关测试附件,可对太阳能电池片的IV性能进行测量、分级分选等; 介绍 AAA class太阳光模拟器整合完整的IV测量系统,针对各种太阳能电池的性能&a…

Redis学习[3] ——持久化

四. Redis 持久化 4.1 Redis 如何保证数据不丢失? 由于Redis的数据是保存在内存中,而内存中的数据会在Redis重启后丢失。因此,为了保证数据不丢失,Redis实现了数据持久化的机制。这个机制会将内存中的数据存储到磁盘&#xff0c…

【JVM】内存区域、垃圾回收和内存分配策略

文章目录 运行时数据区域程序计数器Java虚拟机栈栈帧Java堆方法区运行时常量池 直接内存 揭秘对象对象的内存布局对象头实例数据对齐填充 对象的访问定位 OutOfMemoryError异常Java堆溢出虚拟机栈和本地方法栈溢出方法区和运行时常量池溢出本机直接内存溢出 对象已死&#xff1…

剪画小程序:什么?刷到陈楚生的视频转换成音频这么简单!

在这个信息爆炸的时代,我们常常在各种平台上刷到自己喜欢的视频,尤其是那些有陈楚生精彩表现的视频。 而有时候,我们可能只想单纯地聆听他的歌声,不想被视频画面所干扰。 你是否曾想过,把刷到的陈楚生的视频转换成音频…

爬虫实战:数据请求与解析(4种不同方式的数据解析)

根据目标网页的结构和内容的复杂性,我们可以选择多种不同的库或工具来提取所需的数据。本文将通过实战案例,介绍如何使用正则表达式、BeautifulSoup、pyquery、XPath 这四种方法从网页中解析数据。 一、准备工作 1.1 确定目标 我们测试的数据是崔庆才…

项目:基于gRPC进行项目的微服务架构改造

文章目录 写在前面基本使用封装客户端封装服务端Zookeeper 写在前面 最近学了一下gRPC进行远程调用的原理,所以把这个项目改造成了微服务分布式的架构,今天也是基本实现好了,代码已提交 这里补充一下文档吧,也算记录一下整个过程…

029-GeoGebra中级篇—一般对象之复数

GeoGebra 支持复数运算和可视化,允许用户在复平面上进行各种操作。用户可以定义复数、进行加减乘除等基本运算,并使用 GeoGebra 的图形工具在复平面上绘制复数的表示,探索复数的几何意义。这使得 GeoGebra 成为学习和研究复数及其应用的有力工…

合并K个有序链表

题目 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例1: 输入: 输出: 示例2: 输入: 输出: 示例3: 输入&…

【Vue3】组件生命周期

【Vue3】组件生命周期 背景简介开发环境开发步骤及源码 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本…

Java从入门初级开发到精通百万级架构师:全套教程 | 学习路线(免费白嫖)

以下是一篇关于Java编程从入门到精通的文章,旨在帮助初学者和有一定基础的程序员系统地学习Java语言及其应用: Java语言编程从入门到精通:Java从入门到项目实战全套教程 Java作为一种广泛使用的编程语言,拥有强大的生态系统和丰富…

「 LaTeX 」如何修改公式底纹颜色

一、前言 小白在论文返修过程中,需要标注出部分公式的修正,因此用到这个代码指令。 二、技术实现 指令代码如下: \mathcolorbox{yellow}{ TEXT } 三、实例 \begin{figure*} \begin{equation} \centering \begin{aligned}\begin{bmatrix}{…

食家巷胡麻饼酥脆滋味,难以抗拒

在美食的浩瀚星空中,食家巷胡麻饼宛如一颗璀璨的明珠,散发着独特而迷人的魅力。食家巷胡麻饼,那金黄酥脆的外皮,宛如一层精心雕琢的铠甲,闪烁着诱人的光泽。上面点缀着密密麻麻的胡麻籽,犹如繁星点点&#…

终端pip安装包后,Pycharm却导入失败?新手别慌,3招搞定!

很多小伙伴在学习Python的过程中,都会遇到这种情况:明明在终端用pip安装好了需要的包,但在Pycharm中导入时却报错。难道是安装姿势不对? 例如在cmd中已经有了pandas,但是去pycharm中导入pandas显示没有 先别急着怀疑人生,这很可能是因为pip安装包的路径和Pycharm项目使用…

Docker容器下面home assistant忘记账号密码怎么重置?

环境: docker ha 问题描述: Docker容器下面home assistant忘记账号密码怎么重置? 解决方案: 你可以按照以下步骤来找回或重置密码: 方法一 (未解决) 停止并删除当前的Home Assistant容器(确保你已经保…

设计模式16-代理模式

设计模式16-代理模式 动机定义与结构模式定义结构 代码推导特点应用总结实例说明1. 远程代理2. 虚拟代理3. 保护代理4. 智能引用代理 动机 在面向对象系统中有一些对象由于某种原因比如对象创建的开销很大或者某些操作需要安全控制,或者需要进程外的访问等情况。直…

Mac电脑流氓软件怎么卸载不了 MacBook删除恶意软件 电脑流氓软件怎么彻底清除

对于Mac用户来说,尽管MacOS系统以其较高的安全性而闻名,但依然不可避免地会遭遇流氓软件或恶意软件的困扰。本文将详细介绍Mac电脑流氓软件怎么卸载,Mac电脑如何移除移除恶意软件,确保你的设备运行安全、流畅。 一、Mac电脑流氓软…

【论文共读】【翻译】【GAN】Generative Adversarial Nets

论文原文地址:https://arxiv.org/pdf/1406.2661 翻译:Generative Adversarial Nets 生成对抗网络 0. 摘要 提出了一种新的对抗过程估计生成模型的框架,其中我们同时训练两个模型:一个是捕获数据分布的生成模型G,另一…

【基础夯实】TCP/IP 协议是怎么控制数据收发

【基础夯实】TCP/IP 协议是怎么控制数据收发 网址输入到页面完整显示,对于此问题,粗略的解释可以分为以下几个步骤: 客户端通过 HTTP 协议对数据进行一次包装通过 DNS 服务器(本地无缓存)解析网址的 ip 地址通过 TCP…