spring底层原理初探

news/2024/5/17 17:36:39/文章来源:https://blog.csdn.net/zhenghuishengq/article/details/126825234

一,spring原理初探

1,bean的创建生命周期

userService.class --> 推断构造方法 --> 实例化对象 --> 依赖注入(属性填充) --> 初始化前(@PostConstruct) --> 初始化 (Initializingbean) --> 初始化后(AOP,bean的后置处理器) --> 代理对象 --> 存入到这个单例池Map里面 -->bean

1.1,获取上下文的方式

//通过注解的方式获取这个上下文,在这个类上面需要添加一个@ComponentScan("")
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
//通过xml的方式获取这个上下文
ClassPathXMlConfigApplicationContext xc = new ClassPathXMlConfigApplicationContext(spring.xml);

从spring容器里面获取对象。

//单例对象需要存放在单例池里面,多例的话不需要//一级缓存里面获取,以及缓存Map<"userService",UserService>
UserService us = (UserService)ac.getBean("userService");
UserService newUs = new UserService();
UserService us1 = (UserService)ac.getBean("userService");
UserService us2 = (UserService)ac.getBean("userService");

从容器中获取对象和这个new 对象的区别如下:

从容器中获取的对象结果了依赖注入,里面的属性有值,这个new的对象没有

1.2,推断构造方法:

1,如果类里面只有一个构造方法,那么只用那一个

2,如果有多个构造方法,那么就会用默认的无参构造方法

3,如果需要指定用哪一个构造方法,可以在指定的方法上面加一个@Autowared注解。

1.3,实例化Bean

1,通过type类型寻找,遍历以及缓存里面的全部value,判断是不是UserService这个对象实例

2,通过name名字寻找,一级缓存里面寻找,key/value

1.4,属性填充

给里面的属性上面加了注解的变量进行一个属性填充,如@Autowared。就是判断方法里面有没有哪个属性上面有这个注解,如果有,就进行一个属性填充。
在这里插入图片描述

1.5,初始化前

会去判断一下这个方法里面,有没有属性加了一个@PostConstruct这个注解。这个方法可以在spring容器初始化的时候就可以进行加载,主要是适用于加载一些需要依赖注入的对象。其调用顺序如下 Constructor ----> @Autowired ----> @PostConstruct
在这里插入图片描述

1.6,初始化

会判断对象是否实现这个InitializingBean

1.7,初始化后

可以通过这个bean的后置处理器,实现这个aop操作。

二,AOP

主要用来加日志,监控,权限等等

2.1,aop的实现原理

spring的aop主要是在bean初始化之后,调用bean的后置处理器来实现。aop主要是通过这个cglib的动态代理实现,就是会通过一个子类去继承这个目标类,然后重写目标类里面的需要代理的方法,最后通过一个target对象,来获取这个之前的目标对象,最后通过这个就行了依赖注入的对象,去调用需要代理的方法

2.2,aop的加载流程

aop依赖与ioc,在生产bean并进行实例化之前,先通过bean的第一个后置处理器找到所有在类上面加@AspectJ这个注解的所有类,并在这个类的里面找到所有的befeore,after等注解的方法,每一个before,after等都会生成一个对应的advisor,每个advisor包括advise和pointcut,advise主要是用来作为一个增强器的使用,pointcut是为了进行匹配,匹配成功才进行最终的动态代理的生成。最后获取到所有的advisors,由于可能有大量的advisor,因此在bean的最后一个后置处理器才对这些所有的advisor进行处理,即在bean进行初始化之后才进行处理。最后会去循环遍历这些advisors,通过advisors里面封装的pointcut和生成的advisor进行比较,如果匹配成功,则说明bean需要创建动态代理。主要是通过责任链的方式实现。

三,spring事务

3.1,事务使用

1,开启事务

//开启事务
@EnableTransactionManagement
//开启动态代理暴露,将动态代理暴露在当前线程
@EnableAspectJAutoProxy//(exposeProxy = true) 
@ComponentScan(basePackages = {"com.zhenghuisheng"}) 

2,配置数据库连接,指定的具体的dataSource,这里可以指定一个jdbcTemplate

@Bean 
public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); 
}

3,接下来模拟一个扣减库存的实例

@Autowired
private AccountInfoDao accountInfoDao;
@Autowired
private ProductInfoDao productInfoDao;public void pay(String accountId, double money) {//查询余额double blance = accountInfoDao.qryBlanceByUserId(accountId);//余额不足正常逻辑if(new BigDecimal(blance).compareTo(new BigDecimal(money))<0) {throw new RuntimeException("余额不足");}//更新余额int retVal = accountInfoDao.updateAccountBlance(accountId,money);//库存-1//updateProductStore(1);((PayService)AopContext.currentProxy()).updateProductStore(1);System.out.println(1/0);
}@Transactional(propagation = Propagation.NESTED)
public void updateProductStore(Integer productId) {try{productInfoDao.updateProductInfo(productId);}catch (Exception e) {throw new RuntimeException("内部异常");}
}

