Spring高级(原理)

news2024/9/21 2:38:27

一、Spring创建Bean

personService -> 构造方法 -> 普通对象 -> 依赖注入(byType->byName) -> 初始化前(@PostConstruct) -> 初始化(InitializingBean) -> 初始化后(AOP) -> 代理对象 -> 将代理对象放入到Map单例池中 -> Bean对象

public class PersonService{
	@Autowiren
	private UserService uservice;
	public String getStr(){
		return "HELLO";
	}
}
  • 创建Bean:Spring创建Bean时是基于Bean的构造方法创建出来的。
  • 依赖注入:当Bean创建完成后,Spring会把值注入到包含了注入注解(@Autowiren,@Resource…)的属性上,并不是给所有属性注入值。

举例

// 通过无参构造方法得到一个对象
PersonService personService = new PersonService();
// 通过反射得到属性,判断哪些属性是需要注入值的
for(Field field : personService.getClass().getDeclaredFields()){
	if(field.isAnnotationPresent(Autowiren.class)){
		field.set(personService,???);
	}
}

personService --> 构造方法得到对象 --> 对象 --> 依赖注入 --> Bean对象

二、Spring中的单例池和作用

单例池:Map<beanName,Bean对象>

  • Spring单例池是一个Map<beanName,Bean对象>来存储Bean的,所以通过application.getBean("beanName");得到的Bean是同一个对象。

  • 如果通过application.getBean("beanName");获取不到Bean时,Spring会帮我们创建一个Bean,并把需要赋值的属性都注入值,然后将这个Bean存放到Map<beanName,Bean对象>中来,以供我们来获取使用。

AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(AppConfig.class);
// 单例Bean
PersonService personService1 = (PersonService)application.getBean("personService");
PersonService personService2 = (PersonService)application.getBean("personService");
PersonService personService3 = (PersonService)application.getBean("personService");
// 结果为true
boolean bool = personService1.equals(personService2) && personService2.equals(personService3); // true

PersonService personService4 = new PersonService();
PersonService personService5 = new PersonService();
PersonService personService6 = new PersonService();
// false
boolean boo = personService4.equals(personService5) || personService5.equals(personService6); // false
/** 如果每次得到的Bean都是不一样的,那么也就没必要放到Map<beanName,Bean对象>中了 */

三、推断构造方法

  • Spring创建对象时会优先选择无参构造方法,当对象中没有无参构造方法并且有且仅有一个有参构造方法时,Spring会使用该有参构造为我们创建一个对象。
  • 当对象中有无参构造方法和多个有参构造方法时,Spring会默认使用无参构造方法为我们创建一个Bean对对象。
  • 当对象中没有无参构造方法,且有多个有参构造方法时,Spring便会在初始化时抛出异常,因为没有无参构造方法时,Spring无法在多个有参构造方法中选择。
    Caused by: java.lang.NoSuchMethodException Create breakpoint : ....PersonService.<init>()
  • 当对象中没有无参构造方法,且有多个有参构造方法时,我们可以使用@Autowried注解来告诉Spring默认使用具体的那个构造方法来帮我们创建出Bean对象。
public class PersonService{
	private UserService uservice;
	
	//public PersonService(){}
	
	public PersonService(UserService uservice){}
	
	@Autowried
	public PersonService(UserService uservice1,UserService uservice2){
		System.out.println("告诉Spring使用当前构造方法创建Bean对象!");
	}
}

四、构造方法参数注入

  • Spring在使用有参构造方法创建Bean对象时,发现需要传入参数,Spring会先从单例池(Map<beanName,Bean对象>)中获取,有值则会传进来,没值Spring则会创建一个Bean对象,然后传到构造方法中。
  • 当创建PersonService对象的时候发现参数为空,Spring会为我们创建一个UserService对象当作参数,此时会出现一个循环依赖问题,Spring是通过三级缓存来解决循环依赖的。
@Autowried
public PersonService(UserService uservice){
	System.out.println("Spring会创建uservice的Bean对象作为参数传过来!");
}

五、先byteType再byName

在这里插入图片描述

当Spring单例池(Map<beanName,Bean对象>)中存在多个UserService单例Bean时,Spring选择时先byteType再byName的机制

