Spring知识点补充

news2025/7/18 8:17:57

1.常见的ORM框架都有哪些呢?

什么是ORM框架?

所谓的ORM框架,就是对象关系映射框架,就是让我们程序中的类里面的属性直接映射到我的数据库中的表里面的列,我们在Java中操作这个类的时候,就相当于直接操作数据库中的表和字段,运用OOP思想;

1)Mybatis是⼀种典型的半⾃动的 ORM 框架,所谓的半自动,是因为还需要⼿动的写 SQL 语句,再由框架根据SQL以及传入数据来进行组装执行的SQL,下面是他的优点:

1. 因为由程序员自己写 SQL,相对来说学习⻔槛更低,更容易⼊⻔,在高级也就写个联表查询,所以说很灵活

2. 更⽅便做 SQL的性能优化及维护。

3. 对关系型数据库的模型要求不⾼,这样在做数据库模型调整的时候,影响不会太大,适合于软件需求变更比较频繁的系统

4)他的缺陷就是:不能跨数据库,因为写的SQL可能存在数据库特有的语法或者关键词,做数据库转换不方便,

mybatis的数据库移植性较差,这个是它的一个非常大的缺点了。

具体的来说,例:

mysql移植到Orecle,SQL语句会有差异从而引起error

3)Hibernate是⼀种典型的全⾃动 ORM 框架,所谓的全⾃动,是 SQL 语句都不⽤在编写,基于框 架的 API,可以将对象⾃动的组装为要执⾏的 SQL 语句,比如说,底层会提供一个Insert方法,我们只需要将对象的属性设置进去,将这个对象放到方法的参数里面,就可以进行使用了,其优点为:

1. 全⾃动 ORM 框架,⾃动的组装为 SQL 语句。

2. 可以跨数据库,框架提供了多套主流数据库的 SQL ⽣成规则。

其缺点为:

1)学习⻔槛更⾼,要学习框架 API 与 SQL 之间的转换关系,况且如果实现一个简单的增删改查是非常简单的,但是说如果写一些复杂的SQL调用API就会很麻烦,Hibernate提供了一些自己复杂的语法进行连表查询,HQL语法是一个中间语法

2)对数据库模型依赖⾮常⼤,在软件需求变更频繁的系统中,会导致⾮常难以调整及维护。可 能数据库中随便改⼀个表或字段的定义,Java代码中要修改⼏⼗处。

4)很难定位问题,也很难进⾏性能优化:需要精通框架,对数据库模型设计也⾮常熟悉。

2.谈谈你对Bean容器和IOC容器的理解:

Spring容器主要是对IoC设计模式的实现,主要是使⽤容器来统⼀管理Bean对象,及管理对象之间的依赖关系,但是IOC只是Bean容器实现的一种模式,有可能也有其他的实现模式

创建容器的API主要是BeanFactory和ApplicationContext两种:

1)BeanFactory是最底层的容器接⼝,只提供了最基础的容器功能:Bean 的实例化和依赖注⼊,并且使⽤懒加载的⽅式,这意味着 beans 只有在我们通过 getBean() ⽅法直接调⽤它们时才进⾏实例化。

2.)ApplicationContext(应⽤上下⽂)是BeanFactory的⼦接⼝,与 BeanFactory 懒加载的⽅式不同,它是预加载,所以,每⼀个 bean 都在 ApplicationContext 启动之后实例化。

3) 除了基础功能,还添加了很多增强:

3.1)整合了Bean的⽣命周期管理

3.2)国际化功能(MessageSource)

3.3)载⼊多个(有继承关系)上下⽂ ,使得每⼀个上下⽂都专注于⼀个特定的层次,⽐如应⽤的web层

3.4)事件发布响应机制

3.5)AOP

对IOC和DI的理解:

IOC:是Inversion of Control,是面向对象编程中的一种常见的设计原则,主要是通过IOC容器,对Bean对象来进行统一的一个管理,以及组织对象的之间的依赖关系,获取依赖对象的过程,原本是由程序自己进行控制的,现在变成了IOC容器进行自动注入,控制权发生了反转,所以叫IOC控制反转

DI:就是在IOC容器在运行期间,动态地将某种依赖关系注入到对象里面

DI的实现方式只有两种,构造方法注入和属性注入

实现原理:主要是依赖于反射或者是ASM字节码框架实现(字节码框架操作字节码更为高效,功能是更强大的)

3.Spring单例Bean的线程安全问题:

