Spring-Bean的生命周期概述

Bean的生命周期概述

入门使用的Spring代码:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

思考问题:

1、第一行代码都做了哪些事情?

2、第二行代码getBean()如何实现的?返回的UserService对象和new创建的对象有什么区别?

在新版的Spring MVCSpring Boot的底层主要用的都是AnnotationConfigApplicationContext

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = (UserService) context.getBean("userService");
userService.test();

注意:AppConfig.classspring.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、是否使用的同一个事务管理器(或者说是否同一个数据库连接)

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

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

相关文章

Node.js的readline模块 命令行交互的模块

Node.js是一个非常流行的JavaScript运行时环境&#xff0c;它提供了许多内置模块来帮助我们开发应用程序。其中之一是readline模块&#xff0c;它提供了一种简单的方法来读取用户输入并进行交互。 本文将详细介绍readline模块的API和使用案例&#xff0c;并附有代码注释。 re…

财报解读:步步逼近ChatGPT,科大讯飞即将迎来全面爆发?

10月份&#xff0c;科大讯飞进入新的成果验证节点。 一是进一步透露AI进展的财报发布。三季报显示&#xff0c;科大讯飞仍然保持较为稳健的发展步伐&#xff0c;营收始终处于增长状态&#xff0c;对讯飞星火认知大模型的应用成果&#xff0c;进行了进一步揭示。基于此&#xf…

基于LSTM encoder-decoder模型实现英文转中文的翻译机器

前言 神经网络机器翻译(NMT, neuro machine tranlation)是AIGC发展道路上的一个重要应用。正是对这个应用的研究&#xff0c;发展出了注意力机制&#xff0c;在此基础上产生了AIGC领域的霸主transformer。我们今天先把注意力机制这些东西放一边&#xff0c;介绍一个对机器翻译…

文心一言简单体验

百度正式发布文心一言&#xff0c;文心一言 这里的插件模式挺有意思&#xff1a; 测试了一下图解说明&#xff0c;随意上传了一张图片&#xff1a; 提供图解让反过来画&#xff0c;抓住了部分重点&#xff0c;但是还是和原图有比较大的差异&#xff01; 百宝箱 暂未逐个体验&am…

2023年9月青少年软件编程(Python) 等级考试试卷(五级)

2323.9青少年软件编程&#xff08;Python&#xff09; 等级考试试卷&#xff08;五级&#xff09; 分数&#xff1a; 100 题数&#xff1a; 38 一、 单选题(共 25 题&#xff0c; 共 50 分) 1. 阅读以下代码&#xff0c; 程序输出结果正确的选项是&#xff1f; &#xff08; &a…

Linux ————​文件权限

&#xff08;一&#xff09;文件权限 基础补充 文件基本属性&#xff08;Linux中万物皆是文件&#xff09;文件是操作系统用来存储信息的基本结构&#xff0c;是一组信息的集合。文件通过文件名来唯一标识。Linux中的文件名称最长允许255个字符&#xff0c;这些字符可用A~Z、0…

Vuex、localStorage和sessionStorage:如何选择合适的数据存储方式?

&#x1f31f;Vuex、localStorage和sessionStorage&#xff1a;如何选择合适的数据存储方式&#xff1f; 在Web应用开发中&#xff0c;我们经常需要管理和存储数据。而在Vue应用中&#xff0c;我们通常会遇到以下问题&#xff1a;如何管理应用程序中的状态和数据&#xff1f;如…

SpringBoot篇---第五篇

系列文章目录 文章目录 系列文章目录一、Spring Boot 的核心配置文件有哪几个&#xff1f;它们的区别是什么&#xff1f;二、如何集成 Spring Boot 和 ActiveMQ&#xff1f; 一、Spring Boot 的核心配置文件有哪几个&#xff1f;它们的区别是什么&#xff1f; Spring Boot 的核…

【JAVA学习笔记】46 - (43)第十一章作业

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter11/src/com/yinhai/homework11 1.枚举类 1.创建一个Color枚举类 2.有RED,BLUE,BL ACK,YELLOW,GREEN这个五个枚举值/对象: 3. Color有三 个属性redValue, greenValue, blueValue, 4.创建构…