import cn.molu.service.UserService;
@Component
public class AppConfig{ 
	@Bean
	public UserService uservice(){  // Map<uservice,UserService>
		return new UserService();
	}
	@Bean
	public UserService uservice1(){ // Map<uservice1,UserService>
		return new UserService();
	}
	@Bean
	public UserService uservice2(){ // Map<uservice2,UserService>
		return new UserService();
	}
}
  • 当Spring在单例池(Map<beanName,Bean对象>)中发现有多个单例Bean时,Spring会先以UserService(cn.molu.service)的类型来匹配(此时发现存在3个UserService ),之后在以入参的名称uservice来匹配Bean对象,之后返回该Bean对象。
  • Spring在单例池(Map<beanName,Bean对象>)中未找到Bean或者按照Type找到多个而按照Name没找到时,Spring就会抛出异常

六、Spring底层AOP的操作

在这里插入图片描述

首先Spring的代理对象(UserServiceProxy)会继承被代理对象(UserService)
代理对象(UserServiceProxy)中会有一个属性为普通对象(UserService target;)
代理对象重写父类(被代理对象)中的方法,最后使用普通对象(UserService target;)执行对应的方法。
UserServiceProxy -> UserService代理对象 -> UserService代理对象.target=普通对象(UserService) -> 存放到Map<beanName,Bean对象>代理池中

class UserServiceProxy extends UserService{
	UserService target;// 普通对象
	@Override
	public void method(){
		//@Before切面逻辑
		target.method();// 最终执行普通对象中的method方法
	} 
}

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

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

相关文章

WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第五步-高级可视化)

1写在前面 前面我们用WGCNA分析完成了一系列的分析&#xff0c;聚类分割模块。&#x1f970; 随后进一步筛选&#xff0c;找到与我们感兴趣的表型或者临床特征相关的模块&#xff0c;而且进行了模块内部分析。&#x1f618; 再然后是对感兴趣模块进行功能注释&#xff0c;了解模…

Mars3D Studio 的使用方法

Mars3D Studio的使用 1、介绍&#xff1a; mars3d Studio是mars3d研发团队于近期研发上线的一款 场景可视化编辑平台。拥有资源存档、团队协作、定制材质等丰富的功能。可以实现零代码构建一个可视化三维场景。 2、功能介绍 &#xff08;1&#xff09;数据上传&#xff1a…

代码随想录【Day16】| 110. 平衡二叉树、257. 二叉树的所有路径、404. 左叶子之和

110. 平衡二叉树 题目链接 题目描述&#xff1a; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,nul…

物理层基本介绍

corset 0 告诉下行初始带宽是多少 initail DL BWP, 4g 是20M带宽&#xff0c;5G是FR1 如果5G是全带宽的话&#xff0c;手机很快就会没电了。 告诉手机带宽会分布在某一个带宽里面去&#xff0c;将手机的带宽调整就行。 DCI&#xff0c;告诉手机&#xff0c;未来的某一个时刻&a…

【MyBatis】第九篇:mybatis逆向工程插件----mybatis-generator

本篇聊mybatis逆向工程&#xff0c;但是这个和安卓逆向不一样&#xff0c;不是说反编译&#xff0c;破解什么加密 &#xff0c;最后打包。而是通过一某插件&#xff0c;快速生成一个mybatis项目的结构而已。 简单的说就是&#xff0c;通过先创建的数据表&#xff0c;由框架通过…

【1139. 最大的以 1 为边界的正方形】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个由若干 0 和 1 组成的二维网格 grid&#xff0c;请你找出边界全部由 1 组成的最大 正方形 子网格&#xff0c;并返回该子网格中的元素数量。如果不存在&#xff0c;则返回 0。 示例 1&#…

浮点数值计算精度丢失问题剖析及解决方法

文章目录1、原因分析2、解决方法2.1、Java中使用 BigDecimal 类2.2、JavaScript 中解决计算精度丢失的问题3、使用建议1、原因分析 首先我们来看个反直觉的浮点数值计算 System.out.println(0.3*3);有的同学可能要问为啥不是0.9&#xff1f; 首先要知道为什么会产生这个问题…

Mybatis的Mapper接口代理机制

提示&#xff1a;本文章基于B站动力节点的课程仿写 文章目录前言一、解析mybatis-config.xml1.1 引入dom4j依赖1.2 解析mybatis-config.xml1.3 解析mapper映射文件二、引入javassist2.1 引入javassist依赖2.基于mybatis的javassist来实现该功能前言 本文章基于B站动力节点的课…

算法训练营DAY54|583. 两个字符串的删除操作、72. 编辑距离