我们在默认情况下,Bean是单例模式,所有人都是在用这一个对象,如果有人针对这个对象进行属性的修改的时候,那么就会存在数据覆盖的问题,所以不是线程安全的

1)在Bean对象中尽量避免可变的成员变量,设置成final,不能被修改

2)在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal里面,每一个线程设置的是自己的变量,用于处理线程安全的单例Bean

4.BeanFactory和FactoryBean又什么区别呢?

1)BeanFactory就类似于线程池,FactoryBean就类似于线程工厂,咱们的BeanFactory是Spring容器的顶级接口,所有的Bean对象都是通过BeanFactory也就是Bean容器来进行管理

2)FactoryBean是一个实例化一个Bean对象的工厂类,实现了Factory<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的是其实FactoryBean方法返回的对象,而不是FactoryBean本身

5.对Spring三级缓存的理解:换种说法就是Spring是如何进行解决循环依赖问题的,本质上就是三个HashMap

我们先来说一说什么是循环依赖?

简单来说就是A对象依赖于B对象,B对象又依赖于A对象,咱们的类似的代码如下:
@Component
public class A{
    @Autowired
    private B b;
 }
@Component
public class B{
    @Autowired
    private A a;
}

那么默认单例的属性注⼊场景,Spring是如何⽀持循环依赖的?

Spring是使⽤三级缓存的机制来解决循环依赖问题,以下为三级缓存的定义:

一级缓存:Spring容器,存放完整的Bean对象,如果A对象被完整地初始化了,就会放到一级缓存里面,让其他人可以直接去用

二级缓存:里面主要保存的是一个半成品,就是提前曝光不完整对象,一个是保存初始化一半的Bean,比如说A里面是依赖B的,B又去依赖A了,就会先把A的一半对象保存在二级缓存里面里面,只有一个引用,只有一个地址;

三级缓存:存放的是ObjectFactory(Bean的工厂类),咱们再Spring里面,获取到每一个类,都会对应到一个ObjectFactory,只有ObjectFactory,我们才可以获取到Bean,所有Bean的创建,都是要依赖Bean的工厂进行创建的(就像线程池创建线程),一开始实例化的时候,是放在三级缓存里面的,实例化一半的过程中是把对象放到二级缓存里面了

三级缓存singletonFactories中保存的是ObjectFactory对象(Bean⼯⼚),其中包含了

BeanName,Bean对象,RootBeanDefinition,该⼯⼚可以⽣成Bean对象。

解决的过程:

1)A在进行加载的时候,首先我们会生成一个A的一个ObjectFactory(创建Bean的一个工厂类),存到三级缓存里面,然后我们执行对A的初始化,我们发现A里面引用了B对象了

2)此时我们进行初始化B操作,我们首先在三级缓存里面创建一个B的ObjectFactory,我们发现初始化B的时候,发现属性要用到A,又要用到A了,我们就会通过A的三级缓存,生成一个A一半的Bean,因为我执行一半,里面的初始化还没有执行完呢,这是就是一个A的半成品,我们把半成品存到二级缓存里面

3)然后我们的Bcontroller继续执行,此时B就已经拿到了半成品的A了,直接把A的内存地址放到B的属性里面,B就会针对本身进行初始化后面的代码了,最后,我们生成了一个完整的B的Bean对象,然后B直接放到一级缓存里面了,然后我们再把B的二级缓存和三级缓存中的半成品和ObjectFactory进行删除

4)然后我们的A继续初始化(A在这时就可以拿到完整的B了),把A初始化好的Bean放到Spring容器里面,删除A二级缓存和三级缓存的ObjectFactory和一半的Bean

因此,Spring一开始提前暴露的并不是实例化的 Bean,而是将 Bean 包装起来的ObjectFactory,为什么要这么做呢?

1)这实际上涉及到 AOP。如果创建的 Bean 是有代理的,那么注入的就应该是代理 Bean,而不是原始的 Bean。但是,Spring一开始并不知道 Bean是否会有循环依赖,通常情况下(没有循环依赖的情况下),Spring 都会在“完成填充属性并且执行完初始化方法”之后再为其创建代理。但是,如果出现了循环依赖,Spring 就不得不为其提前创建"代理对象";否则,注入的就是一个原始对象,而不是代理对象。因此,这里就涉及到"应该在哪里提前创建代理对象"

2)Spring 的做法就是:在 ObjectFactory 中去提前创建代理对象

