Spring-Bean的生命周期概述
Bean的生命周期概述
入门使用的Spring代码:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();
思考问题:
1、第一行代码都做了哪些事情?
2、第二行代码getBean()如何实现的?返回的UserService对象和new创建的对象有什么区别?
在新版的Spring MVC和Spring Boot的底层主要用的都是AnnotationConfigApplicationContext:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = (UserService) context.getBean("userService");
userService.test();
注意:AppConfig.class和spring.xml的本质是一样的,都表示Spring的配置,类比两种写法:
spring.xml中的内容为:
<context:component-scan base-package="com.gax"/>
<bean id="userService" class="com.gax.service.UserService"/>AppConfig中的内容为:
@ComponentScan("com.gax")
public class AppConfig {@Beanpublic UserService userService(){return new UserService();}
}
目前spring.xml这种方式已经很少见了;更多的是使用Spring MVC或者Spring Boot,这两种也是基于spring.xml这种方式,在内部创建一个ApplicationContext,但是也有区别:
1、Spring MVC创建的是XmlWebApplicationContext,和ClassPathXmlApplicationContext类似,都是基于XML配置的
2、Spring Boot创建的是AnnotationConfigApplicationContext
后续重点学习研究的是AnnotationConfigApplicationContext这一种
Spring中是如何创建一个对象?
AnnotationConfigApplicationContext可以简单理解为创建Java对象,当调用context.getBean("userService")方法时创建一个对象。那么问题来了,方法内部如何知道"userService"对应的是UserService类呢?
可以分析出来AnnotationConfigApplicationContext的构造方法做的一些事情:
1、解析AppConfig.class,得到扫描路径
2、遍历扫描路径下的所有Java类,如果类上面有@Component、@Service等注解,那么Spring就会把这个类记录下来,存放在一个Map里,比如像Map<String, Class>,Spring源码中叫BeanDefinitionMap
3、Spring根据规则生成当前类的beanName,作为存入Map时的key,当前类作为存入Map时的value(Spring中的beanName默认是类名首字母小写)
Bean的创建过程
Spring到底是如何来创建一个Bean的呢,也就是Bean创建的生命周期。大致流程如下:
1、利用该类的构造方法来实例化得到一个对象(有多个构造方法时,Spring会做出选择,推断构造方法)
2、得到一个对象后,Spring会判断该对象中是否存在被@Autowired注解了的属性,把这些属性找出来并由Spring进行赋值,依赖注入
3、依赖注入后,Spring会判断该对象是否实现了BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示当前对象必须实现该接口中所定义的setBeanName()、setBeanClassLoader()、 setBeanFactory()方法,那Spring就会调用这些方法并传入相应的参数,Aware回调
4、Aware回调后,Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法,初始化前
5、Spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法,那Spring就会调用当前对象中的afterPropertiesSet()方法,初始化
6、Spring会判断当前对象需不需要进行AOP,如果不需要那么Bean就创建完了,如果需要进行AOP,则会进行动态代理并生成一个代理对象做为Bean,初始化后
注意:不用AOP时,Bean就是构造方法创建的普通对象;需要AOP时,Bean是代理类实例化的对象
Bean对象创建完成后,如果是单例Bean就放在Map里,下次可以直接从Map中直接获取(Spring源码中Map就是单例池);如果是原型Bean就不用放在Map里,下次重新创建
推断构造方法
选择构造方法的判断逻辑:
1、只有一个构造方法,无论是否有参,Spring都会选择这个
2、有多个构造方法时,Spring会选择无参的构造方法(无参本身就是一种默认)
没有无参构造方法,且构造方法上面都没有@Autowired注解时报错,Spring不知道选择哪一个
没有无参构造方法,但是某个构造方法上面添加了@Autowired注解,Spring选择这一个构造方法
注意:Spring选择有参构造方法时,Spring会先根据参数类型,类型相同再根据参数名字去找Bean对象,类型和名字都找不到就报错
推断构造方法:确定用哪个构造方法,确定入参的Bean对象
AOP大致流程
判断当前Bean对象需不需要进行AOP:
1、找出所有的切面Bean
2、遍历切面中的每个方法,看是否写了@Before、@After等注解
3、如果写了,则判断所对应的Pointcut是否和当前Bean对象的类匹配
4、如果匹配则表示当前Bean对象有匹配的的Pointcut,需要进行AOP
利用cglib进行AOP的大致流程:(cglib说白了就是父子类)
1、生成代理类XXServiceProxy,代理类继承XXService
2、代理类中重写了父类的方法
3、代理类中有一个target属性,该属性的值为被代理对象
(这里的被代理对象:是推断构造方法实例化的对象,完成了依赖注入、初始化等)
4、代理类中的方法被执行时,先执行before的切面逻辑,再执行target.目标方法
注意:XXServiceProxy是代理类,它实例化出来的是代理对象;target是被代理对象
思考:代理对象的属性是null,没有进行依赖注入,为什么?
没有必要,大部分情况用不到,需要用的话也可以通过target获取
Spring事务
在某个方法上加了@Transactional注解后,就表示该方法在调用时会开启Spring事务,而这个方法所在的类所对应的Bean对象会是该类的代理对象。
1、判断当前执行的方法是否存在@Transactional注解
2、如果存在,则利用事务管理器(TransactionMananger)新建一个数据库连接
3、修改数据库连接的autocommit为false
4、执行target.目标方法,业务逻辑的sql
5、执行完之后没有异常则提交,否则回滚
事务失效的场景分析:
1、调用目标方法的是否为代理类,使用代理类调用时才有切面的逻辑
2、是否使用的同一个事务管理器(或者说是否同一个数据库连接)
相关文章:
Spring-Bean的生命周期概述
Bean的生命周期概述 入门使用的Spring代码: ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext("spring.xml"); UserService userService (UserService) context.getBean("userService"); userService.test(); …...
SENet 学习
ILSVRC 是一个比赛,全称是ImageNet Large-Scale Visual Recognition Challenge,平常说的ImageNet比赛指的是这个比赛。 使用的数据集是ImageNet数据集的一个子集,一般说的ImageNet(数据集)实际上指的是ImageNet的这个子…...
目前和未来的缓存构建
说起来可能有点反直觉,有时候不运行反而可以帮助我们加快速度,这正是网络浏览器运行的指导原则。不必在页面上加载所有内容,缓存的元素已经存在,不需要每次访问网站或网页时都重新加载。页面加载速度越快,浏览器的工作…...
aws亚马逊云免费账号代充值!!!什么是 AWS Lambda?
AWS Lambda 是一项计算服务,可使您无需预配置或管理服务器即可运行代码。 Lambda 在可用性高的计算基础设施上运行您的代码,执行计算资源的所有管理工作,其中包括服务器和操作系统维护、容量调配和弹性伸缩和记录。使用 Lambda,您…...
《从零开始大模型开发与微调 :基于PyTorch与ChatGLM》简介
内 容 简 介 大模型是深度学习自然语言处理皇冠上的一颗明珠,也是当前AI和NLP研究与产业中最重要的方向之一。本书使用PyTorch 2.0作为学习大模型的基本框架,以ChatGLM为例详细讲解大模型的基本理论、算法、程序实现、应用实战以及微调技术,…...
【LeetCode】102. 二叉树的层序遍历
题目链接 文章目录 Python3方法一: 广度优先搜索 (BFS) ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法二: 深度优先搜索 (DFS) ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯ C方法一: 广度优先搜索 (BFS) ⟮ O ( n ) ⟯ \lgroup O(n…...
golang连接池检查连接失败时如何重试
在Go中,可以通过使用database/sql包的DB类型的Ping方法来检查数据库连接的可用性。如果连接检查失败,可以选择进行重试。以下是一个简单的示例代码,演示了如何在连接检查失败时进行重试: import ("database/sql""…...
从JavaScript到Rust的三年时间小结
Rust 是一种注重安全性、速度和并发性的系统编程语言。它能编译成高效的本地代码,无需垃圾回收即可访问内存等底层资源,同时还能防止分隔故障。 作者讨论了他们几年来用 Rust 构建大型应用程序和库的经验。他们发现 Rust 的借用检查器和类型系统有助于减…...
【Python机器学习】零基础掌握VotingRegressor集成学习
如何更准确地预测房价? 想象一下,你是一名房地产分析师,你的任务是预测一个小区的未来房价。这看似简单,但实际上,房价受到多种因素的影响,如地理位置、房屋面积、周围设施等。你可能会使用线性回归模型来进行预测,但是你会发现,尽管模型的准确性还可以,但还是存在一…...
云计算模式的区域LIS系统源码,基于ASP.NET+JQuery、EasyUI+MVC技术架构开发
云计算模式的区域LIS系统源码 云LIS系统源码,自主版权 LIS系统是专为医院检验科的仪器设备能与计算机连接。可通过LIS系统向仪器发送指令,让仪器自动操作和接收仪器数据。并快速的将检验仪器中的数据导入到医生工作站中进行管理,且可将检验结…...
面向对象设计原则之接口隔离原则
目录 定义接口隔离原则与单一职责原则示例 定义 接口隔离原则,全称为 Interface Segregation Principle,缩写ISP。 原始定义:Clients should not be forced to depend upon interfaces that they don’t use。 翻译: 不应该强行…...
haproxy 负载均衡
haproxy负载均衡 haproxy:基于C语言开发的开源软件 支持高性能的tcp和http负载均衡器,工作中用的版本1.5.9 haproxy功能:主要用于高并发的web站点,工作原理和nginx、lvs都一样 haproxy缺点: 单节点部署,单实例运行。代…...
在el-dialog中使用tinymce 点击工具栏下拉框被遮挡
在el-dialog中使用tinymce控件时,会出现点击工具栏下拉框出现在弹窗下一层,审查元素之后发现是tinymce的下拉框z-index优先级低于el-dialog的z-index导致的,所以需要增加tinymce的下拉框的z-index值。 通过审查元素得到,需要修改t…...
CloudQuery + StarRocks:打造高效、安全的数据库管控新模式
随着技术的迅速发展,各种多元化的数据库产品应运而生,它们不仅类型众多,而且形式各异,国产化数据库千余套,开源数据库百余套 OceanBase 、PolarDB 、StarRocks…还有一些像 Oracle、MySQL 这些传统数据库。这些数据库产…...
各类统计模型R语言的详细使用教程-R语言的线性回归使用教程
各类统计模型R语言的详细使用教程-R语言的线性回归使用教程 前言R语言的线性回归代码示例回归诊断误差项正态qq图内学生化残差外学生化残差线性关系异常值的发现、处理帽子矩阵的方法DFFITS 准则Cook统计量COVRATIO准则多重共线性summaryKlein判别法特征根法条件指数法方差膨胀…...
点云从入门到精通技术详解100篇-基于尺度统一的三维激光点云与高清影像配准
目录 前言 研究现状 三维激光点云与影像配准研究现状 点云配准研究现状...
<蓝桥杯软件赛>零基础备赛20周--第2周
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...
CMake多文件构建初步
前面学习了cmake,不熟悉,只是记录了操作过程;下面再继续; 略有一点进步,增加一个代码文件,之前是1个代码文件; 如下图,prj是空文件夹, CMakeLists.txt如下;…...
游戏研发的解决方案有哪些?
游戏研发的解决方案可以根据不同的需求和情境而有所不同,以下是一些常见的游戏研发解决方案: 游戏引擎: 游戏引擎是游戏研发的基础,它提供了开发游戏所需的核心功能,如图形渲染、物理引擎、音效管理、动画等。一些流行…...
Bayes决策:身高与体重特征进行性别分类
代码与文件请从这里下载:Auorui/Pattern-recognition-programming: 模式识别编程 (github.com) 简述 分别依照身高、体重数据作为特征,在正态分布假设下利用最大似然法估计分布密度参数,建立最小错误率Bayes分类器,写出得到的决…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...
