Spring底层源码分析

spring依赖注入底层原理解析

spring之bean对象生命周期步骤详情
在这里插入图片描述

流程:

UserService.class —>推断构造方法—>普通对象----依赖注入------>初始化(afterPropertiesSet方法)------>初始化后(AOP)------>代理对象----->放入Map<baenName,Bean对象>

推断构造方法
@Component
public class UserService implements InitializingBean {@Autowiredprivate OrderService orderService;//无参构造方法public UserService() {System.out.println(8);}//有参构造方法public UserService(OrderService orderService) {this.orderService = orderService;System.out.println(1);}//有参构造方法public UserService(OrderService orderService, OrderService orderServicel) {this.orderService = orderService;System.out.println(2);}
}

以上如何选择呢?
spring会默认使用无参构造方法,如果没有无参的有多个有参的构造方法spring就会报错
在这里插入图片描述
如果有多个就可以明确给spring指定哪一个构造方法-------在构造方法上加@Autowired 注解
在这里插入图片描述

依赖注入

在这里插入图片描述
判断普通对象中是否有Autowired注解再进行依赖注入
源码大体逻辑:
在这里插入图片描述
依赖注入的话如何判断注入对象就是想要的依赖对象呢?

先byType---->再byName 在 Map<beaName,Bean对象> 中寻找

在这里插入图片描述
spring中使用 对象类型 和 对象名字进行识别唯一的

类型可以一样 名字必须不一样
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在Bean中的地址不一样生成的Bean不同

初始化

初始化必须实现spring提供的指定方法

import org.springframewolk.beans.factory.InitializingBean;//实现一个接口
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserService implements InitializingBean {@Autowiredprivate OrderService orderService;//初始化执行自己定义@Overridepublic void afterPropertiesSet() throws Exception {System.out.println(orderService);}public void test() {System.out.println(orderService);}
}

源码中判断UserService是否实现了InitializingBean接口,如果实现了就调用afterPropertiesSet自己定义初始化方法
在这里插入图片描述

AOP

UserServiceProxy对象===UserService代理对象----->UserService代理对象.target


UserService代理对象.test()
class UserServiceProxy extends UserService {UserService target;public void test(){// 切面逻辑// target.test()  //UserService普通对象.test()
}
放入Map<baenName,Bean对象>

放入Bean对象到Map<String,Object>的API(自己调用方法),一般是再UserService.class方法上面加Component注解,加入到Map<String,Object>的

//放入Bean对象到Map<String,Object>的API
Object o = new Object();|I
applicationContext.getBeanFactory().registerSingleton( beanName: "xxx",o);

放入Map<String,Object>的源码
在这里插入图片描述

spring事务

流程:

Spring事务切面逻辑----->@Transactional开启Spring事务----->利用事务管理器新建一个数据库连接conn ThreadLocal------>conn.autocommit=false------>target.test() //UserService普通对象.test() jdbcTemplate 执行sql1.sql2 ----->conn.rollback()conn.commit()

1、@Transactional
2、开启Spring事务
3、利用事务管理器新建一个数据库连接conn ThreadLocal
4、conn.autocommit=false
5、target.test() // UserService普通对象.test() jdbcTemplate执行sql1.sql2
6、conn.rollback()conn.commit()

准备Bean对象

配置事务创建链接数据库的对象Bean相当于mybatis对象

@ComponentScan("com.zhouyu")
@EnableTransactionManagement  //用于启用基于注解的事务管理
@Configuration //通过配置类可以定义和组装Spring Bean。  返回的是同一个dataSource对象 AppConfig代理对象
public class AppConfig {@Bean
public JdbcTemplate jdbcTemplate() {return new JdbcTemplate(dataSource());
}//利用事务管理器创建数据库链接
@Bean
public PlatformTransactionManager transactionManager() {DataSourceTransactionManager transactionManager = newDataSourceTransactionManager();transactionManager.setDataSource(dataSource());return transactionManager:
}@Bean
public DataSource dataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.seturl("jdbc :mysql://127.0.0.1:3306/tuling");dataSource.setUsername("root");dataSource.setPassword("Zhouyu123456***");returm dataSource;
}

@EnableTransactionManagement 是Spring框架提供的一个注解,用于启用基于注解的事务管理。通过使用这个注解,你可以开启Spring对事务的自动管理功能,使得你可以在方法上使用 @Transactional 注解来声明事务。

@EnableTransactionManagement 主要有以下两个属性:

  • mode(默认为 AdviceMode.PROXY):指定事务代理的模式。可以选择的值有 AdviceMode.PROXY 和
    AdviceMode.ASPECTJ。默认是 AdviceMode.PROXY,表示使用基于代理的方式实现事务管理。如果选择
    AdviceMode.ASPECTJ,表示使用基于AspectJ的方式实现事务管理。
  • proxyTargetClass(默认为 false):用于确定代理是否应该使用目标类的类代理,而不是目标类实现的接口。如果设置为
    true,代理将使用目标类的类代理(CGLIB代理),如果设置为 false,代理将使用目标类实现的接口代理(JDK动态代理)。

当你在配置类上使用 @EnableTransactionManagement 注解时,Spring框架会自动扫描带有 @Transactional 注解的方法,并在这些方法周围织入事务管理的逻辑。如果一个带有 @Transactional 注解的方法执行过程中出现了异常,Spring会自动回滚事务。这个注解的作用是简化事务管理的配置和使用,提高开发效率。

测试事务
class UserService{@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactionalpublic void test() {jdbcTemplate.execute( sql: "insert into t1 values(1,1,1,1,'1')");//抛空指针异常,触发事务回滚throw new NullPointerException();}	
}
主程序逻辑

在这里插入图片描述
检查数据库中数据是否插入成功

事务失效

1、原因:

一个对象调用了另一个对象
代理对象和普通对象是两个对象

class UserService{@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactionalpublic void test() {jdbcTemplate.execute( sql: "insert into t1 values(1,1,1,1,'1')");throw new NullPointerException();a();}//多个事务报错propagation = Propagation.NEVER@Transactional(propagation = Propagation.NEVER)public void a(){jdbcTemplate.execute( sql: "insert into t1 values(2,2,2,2, '2' )");}
}

以上原因一个对象调用了另一个对象的a()
使用this.a()不能解决,因为this是普通对象

解决方法:

1、新建一个Base类,把需要调用的功能拿到另一个Bean对象中
在这里插入图片描述
新建类UserServiceBase,把UserService的a方法删掉,不要有相同的方法
在这里插入图片描述

2、自己注入自己
在这里插入图片描述

1、原因:

在这里插入图片描述

@ComponentScan("com.zhouyu")
@EnableTransactionManagement  //用于启用基于注解的事务管理
@Configuration //AppConfig代理对象来掉用
public class AppConfig {@Beanpublic JdbcTemplate jdbcTemplate() {return new JdbcTemplate(dataSource());}//利用事务管理器创建数据库链接@Beanpublic PlatformTransactionManager transactionManager() {DataSourceTransactionManager transactionManager = newDataSourceTransactionManager();transactionManager.setDataSource(dataSource());return transactionManager:}//创造dataSource对象@Beanpublic DataSource dataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.seturl("jdbc :mysql://127.0.0.1:3306/tuling");dataSource.setUsername("root");dataSource.setPassword("Zhouyu123456***");returm dataSource;}
}

@Configuration 中使用的是super.方法

AOP中使用的是target.方法

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

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

相关文章

Zabbix“专家坐诊”第231期问答

问题一 Q&#xff1a;用docker-compose部署zabbix&#xff0c;部署完后如果要修改zabbix的配置应该要改docker-compose文件里的环境变量吧&#xff1f;改了环境变量之后只能重建容器才能生效吗&#xff1f;能不能在不影响已经配好的那些监控项的情况下让新的环境变量生效&#…

洛谷P1331海战

题目背景 在峰会期间&#xff0c;武装部队得处于高度戒备。警察将监视每一条大街&#xff0c;军队将保卫建筑物&#xff0c;领空将布满了 F-2003 飞机。 此外&#xff0c;巡洋船只和舰队将被派去保护海岸线。不幸的是&#xff0c;因为种种原因&#xff0c;国防海军部仅有很少…

win安装卸载python3.13

一、安装 访问python官网&#xff1a;https://www.python.org/ 点击“Downloads” 点击“Windows” 找到自己要下载的版本和位数&#xff0c;比如我这个是3.13版本、64位的安装包 下载好了之后&#xff0c;双击安装包 勾选“Add python.exe to PATH”&#xff1a;把python环…

[记录]-PyCharm中的Unresolved Reference疾病专治

转载https://blog.csdn.net/qq_36166962/article/details/115905359?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170930227516800227476736%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id170930227516800227476736&biz_i…

作业1-224——P1331 海战

思路 深搜的方式&#xff0c;让它只遍历矩形块&#xff0c;然后在下面的遍历中判断是否出现矩形块交叉&#xff0c;但是很难实现&#xff0c;然后发现可以通过在遍历过程中判断是否合法。 参考代码 #include<iostream> #include<cstdio> using namespace std; …

SQLSERVER 2014 删除数据库定时备份任务提示失败DELETE 语句与 REFERENCE 约束“FK_subplan_job_id“冲突

SQLSERVER 2014 删除数据库定时备份任务提示失败DELETE 语句与 REFERENCE 约束“FK_subplan_job_id“冲突 &#xff0c;错误如图&#xff1a; 问题原因&#xff1a;不能直接删除作业 任务&#xff0c;需要先删除计划里面的日志、删除代理作业、删除子计划以后才能删除作业。 解…

蓝桥杯:真题讲解3(C++版)附带解析

报纸页数 来自&#xff1a;2016年七届省赛大学C组真题&#xff08;共8道题) 分析&#xff1a; --画出报纸长的样子&#xff0c;如果我们在上面多画一张报纸&#xff0c;那么就符合题意的5&#xff0c;6&#xff0c;11&#xff0c;12。 观察这张图&#xff1a;观察3&#xf…

VUE3子组件实例方法暴露(导出)方法

最近很多朋友私我请教子组件实例的获取方法 解答&#xff1a; vue2中可直接通过父组件内组件的ref读取子组件的实例&#xff0c;vue3有些许区别 vue3中需要在子组件中导出&#xff08;暴露&#xff09;相关实&#xff08;你需要再父组件中调用&#xff09;例方法&#xff1a;…

力扣:35. 搜索插入位置

力扣&#xff1a;35. 搜索插入位置 描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,…

Mybatis | Mybatis的核心配置

目录: Mybatis的核心配置 :一、MyBatis的 “核心对象”1.1 SqlSessionFactory1.2 SqlSession :SqlSession对象中的操作数据库的方法 :\<T> T selectOne ( String statement )\<T> T selectOne( String statement , Object parameter )\<E> List\<E> se…

SpringBoot基于注解实现全局日期格式化

首先根据项目要求提供自定义的日期序列化器和反序列化器&#xff0c;其中包括&#xff1a; DateJsonSerializerextendsJsonSerializer 表示将Date格式化为日期字符串。DateJsonDeserializerextendsJsonDeserializer 表示将日期字符串解析为Date日期。 使用注解 JsonComponent…

openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划

文章目录 openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划 openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划 完成资源负载管理功能配置前&#xff0c;需要先根据业务模型完成租户资源的规划。业…

绍兴市新昌县人大一行莅临迪捷软件走访考察

2024年2月29日下午&#xff0c;绍兴市新昌县人大常委会副主任王敏慧一行莅临迪捷软件走访考察&#xff0c;绍兴市委科创委副主任、科创走廊建设领导小组副组长、市人大一级巡视员王继岗&#xff0c;绍兴市科技局副局长、科创走廊建设办公室常务副主任梁枫陪同。 王主任一行听取…

九州金榜|导致孩子厌学因素有哪些?家庭教育中要怎样解决?

现在如今孩子出现厌学的情况越来越严重&#xff0c;这也难坏了很多家长&#xff0c;众所周知&#xff0c;当下社会竞争越来越激烈&#xff0c;孩子的压力也越来越大&#xff0c;这也是导致孩子厌学的主要因素。其实家庭因素也是引起孩子厌学情绪产生的重要原因&#xff0c;在家…

数据结构——二叉树的基本概念及顺序存储(堆)

目录 一.前言 二.树概念及结构 2.1 树的概念 2.2 树的相关概念 2.3 树的表现 2.4 树在实际中的应用&#xff08;表示文件系统的目录树结构&#xff09; 三.二叉树的概念及结构 3.1 概念 3.2 特殊的二叉树 3.3 二叉树的性质 3.4 二叉树的存储结构 3.4.1 顺序存储 3…

YOLOv9有效提点|加入SE、CBAM、ECA、SimAM等几十种注意力机制(一)

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、本文介绍 本文将以SE注意力机制为例&#xff0c;演示如何在YOLOv9种添加注意力机制&#xff01; 《Squeeze-and-Excitation Networks》 SENet提出…

向上生长笔记

第一章 成为一个很厉害的人(持续输入&#xff0c;反复练习) 为什么要学习及如何学习 1、自毁趋势(熵增)&#xff0c;故需要能量输入(负熵流) //引申&#xff1a;水往低处流是趋势&#xff0c;学习是逆趋势。 2、持续输入能量&#xff08;物质和信息&#xff09;&#xff0c;…

linux本地安装nginx教程

1.安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c libtool openssl openssl-devel pcre-devel 2.下载 nginx包到指定位置 wget https://nginx.org/download/nginx-1.18.0.tar.gz 3.解压包 tar -zxvf nginx-1.18.0.tar.gz #解压 4.在你想安装nginx的…

力扣2月最后三天的每日一题

力扣2月最后三天的每日一题 前言2867.统计树中的合法路径数目思路确定1e5中的质数统计每个点的连接情况开始对质数点进行处理完整代码 2673.使二叉树所有路径值相等的最小代价思路完整代码 2581.统计可能的树根数目思路建立连通关系将猜测数组变为哈希表&#xff0c;方便查询利…

2280. 最优标号(最小割,位运算)#困难,想不到

活动 - AcWing 给定一个无向图 G(V,E)&#xff0c;每个顶点都有一个标号&#xff0c;它是一个 [0,2^31−1] 内的整数。 不同的顶点可能会有相同的标号。 对每条边 (u,v)&#xff0c;我们定义其费用 cost(u,v) 为 u 的标号与 v 的标号的异或值。 现在我们知道一些顶点的标号…