总结:加入缓存中是从下向上加的,查找缓存是从上向下进行查找的

对AOP的理解: 

AOP:是面向切面编程,对针对业务代码横切来实现统一的业务管理,而不用侵入业务代码本身,这样面向切面编程的思想就是AOP

使用场景:日志管理,事务管理,性能统计,安全控制,异常处理

优点:实现了代码的解耦,统一业务功能对具体业务没有什么侵入性,这样可扩展性更好,灵活性更高

Spring是采取动态代理的方式,具体是基于JDK和CGLIB两种:

JDK动态代理需要被代理类实现接口

CGLIB需要被代理类能够被继承,不能被final修饰,底层是基于ASM字节码框架,在运行的时候动态生成代理类

SpringAOP如何进行使用:使用@Aspect来进行定义切面,并注册到容器里面,使用@Pointcut定义好切点方法之后,可以对目标方法来进行拦截,然后执行我们的前置通知,后置通知之类的东西

SpringMVC的执行流程: 

1)DispatcherServlet:前端控制器它是用来接收请求,响应结果,相当于转发器,中央处理器。有了DispatcherServlet减少了其它组件之间的耦合度,是由调度器来进行数据的分发和返回操作的----不需要程序员来进行开发

2)HanderMapping:处理器映射器,经过处理器映射器之后:(根据URL来进行查找,最终的目的就是匹配Controller的,最终找到执行类)-----不需要程序员来进行开发

3)HanderAdapter:叫做处理器适配器,按照特定规则去执行Handler----不需要程序员来进行开发

4)处理器Handler:编写Handler的时候需要按照HandlerAdapter的要求去做,这样适配器才可以真正的执行Handler

1)用户发起请求到我们的前端控制器:DispatcherServlet

2)前端控制器请求HandlerMapping查找 Handler(可以根据xml配置、注解进⾏查

找)--------作⽤根据请求的url查找Handler(方法,就是一个Controller);

3)他的这个处理器映射器也就是HanderMapping执行之后,会返回一个执行链给DispatcherServlet(因为我们在这个时候可能会有拦截器,执行一些逻辑,比如说登录功能的校验等等,如果有拦截器,会执行拦截器,没有就会继续向下执行)

4)HanderMapping会把请求映射成HanderExecutionChain对象,这个对象里面就包含了一个Hander处理器对象,还有多个HanderInterceptor对象)

5)然后再根据这个DispatcherServlet调用处理器适配器去执行Hander

6)此时如果加上了@RestController或者是@ResponseBody表示此时返回给前端的是一个完整的数据而不是页面

7)如果此时没有加这两个注解,那么Handler会向处理器适配器(HanderAdapter)返回一个ModelAndView

8)然后处理器适配器会向DisDispatcherServlet返回一个ModelAndView

9)前端控制器请求视图解析器来进行视图解析,视图解析器把结果返回给前端控制器,前端控制器返回结果

4)适配器是去确定最终执行的Controller的,执行完适配器中的Controller,会返回一个ModelAndView,先返回给我们的DispatcherServlet,然后在传递请求给我们的视图解析器进行视图解析,

其实根据RequestBody一些注解来进行确定来决定我们返回的是是view还是非view的一些其他信息,如果是视图,视图解析器时进行处理服务器的一些标签的(当服务器有模板引擎,解析,把咱们的标签来解析成一些值),如果说咱们的返回数据是一个Json对象的话,就不会有视图解析器这一步操作了,解析完成之后,会返回view给DispatherServlet,然后再由DispatcherServlet发送请求给view进行视图渲染,将模型数据Model填充到request域,再把视图渲染返回给DispatcherServlet,再把结果返回给前端

SpringBoot自动装配原理/SpringBoot自动化配置的理解

SpringBoot再进行自动配置的时候,尤其是我再进行Bean加载的时候,启动的时候,我是根据@SpringBootApplication注解来进行启动的,他是一个组合注解

约定大于配置

启动类的@SpringBootApplication注解由@SpringBootConfiguration,

@EnableAutoConfiguration,@ComponentScan三个注解组成,三个注解共同完成自动装配;

1)@SpringBootConfiguration 注解标记启动类为配置类
2)@ComponentScan
注解实现启动时扫描启动类所在的包以及子包下所有标记为bean的类由IOC容器注册为bean
3)@EnableAutoConfiguration通过 @Import 注解导入 AutoConfigurationImportSelector类,然后通过AutoConfigurationImportSelector 类的 selectImports 方法去读取需要被自动装配的组件依赖下的spring.factories文件配置的组件的类全名,并按照一定的规则过滤掉不符合要求的组件的类全名,将剩余读取到的各个组件的类全名集合返回给IOC容器并将这些组件注册为bean,