4,采用动态代理的方式实现
通过AutoProxyRegistrar来注册一个bean的后置处理器,来解析切面等信息。

5,aop和事务都需要开启,都会通过bean的后置处理器注册成一个bean定义,最后会判断aop的后置处理器的优先级的大小,最后谁优先级高则会进行覆盖。处理aop的优先级会比事务的优先级高,因此事务会被覆盖

3.2,事务的加载流程

1,@EnableTransactionManagement 注解里面,有一个 @Import(TransactionManagementConfigurationSelector.class),基于importSelector的bean定义

2,import里面会导入完整的类名数组,分别是AutoProxyRegistar.class.getName()和ProxyTransactionManagementConfiguration.class.getName()两个

3,AutoProxyRegistar是基于一个注册bean的import的一个组件,由于处理aop的优先级会比处理事务的优先级高,所以最终处理aop的会将处理事务的覆盖,因此这个也是用于处理事务的一个aop的一个bean的后置处理器

4,ProxyTransactionManagementConfiguration是一个配置类,里面配置了advisor,直接通过配置类直接注册成一个内置的advisor,advisor里面包含一个通知advise和一个切入点pointcut,advise就是用来增强代码的,比如说处理事务,开启事务,回滚事务,提交事务,都在这个advise里面,pointcut负责匹配是否符合创建动态代理,判断方法上面是否有@Transactional,如果有则创建动态代理

5,调用createBean进行实例化,再调用doCreateBean进行属性赋值,再初始化。

6,获取所有的advisors,通过BeanFactoryTransactionAttributeSourceAdvisor来解析事务,根据当前bean的所有方法,找类里面的方法上找有没有Transaction的这个注解,没有的话会往父类或者接口找。如果是接口的话,会调用jdk动态代理,也可以强制加注解使用CGLIB代理

7,对advisors进行匹配,通过调用 ClassFilter 方法进行筛选,进行初筛。

8,精筛,会调用事务的属性源来进行判断,主要判断方法上面有没有 @Transaction 注解

9,可能也会根据接口或者父类来判断是否存在 @Transaction

dvisors进行匹配,通过调用 ClassFilter 方法进行筛选,进行初筛。

8,精筛,会调用事务的属性源来进行判断,主要判断方法上面有没有 @Transaction 注解

9,可能也会根据接口或者父类来判断是否存在 @Transaction

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

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

相关文章

Wireshark分析https流量

这里写自定义目录标题本文介绍使用wireshark分析https流量的方法。适用chromium内核的浏览器和firefox浏览器&#xff0c;前提是这些浏览器内核都支持如下选项&#xff1a; –ssl-key-log-file 浏览器配置 添加启动参数 例如&#xff1a; firefox.exe --ssl-key-log-filec:/s…

Python中setdefault()通过键查找字典中对应的值

【小白从小学Python、C、Java】 【Python-计算机等级考试二级】 【Python-数据分析】 字典中根据键k查找键k对应的值v 如果没找到键k&#xff0c;则创建键k并赋值为default setdefault() [太阳]选择题 以下Python代码中setdefault(d, 666)的返回值是什么&#xff1f; myDic {&…

java基于微信小程序的大学生个人家庭理财产品 uniapp小程序

为了方便操作,从多方面把用户的个人支付&#xff0c;个人收入等财产管理的数据,以及他们的生活结余和消费统计,用科学统计的方法把这些数据存储在财务管理软件之中&#xff61;文中着重论述了该系统的功能与实现,如数据流程与存储&#xff64;管理等功能,并对关键的技术作了较详…

动态规划 - 背包问题 回文串分割

目录 1.背包问题 1.1 题目描述 1.2 画图分析 1.3 思路分析 1.4 代码示例 2. 回文串分割 2.1 题目描述 2.2 思路分析 2.3 代码示例 1.背包问题 1.1 题目描述 有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小 和数组 V 表示每个物品的价值.问最多能装…

ROS+Arduino学习导航贴

前言 原先写了一些ROSarduino学习记录的帖子&#xff0c;发现每次找起来非常麻烦&#xff0c;所以做一个汇总帖&#xff0c;以后需要的话&#xff0c;找起来就方便了。 关于我用的开发板&#xff0c;一开始学习的时候&#xff0c;我用的开发板是arduino uno这类的&#xff0c…

[笔记]MySQL 插入导致死锁

