【百面成神】spring基础12问,你能坚持到第几问

news/2024/11/27 8:45:07/

在这里插入图片描述

前 言
🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端
☕专栏简介:java面试宝典,特点:全、精、深、简,力求每个核心知识点1分钟回答好。
🌰 文章简介:本文将介绍spring核心的面试12问

文章目录

  • 一、Spring
    • 1.谈谈你理解的spring
    • 2.谈谈spring的优缺点
  • 二、IOC
    • 3.谈谈你对IOC的理解
    • 4.谈谈IOC的实现机制是什么
    • 5.从源码角度说下Spring IOC的加载过程
  • 三、bean
    • 6.聊聊你对Spring Bean的了解?
    • 7.Spring Bean的默认作用域是什么?它有什么优势
    • 8.Spring中bean是线程安全的吗?
    • 9.什么是自动装配?它有几种方式
    • 10.谈谈spring中bean的生命周期?
    • 11.Spring中Bean的循环依赖问题是如何解决的?
  • 四、注解
    • 12.@Component,@Repository,@Service,@Controller有什么区别?

一、Spring

1.谈谈你理解的spring

在这里插入图片描述

2.谈谈spring的优缺点

(1)优点:

先回顾下spring的特性:IOC、AOP、事务、功能性的封装

IOC带来的优点:

  • 集中管理了对象,使对象之间的耦合度降低了。

  • 对象的开发维护变得简单了。

AOP带来的优点:

  • 可以在不修改代码的情况下进行功能增强,并且减少了重复的代码,提高了代码的维护,降低了代码冗余

事务声明:

  • spring事务机制简化了开发

功能性的封装:

  • 封装了许多功能性代码,如jdbctemplate,也方便于集成各个优秀框架,可以帮助方便的使用三方框架,简化了开发。

源码:spring的底层大量运用反射、设计模式等,其源码也是不可多得的宝贵学习资料。

(2)缺点:

简化了开发,从应用角度上更好,但是对于底层的细节进行了封装,想要了解底层就更加困难。而且它大而全,源码代码量达百万,不易研究源码。

二、IOC

3.谈谈你对IOC的理解

IOC的意思是控制反转,控制反转的意思就是将创建对象的权力转移到容器来完成。

以前创建一个对象,是由程序员通过new一个对象来创建,这样会造成两个问题:
(1)耦合度过高,这其实本质上是面向接口编程的问题。如果通过硬编码写了一个superclass A= new subclass(),如果想要使用另外一个subclass,就需要更改源码重新编译。如果使用Spring IOC来做,只需要更改配置即可。

(2)维护不方便。在实际项目中一个 Service 类可能依赖了很多其他的类,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方使用@Autowired注解自动注入(DI)就行了,这大大增加了项目的可维护性且降低了开发难度。

控制反转可以达到解耦和方便维护的目的。

注:
Spring IOC和DI的区别是什么?
IOC是思想,DI是实现,是实现IOC的关键一步。

4.谈谈IOC的实现机制是什么

Spring IOC实际上是通过简单工厂设计模式和反射来实现的。所谓简单工厂设计模式其实就是通过传入一个标识,根据标识选择生产对应的对象。通过简单工厂模式(BeanFactory.getbean())会带来一个问题,就是需要给每一个对象提供一个创建的过程,如果创建的对象变化,还需要改源码。因此引入反射机制,将类的完整类路径作为参数传递给工厂,工厂通过反射机制直接获取对象返回即可。

注:为了方便理解,可以参考如下代码。
在这里插入图片描述

5.从源码角度说下Spring IOC的加载过程

第一步:通俗理解就是通过bean工厂的后置处理器将配置文件转化为一个对应的java类。
在这里插入图片描述
第二步:通俗理解就是通过简单工厂模式和反射来实例化对象
在这里插入图片描述
第三步:通俗理解就是通过依赖注入来完成对象的属性注入工作
在这里插入图片描述

三、bean

6.聊聊你对Spring Bean的了解?

(1) 什么是Spring Bean
被spring IOC容器管理、实例化的对象称之为spring的bean。

(2)怎么配置Spring Bean
可以通过如下四种方式配置Spring Bean。
在这里插入图片描述
(3)Bean有哪些作用域
单例、多例,request(针对web应用,一个请求创建一个request对象),session(web 应用,会话),application(一个全局的应用)

7.Spring Bean的默认作用域是什么?它有什么优势

Spring默认的Bean是单例,对象只会创建一次。

具有如下优势:
在这里插入图片描述

8.Spring中bean是线程安全的吗?

Spring默认的Bean是单例,多个线程操作的是同一个对象,如果在类中声明了成员变量,并且进行了读写操作(有状态),就会出现线程安全问题。

但是,我们如果把变量声明在方法中,就是线程安全的。将成员变量使用ThreadLocal修饰,将操作方法或者代码块加上synchronized同步锁(并行会变成串行,影响吞吐量),或者将bean设置为多例,也可以保证线程安全。

9.什么是自动装配?它有几种方式

自动装配就是指,spring中的对象无需手工创建其依赖对象,可以由容器创建需要依赖的对象并进行装配。
在这里插入图片描述

10.谈谈spring中bean的生命周期?

在这里插入图片描述

11.Spring中Bean的循环依赖问题是如何解决的?

循环依赖是指spring中多个对象相互依赖,导致在容器创建对象过程时出现互相嵌套的问题。

在这里插入图片描述

八股文结束。

详细理解:

循环依赖可以参考下图理解。
在这里插入图片描述
其中AServce的生命周期如下图。
在这里插入图片描述
在上图中要填充bService对象,就需要从单例池中获取一个bService对象。如果此时bService没有创建,在单例池找不到,因此需要触发bService的生命周期创建bService。而bService创建时,也需要填充aService,就会循环套娃,这就是所谓的循环依赖。

因此需要打破循环,因此需要从其它地方找到一个aService对象。因此可以考虑在aService的生命周期第一步就进行一次缓存(一级缓存),因为尽管此时已经有一个无参的aService对象了。具体的细节可以参考下图理解。

在这里插入图片描述
不过,上面的做法其实埋了坑。考虑如果aService执行了AOP,那么就会创建一个代理类,在生命周期的第五步,实际上加入单例池中是其代理类对象。而bService在填充时获得的是一个aService对象,这不就不一致了么。

实际上,在bService填充时应该也是填充一个aService的代理对象(加强了功能)。要做到这一点,就应该在第一步就进行aService的AOP。

按照这个思路走,aService的生命周期如下。

在这里插入图片描述
不过,这样bean的生命周期设计就乱了啊。第1步就创建AOP,第4步还创建不创建了?最好能够判断是否出现循环依赖,只有出现循环依赖时才提前创建AOP代理对象。可以在aService创建时就设置一个状态量进行下标记,如果在创建bService发现aService还没有创建完,就可以知道出现循环依赖问题了。
在这里插入图片描述
现在考虑三个对象的情况,如果aService还和cService也出现了循环依赖会咋样?答案是冗余操作。而且进行了两次AOP,那么bService和cService中填充的还是同一个代理对象么?不是了啊
那么我们在第一次AOP产生代理对象,把它放到单例池中不就可以了?

但是,单例池中是啥都可以放的吗?它只能够放一个完整的对象,这些过程中的对象你也放进去么?

还是分清楚点最后,引入二级缓存。

在这里插入图片描述
似乎大功告成了。不过现在可存在一个大问题。在2.1进行AOP生成代理对象时,代理对象需要有一个aService类型的属性啊。哦豁,还是没有啊。

引入三级缓存。问题解决。

在这里插入图片描述
实际上,第1步三级缓存中存的并不是一个aServce的对象,而是一个Lambda表达式,即一个函数式接口。其存储的源码如下。
在这里插入图片描述
为什么呢?这说明三级缓存只存储一个变量不够,它需要存储方法。实际上,它里面包含判断AOP判断是否要进行AOP代理的代码逻辑。

四、注解

12.@Component,@Repository,@Service,@Controller有什么区别?

  • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。这是Repository,Service和Controller的元注解。
  • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
  • @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。

http://www.ppmy.cn/news/35000.html

相关文章

Python用湖南天气详情数据(可惜没雨),进行简单的可视化分析

前言 Echarts是一个开源的数据可视化JS库,pyecharts是一款将python与echarts结合的强大的数据可视化工具 开发环境 python 3.8pycharm 2022.3.2 完整源码看这里这里👈👈👈 先来获取我们想要的天气数据 请求数据 因为是静态网…

数据仓库相关面试题

1.请介绍一下星型模型和雪花模型的区别及适用场景。 星型模型和雪花模型是数据仓库中常见的两种数据建模方式。 星型模型是由一个中心事实表和多个与之相关的维度表构成的,维度表通常只有一层,每个维度表只关联一个事实表。在星型模型中,事实…

Sketch for mac(专业矢量绘图设计软件)图文安装教程

Sketch是一款Mac上的矢量图形设计软件,专门用于UI/UX设计,它能够帮助设计师快速创建高质量的数字产品原型和界面设计方案。 Sketch具有简单易用的界面,支持多种插件和扩展,可以轻松地集成到设计工作流程中。Sketch内置了多种常用…

CentOS支持中文

一般 centos 默认支持语言 en_US.UTF-8,但是这样会有中文乱码的出现,我们需要设置成 zh_CN.UTF-8 才行。 1.查看系统是否安装有中文语言包 locale -a | grep “zh_CN” 命令含义:列出所有可用的公共语言环境的名称,包含有"z…

如何巧妙应用JMeter的Dummy Sampler

很少人知道Dummy Sampler这个采样器(扩展插件里带的),也不知道它的妙用。Dummy Sampler 可以比较方便地模拟测试场景,自定义Request Data和Response Data,在学习测试脚本编写的过程中非常有用。另外如果巧妙应用它,可以在开发人员出接口文档后(接口还没实现)就可以同步…

【Vue2从入门到精通】详解Vue.js的15种常用指令及其使用场景

文章目录前言1. v-text / {{ expression }}2.v-html3.v-bind4.v-on5. v-model6.v-for7.v-if / v-else-if / v-else9.v-show10.v-cloak11.v-pre12.组件注册指令13.动态组件指令14.自定义指令15.过滤器指令前言 Vue.js 是一款流行的前端框架,它通过指令(Di…

【数据结构】千字深入浅出讲解栈(附原码 | 超详解)

🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:C语言实现数据结构 💬总结:希望你看完…

2023年总结的web前端学习路线分享(学习导读)

如果你打开了这篇文章,说明你是有兴趣想了解前端的这个行业的,以下是博主2023年总结的一些web前端的学习分享路线,如果你也想从事前端或者有这方面的想法的,请接着往下看! 前端发展前景 前端入门 巩固基础 前端工程…