其中这里面的@import注解,他会把所有满足条件的Bean全部加载到SpringBoot里面,什么是满足条件的Bean呢?

在SpringBoot里面有一个jar包,叫做:Maven:org.springframework.boot:spring-boot:2.5.11里面有一个MEAT-INF目录,里面有一个文件叫做spring.factories,里面就记录了所有可以加载和支配启动加载的Bean,里面有PropertySourceLoader,配置信息

在我们的MyBatis中,我们为什么可以将Mapper接口直接进行注入使用?

我们为什么只在UserService里面写了一个@Resource就可以把标记了@Mapper的接口直接注入使用?

表面上是一个接口,但实际上咱们的程序时不会进行new这个接口的,而是我们使用代理的方式来进行实现的(调用动态代理子类)
 

1)JVM从JDK1.6是有锁升级的一个过程的,偏向锁--->轻量级锁---->重量级锁,在对象头里面有一个标识,用来表示当前有没有锁,是属于哪一个线程里面的,会进行判断线程ID和我们对象头中的线程ID是不是一致的,如果是一致的,那么代表我是可以重入的,重新获取到这把锁;

2)如果ID不同,就会尝试获取锁,使用自旋锁

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

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

相关文章

Python避坑指南(续)

在上一篇《Python避坑指南》中&#xff0c;我重点给大家讲了Python可变容器数据类型中的坑。除了这些&#xff0c;Python还有其他一些细小方面的坑&#xff0c;本章为大家讲解Python中这些大家可能会忽视的细节。 文章目录链式or的坑访问字面量属性的坑is的坑GIL全局锁的坑多数…

建模杂谈系列177 APIFunc继续实践-比对研究

说明 在最终的实用上,我还是选择了Kettle。主要还是因为考虑未来公司的部署和使用上有比较全的文档,也比较有说服力。所以有时候也挺有趣的: 1 其实APIFunc要好得多,但是(刚做完原型验证)并不能取得大部分人的信任2 有一些方法对于有一定基础的人来说很方便,但是对于更…

剑指offer试题整理1

1、定义一个空的类型&#xff0c;里面没有任何成员变量和成员函数。对该类型求sizeof&#xff0c;得到的结果是什么&#xff1f; 答案&#xff1a;1. 为什么不是0? 空类型的示例中不包含任何信息&#xff0c;本来求siezof应该是0&#xff0c;但是当我们声明改类型的实列是时…

Zookeeper的数据模型和节点类型

数据模型&#xff1a; 树形结构 zk维护的数据主要有&#xff1a;客户端的会话&#xff08;session&#xff09;状态及数据节点&#xff08;dataNode&#xff09;信息。 zk在内存中构造了个DataTree的数据结构&#xff0c;维护着path到dataNode的映射以及dataNode间的树状层级关…

asp.net+sqlserver团购网站c#

数据需求分析 该网站的主要功能主要体现在对各种信息的添加、修改、删除和查询的操作上&#xff0c;包括会员信息、公司管理信息、订单信息、产品信息、团购管理信息等&#xff0c;各部分的信息之间又有着内在联系&#xff0c;因此总结出如下需求&#xff1a; &#xff08;1&am…

使去中心化媒体网络相关联的NFT元数据标准

1. 概述 (社交)媒体网络的力量日益强大。我们需要分散这种力量&#xff0c;使网络更加透明。 由于网络效应&#xff0c;新媒体网络和能够与现有网络竞争的去中心化替代方案很难吸引广大公众。 我们建议&#xff0c;与其创建新的协议&#xff0c;将每个平台的内容隔离起来&…

录屏怎么录,这2个方法不容错过!

​我们都知道在电脑使用频率越来越高的现在&#xff0c;无论是生活中还是工作中&#xff0c;有时可能会因为一些需要&#xff0c;使用到录屏的功能。最近&#xff0c;有不少的小伙伴前来询问小编&#xff0c;录屏怎么录&#xff1f;其实答案很简单&#xff0c;接下来小编分享的…

手机号码认证什么价格?手机号码认证怎样申请?