Python的Matplotlib库:数据可视化的利器

引言&#xff1a; Matplotlib是一款强大的Python库&#xff0c;专为数据可视化而设计。无论是绘制折线图、散点图、柱状图还是饼图&#xff0c;Matplotlib都能提供灵活且易于操作的绘图方法。 1. Matplotlib简介 Matplotlib是Python中最流行的绘图库之一&#xff0c;被广泛应…

Kafka To HBase To Hive

目录 1.在HBase中创建表 2.写入API 2.1普通模式写入hbase&#xff08;逐条写入&#xff09; 2.2普通模式写入hbase&#xff08;buffer写入&#xff09; 2.3设计模式写入hbase&#xff08;buffer写入&#xff09; 3.HBase表映射至Hive中 1.在HBase中创建表 hbase(main):00…

电商行业的代言人合伙人模式:创新营销策略的新革命

在当今的电商行业中&#xff0c;传统的营销策略已经无法满足品牌日益增长的需求。为了在激烈的市场竞争中脱颖而出&#xff0c;品牌需要寻找更加创新和有效的营销策略。代言人合伙人模式作为一种新型的营销策略&#xff0c;结合了代言人和合伙人模式的特点&#xff0c;为电商行…

Python学习笔记第七十二天(Matplotlib imread)

Python学习笔记第七十二天 Matplotlib imread读取图像数据修改图像裁剪图像图像颜色 后记 Matplotlib imread imread() 方法是 Matplotlib 库中的一个函数&#xff0c;用于从图像文件中读取图像数据。 imread() 方法返回一个 numpy.ndarray 对象&#xff0c;其形状是 (nrows,…

点击弹出实现模拟百度那样子

<uni-section title"输入框示例" type"line" padding><view class"dialog-box"><text class"dialog-text">输入内容&#xff1a;{{ value }}</text></view><button class"button" type&qu…

PL/SQL工具下载地址

https://www.allroundautomations.com/registered-plsqldev/ 选择需要下载的版本即可

LuaTable转C#的列表List和字典Dictionary

LuaTable转C#的列表List和字典Dictionaty 介绍lua中创建表测试lua中list表表转成List表转成Dictionary 键值对表表转成Dictionary 多类型键值对表表转成Dictionary 总结 介绍 之前基本都是从C#中的List或者Dictionary转成luaTable&#xff0c;很少会把LuaTable转成C#的List或者…

Android managed configurations(设置受管理的配置)

文章目录 Android managed configurations(设置受管理的配置)远程配置概览定义托管配置检查托管配置读取和应用托管配置监听托管配置更改向 EMM 发送托管配置反馈键控应用状态的组成部分发送托管配置反馈报告已解决的错误为您的应用添加对键控应用状态的支持第 1 步:将 Google…

微信小程序通过startLocationUpdate,onLocationChange获取当前地理位置信息,配合腾讯地图解析获取到地址

先创建个getLocation.js文件 //获取用户当前所在的位置 const getLocation () > {return new Promise((resolve, reject) > {let _locationChangeFn (res) > {resolve(res) // 回传地里位置信息wx.offLocationChange(_locationChangeFn) // 关闭实时定位wx.stopLoc…

深入浅出排序算法之简单选择排序

目录 1. 原理和执行流程 2. 代码实现 3. 性能分析 4. 双向选择排序&#xff08;了解&#xff09; 1. 原理和执行流程 选择排序包含了堆排序和简单选择排序。 每一次从无序区间选出最大&#xff08;或最小&#xff09;的一个元素&#xff0c;存放在无序区间的最后&#xff0…

Echarts-3D柱状图

通过Echarts的echarts.graphic.extendShape实现真正的3D柱状图 思路就是通过调整顶部面(CubeTop)、左侧面(CubeLeft)、右侧面(CubeRight)来决定柱状图的宽窄 建议优先调整顶部面&#xff0c;一般c1不需要动 // echarts-3D-bar-config.js import Vue from "vue";cons…