线上遇到的 MySQL 插入导致死锁,问题排查. 场景复现 MySQL 版本: 5.7.36 数据库存储引擎: InnoDB 事务隔离级别: REPEATABLE-READ 1. 创建测试表 DROP TABLE IF EXISTS tb_task; CREATE TABLE tb_task (id int(11) NOT NULL AUTO_INCREMENT,task_id int(11),order_id int(1…

猿创征文 |【数据结构】2个例题带你理解图的遍历:广度优先搜索

目录 1、定义 2、算法分析 3、算法实现 4、性能分析 &#x1f49f;作者简介&#xff1a;大家好呀&#xff01;我是路遥叶子&#xff0c;大家可以叫我叶子哦&#xff01;❣️ &#x1f4dd;个人主页&#xff1a;【叶子博客】 &#x1f3c6;博主信息&#xff1a;四季轮换…

jquery实现云音乐歌词高亮和自动滚动效果

书接上篇文章 实现效果&#xff1a; 一、歌词高亮 首先要判断当前歌词和播放器的当前时间 循环歌词数组treatLyrics&#xff0c;拿到每条歌词的时间与播放器的当前时间playAudio.currentTime进行比较 treatLyrics.forEach((i, index) > { // console.log(i); // console.…

目前最好用的NAS系统是什么?

NAS被定义为一种特殊的专用数据存储服务器&#xff0c;包括存储器件&#xff08;例如磁盘阵列、CD/DVD驱动器、磁带驱动器或可移动的存储介质&#xff09;和内嵌系统软件&#xff0c;那么目前最好用的nas系统是什么&#xff1f; 常见的NAS系统有哪些 Nas 系统一般都是基于 Li…

Uplink Resource Allocation in IEEE 802.11ax

一、基本信息 题目&#xff1a;IEEE 802.11ax中的上行链路资源分配 作者&#xff1a;Sudeep Bhattarai, Gaurang Naik, Jung-Min (Jerry) Park 摘要&#xff1a;MU-OFDMA使得多个用户可以在更小的子信道(即资源单元&#xff0c;RUs)中同时进行传输&#xff0c;从而提高802.11ax…

如何从零开始解读产品经理行业分析

上次一起了解了什么是产品经理&#xff0c;产品经理PM和PD在不同类型公司的作用。了解产品经理对当前的应用产品中的重要作用。是不是有点憧憬&#xff0c;其实憧憬是美好的&#xff0c;但是还是要走进现实具体怎么去做&#xff0c;一步一步脚踏实地的&#xff0c;一步一步走入…

【Linux入门】— 腾讯云服务器的搭建

꧁ 各位大佬们好&#xff01;很荣幸能够得到您的访问&#xff0c;让我们一起在编程道路上任重道远&#xff01;꧂ ☙ 博客专栏&#xff1a;【Linux知识】❧ ⛅ 本篇内容简介&#xff1a;Linux小白到精通 — 学好Linux从学会服务器搭建开始&#xff01; ⭐ 了解作者&#xff1…

Java操作Zookeeper框架

Zookeeper框架 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hb…

Java Double equals()方法具有什么功能呢?

转自: Java Double equals()方法具有什么功能呢&#xff1f; 下文笔者将讲述equals()方法的功能简介说明&#xff0c;如下所示: equals()方法的功能 java.lang.Double.equals()方法的功能: 将当前的Double对象同一个对象进行比较&#xff0c; 当Object是一个Double对象&…

【牛客 - 剑指offer】JZ8 二叉树的下一个结点 Java实现

文章目录剑指offer题解汇总 Java实现本题链接题目方案一 中序遍历递归代码一 设置flag标记代码二 获取整个arrayList的大小方案二 分类直接寻找&#xff08;分情况讨论&#xff09;思路代码&#xff08;版本一&#xff09;代码&#xff08;版本二&#xff09;剑指offer题解汇总…

计算机毕业设计成品java项目开发实例SSM+MySQL实现的家庭医生预约平台

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 一、项目介绍 二、项目截图 三、项目获取 一、项目介绍 java毕业设计计算机毕设项目之基于SSMMySQL实现的家庭医生预约平台_哔哩哔哩_bilibilijava毕业设计计算机毕设项目之基于SSMMyS…

记首次协助搭建服务器

一&#xff0c;服务器资源申请 1&#xff09;使用云服务器&#xff08;k8s&#xff09;还是IDC服务器 云服务器VS IDC服务器 不同&#xff1a; 费用一样&#xff0c;云服务器支持动态扩容 私有云和IDC没有很大区别&#xff0c;只是私有云支持k8s&#xff0c;动态扩容方便。…

python 日志处理(基础篇)

Logging处理 日志级别等级排序&#xff1a;critical > error > warning > info > debug debug : 打印全部的日志( notset 等同于 debug ) info : 打印 info, warning, error, critical 级别的日志 warning : 打印 warning, error, critical 级别的日志 error : 打…

笑霸餐厅 | 瑞吉外卖项目 | 完整基础部分(后端学习笔记)

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;项目专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…

Android ActionBar

android的ActionBar是3.0才推出的,3.0之前称之为AppBar。为了向后兼容,ActionBar位于Android的支持库AppCompat中,所以要使用ActionBar先必须依赖AppCompat库(现在新建的工程默认都依赖此库了)implementation androidx.appcompat:appcompat:1.3.0如果没有在主题Theme中或Ac…