手机号码认证基于通话场景(呼入&#xff0c;呼出)的指定号码&#xff0c;来电展示企业号码专门名称&#xff0c;可提高电话号码辨识度&#xff0c;防止错误标记&#xff0c;提升品牌曝光度、接听率&#xff0c;低成本提升目标顾客接听率。 手机号码认证如何收费呢&#xff1f;…

【附源码】Python计算机毕业设计图书销售网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

数据结构和算法 IV

数据结构和算法 IV 面试题 冒泡排序 排序算法 原理机制: 相邻元素两两比较,大的/小的往后排,一轮比较结束,最大值出现在最大下标处.会比较多轮 代码实现 public static void main(String[] args) {int[] ary {23,12,7,0,67,9,11};for (int i0;i<ary.length-1;i){ //i…

MySQL高频面试题

1. drop&#xff0c;delete和truncate删除数据的区别&#xff1f; delete 语句执行删除是每次从表中删除一行&#xff0c;并且同时将改行的删除操作作为事务记录在日志中保存以便进行回滚。 truncate 则是一次从表中删除所有的数据并不把单独的删除操作记录计入日志&#xff0c…

详述分布式事务Seata TCC空回滚/幂等/悬挂问题、解决方案(seata1.5.1如何解决?)

文章目录一、前言二、问题介绍、seata1.5.1版本之前的解决方案1、空回滚出现原因解决措施事务控制记录表try()、cancel()中获取xid、branch_id2、幂等出现原因解决措施事务控制记录表3、悬挂出现原因解决措施4、总述最终的事务控制记录表三、seata1.5.1版本起官方提供的解决措施…

[附源码]java毕业设计基于Java烟支信息管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

前端框架 网络请求 Fetch Axios

目录 一、Fetch请求的使用 1、 Fetch官网 2、基本案例 二、跨域请求解决 三、Axios的使用 1、Axios官网 2、基本使用 推荐使用Axios更方便&#xff01; 一、Fetch请求的使用 1、 Fetch官网 使用 Fetch - Web API 接口参考 | MDN 2、基本案例 二、跨域请求解决 &…

2023第二届中国能源管理碳中和国际峰会

峰会背景 应对气候变化已经成为21世纪人类社会面临的紧迫挑战&#xff0c;推进绿色发展成为全球共识。中国积极参与和引导应对气候变化国际合作&#xff0c;向世界作出“力争2030年前实现碳达峰、2060年前实现碳中和”的承诺&#xff0c;逐步完善碳达峰碳中和“1N”政策体系&a…

史上最全安装Maven教程一看就会吊炸天的教程

史上最全安装Maven教程 简单了解一下什么是Maven 1.Maven翻译为“专家“&#xff0c; ”内行”的意思&#xff0c;是著名Apache公司下基于Java开发的开源项目。 2.Maven项目对象模型&#xff08;POM&#xff09;是一个项目管理工具软件&#xff0c;可以通过简短的中央信息描述…

LeetCode第 319 场周赛题解

目录2469. 温度转换2470. 最小公倍数为 K 的子数组数目2471. 逐层排序二叉树所需的最少操作数目2472. 不重叠回文子字符串的最大数目2469. 温度转换 模拟 class Solution { public:vector<double> convertTemperature(double celsius) {return {celsius273.15,celsius*1…

前端面试中小型公司都考些什么

什么是物理像素&#xff0c;逻辑像素和像素密度&#xff0c;为什么在移动端开发时需要用到3x, 2x这种图片&#xff1f; 以 iPhone XS 为例&#xff0c;当写 CSS 代码时&#xff0c;针对于单位 px&#xff0c;其宽度为 414px & 896px&#xff0c;也就是说当赋予一个 DIV元素…

Ubuntu20.04 中已经安装 Pytorch 但 Import 报错 - 解决记录

01 问题描述 笔者使用的是 Ubuntu 20.04.3 LTS&#xff0c;在使用 PyTorch 训练模型的时候&#xff0c;torch 模块引用失败&#xff0c;报错信息是 OSError: /home/wang/.local/lib/python3.8/site-packages/torch/lib/../../nvidia/cublas/lib/libcublas.so.11: undefined s…

C++对象和类概述

11 对象和类 11.1 过程式和面向对象编程 面向过程编程&#xff1a;先考虑函数&#xff0c;然后再细化到数据 面向对象编程&#xff1a;对象&#xff08;数据函数&#xff09; 11.2 抽象和类 在计算中&#xff0c;抽象是根据与用户的接口来表示信息的关键步骤。 11.2.1 什…