583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/delete-operation-for-two-strings/这道题也是对于编辑距离的铺垫题目&#xff0c;是可以操作两个字符串的删除&#xff0c;使得两个字符串的字符完全相同&#xff0c;这道题可…

利用vite插件开发,实现工程化打包,建议收藏

为什么需要工程化打包&#xff1f; vue3vite的工程&#xff0c;普遍都会在项目public文件夹&#xff0c;创建一个config.js文件&#xff0c;存放一些配置态的数据&#xff0c;用于在产品上线后&#xff0c;可能会根据需要修改参数值&#xff0c;从而达到线上配置数据目的。 但…

第0章 一些你可能正感到迷惑的问题

操作系统是什么 操作系统是控制管理计算机系统的硬软件&#xff0c;分配调度资源的系统软件。 由操作系统把资源获取到后台给用户进程&#xff0c;但为了保护计算机系统不被损坏&#xff0c;不允许用户进程直接访问硬件资源。 操作系统相当于是一个分配资源的机构&#xff0c;…

【C++】string类(下)

文章目录1.迭代器(正向遍历)begin有两个版本2.反向迭代器(反向遍历)rbegin由两个版本3. at4. insert ——头插在pos位置前插入一个字符串在pos位置前插入n个字符在迭代器前插入一个字符5. erase从pos位置开始删除len个字符从迭代器位置开始删除6. replace——替换从pos位置开始…

【Linux】进程终止进程等待

文章目录进程创建fork函数初识fork函数返回值写时拷贝fork常规用法fork调用失败的原因进程终止进程退出场景进程常见退出方法进程等待进程等待必要性进程等待的方法wait方法waitpid方法获取子进程status从操作系统层面理解waitpid阻塞状态和非阻塞状态阻塞等待例子:多进程创建和…

设计模式 - 模板方法模式详解

介绍&定义 模板模式&#xff0c;全称是模板方法设计模式&#xff0c;英文是 Template Method Design Pattern。在 GoF 的《设计模式》一书中&#xff0c;它是这么定义的&#xff1a; Define the skeleton of an algorithm in an operation, deferring some steps to subcl…

从辅助驾驶到自动驾驶究竟还有多远?

/ 导读 /现如今&#xff0c;自动驾驶的噱头早已被厂家们放在台面上宣传了太多&#xff0c;小鹏汽车更是在最近宣称要在2023年在中国率先推出全自动驾驶&#xff0c;此言一出更是一石激起千层浪&#xff0c;而业内人士表示针对此类言论早已经见怪不怪了&#xff0c;更何况何小鹏…

计算机网络期末复习汇总(附某高校期末真题试卷)

文章目录一、选择题二、填空题三、名词解析四、简答题五、高校期末真题一、选择题 1、传输延迟时间最小的交换方法是( A ) A.电路交换 B.报文交换 C.分组交换 D.信元交换 2、在OSI七层结构模型中&#xff0c;处于数据链路层与运输层之间的是&#xff08; B&#xff09; A、物…

双代号网络图、双代号时标网络图、单代号网络图精讲

01进度管理—普通双代号网络1.识读、虚箭线(1)网络图的识读&#xff1a;基本组成及逻辑关系&#xff1b;(2)补充虚箭线&#xff1a;共用一个班组、共用一台机械&#xff1b;(3)网络图的基本绘制要求&#xff1a;①只有一个起点及终点&#xff1b;②箭线从小节点编号指向大编号&…

for var in 循环报错

近期对babel进行升级&#xff0c;突然爆出 Property left of ForInStatement expected node to be of a type ["VariableDeclaration","LVal"] but instead got undefined&#xff1b;的错误&#xff0c;不知为何&#xff1b;解决&#xff1a;for(var p in…

数据库如何分库分表

有了主从数据库为啥还需要分库分表 如果一个网站业务快速发展&#xff0c;那这个网站流量也会增加&#xff0c;数据的压力也会随之而来&#xff0c;比如电商系统来说双十一大促对订单数据压力很大&#xff0c;Tps十几万并发量&#xff0c;如果传统的架构&#xff08;一主多从&a…

基于matlab设计x波段机载SAR系统

一、前言此示例说明如何设计在 X 波段工作的合成孔径雷达 &#xff08;SAR&#xff09; 传感器并计算传感器参数。SAR利用雷达天线在目标区域上的运动来提供目标区域的图像。当SAR平台在目标区域上空行进时&#xff0c;当脉冲从雷达天线发送和接收时&#xff0c;会产生合成孔径…