Spring相关面试题(一)

Spring

1.谈谈你对Spring的理解 难度系数

Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的JavaBean 实现以前只有EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。

Spring 容器的主要核心是:

控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring 提供的对象就可以了,这是控制反转的思想。

依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。

面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。

2.Spring中常见的设计模式
  • 工厂模式:Spring使用工厂模式,通过BeanFactory和ApplicationContext来创建对象

  • 单例模式:Bean默认为单例模式

  • 适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式,Spring MVC中也是用到了适配器模式适配Controller

  • 模板方法:可以将相同部分的代码放在父类中,而将不同的代码放入不同的子类中,用来解决代码重复的问题。比如RestTemplate, JmsTemplate, JpaTemplate

  • 策略模式:例如Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略

  • 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术

  • 桥接模式:可以根据客户的需求能够动态切换不同的数据源。比如我们的项目需要连接多个数据库,客户在每次访问中根据需要会去访问不同的数据库

3.Spring的三级缓存

三级缓存就是三个Map对象

/**
​单例对象的缓存:bean名称—bean实例,即:所谓的单例池。
​表示已经经历了完整生命周期的Bean对象
​第一级缓存
​
*/
​
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/**
​早期的单例对象的高速缓存: bean名称—bean实例。
​表示 Bean的生命周期还没走完(Bean的属性还未填充)就把这个 Bean存入该缓存中也就是实例化但未初始化的 bean放入该缓存里
​第二级缓存
​*/
​
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
​
/**
​单例工厂的高速缓存:bean名称—ObjectFactory
​表示存放生成 bean的工厂
​第三级缓存
​*/
​
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
​
​

4.Bean的生命周期
  • 实例化 Instantiation

    • Bean实例化的时机也分为两种,BeanFactory管理的Bean是在使用到Bean的时候才会实例化Bean,ApplicantContext管理的Bean在容器初始化的时候就回完成Bean实例化。

  • 属性赋值 Populate

  • 初始化 Initialization

    • 检查Aware的相关接口依赖,作用是:让Bean拿到容器的一些资源,如BeanNameAware 和 BeanName

    • 后处理器-->进行一些前置和后置的处理

    • 生命周期接口->InitializingBean和DisposableBean 接口就是用来定义初始化方法和销毁方法的

    • 配置生命周期方法

  • 销毁 Destruction

  1. Bean容器在配置文件中找到Person Bean的定义,这个可以说是妈妈怀上了。

  2. Bean容器使用Java 反射API创建Bean的实例,孩子出生了。

  3. Person声明了属性no、name,它们会被设置,相当于注册身份证号和姓名。如果属性本身是Bean,则将对其进行解析和设置。

  4. Person类实现了BeanNameAware接口,通过传递Bean的名称来调用setBeanName()方法,相当于起个学名。

  5. Person类实现了BeanFactoryAware接口,通过传递BeanFactory对象的实例来调用setBeanFactory()方法,就像是选了一个学校。

  6. PersonBean实现了BeanPostProcessor接口,在初始化之前调用用postProcessBeforeInitialization()方法,相当于入学报名。

  7. PersonBean类实现了InitializingBean接口,在设置了配置文件中定义的所有Bean属性后,调用afterPropertiesSet()方法,就像是入学登记。

  8. 配置文件中的Bean定义包含init-method属性,该属性的值将解析为Person类中的方法名称,初始化的时候会调用这个方法,成长不是走个流程,还需要自己不断努力。

  9. Bean Factory对象如果附加了Bean 后置处理器,就会调用postProcessAfterInitialization()方法,毕业了,总得拿个证。

  10. Person类实现了DisposableBean接口,则当Application不再需要Bean引用时,将调用destroy()方法,简单说,就是人挂了。

  11. 配置文件中的Person Bean定义包含destroy-method属性,所以会调用Person类中的相应方法定义,相当于选好地儿,埋了

5.Bean的作用域
  • singleton

  • prototype

    • 在创建Bean的时候

      @Scope("prototype")
      //@Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)
      //通过Spring内置定义的字符串设置属性也行
      @Beans
      public Cat cat(){Cat cat = new Cat();cat.setName("莫妮卡");return cat;
      }

还有四种是在Spring MVC中才生效的:

  1. request(请求作用域): 一次http请求中会生成一个新的Bean实例类似于prototype

场景: 一次http的请求和响应共享Bean.

  1. session(会话作用域): 在http session中定义一个Bean实例

场景: 在用户会话中共享Bean.例如:可以用来记录一个用户的登录信息

  1. application(全局作用域): 在⼀个http servlet Context中,定义⼀个Bean实例

场景:Web应用的上下文信息.

  1. websocket(HTTP WebSocket作用域): 在一个HTTP WebSocket生命周期中,定义一个Bean实例

场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀ 次初始化后,直到WebSocket结束都是同⼀个Bean.

6.Spring的IOC容器,介绍一下?

IOC:控制反转,原因如果想要创建一个对象,是使用new或者通过反射getInstance等方式,这样创建对象,耦合性太高,也不利于复用;引用了SpringIOC,把对象的创建权利交给IOC容器,在使用的时候,可以通过DI(@Autowired等)自动注入,而且IOC的Bean通常情况下也是单例的,可以节约资源;方便集中管理和维护,降低耦合度。

7.Spring的IOC的实现机制。

工厂模式 + 反射

public class IOC {
​public static void main(String[] args) {
​/*加载* <bean class="com.xing.Spring.User">  写xml的时候,会把这些信息写到这里。* */new ClassPathXmlApplicationContext("applicationContext.xml");User user = Factory.getUser("com.xing.Spring.User");}
}
class Factory{public static User getUser(String classPath){User user = null;try {user = (User) Class.forName(classPath).newInstance();}catch (Exception e){e.printStackTrace();}return user;}
}
class User{private String name;public void setName(String name) {this.name = name;}
}
8.IOC 和 DI的区别

IOC是用来解决耦合的设计思想,是控制反转的,创建对象的权利交给Spring。

DI是IOC的实现,是IOC中重要的一环,用来把容器中的对象进行注入。

9.紧耦合和松耦合区别,如何写松耦合的代码。
  • 紧耦合

    • 类和类之间的高度依赖。

  • 松耦合

    • 松耦合是通过促进单一职责和关注点分离、依赖倒置和设计原则实现的。

10.BeanFactory的作用
  • BeanFactory是Spring中非常核心的一个顶层接口它是Bean的“工厂”、它的主要职责就是生产Bean。

  • 它实现了简单工厂的设计模式,通过调用getBean传入标识生产一个Bean。

  • 它有非常多的实现类、每个工厂都有不同的职责(单一职责)功能,最强大的工厂是DefaultlistableBeanFactory Spring底层就是使用的该实现工#行生产Bean的

  • BeanFactory他是容器 Spring容器(管理者某个对象的生命周期)

11.BeanDefinition的作用
  • 存储Bean的定义信息。

  • 之后BeanFactory就可以根据这些信息,通过反射获得一个Bean对象。

Bean的XML信息 ----存储----> BeanDefinition ----获取----> BeanFactory 创建bean对象。

一个Bean信息就对应一个BeanDefinition ,BeanDefinition放在一个集合中。

12.BeanFactory 和 ApplicationContext区别

相同

  • 都可以作为容器,管理Bean的生命周期。

不同

  • BeanFactory用于Bean的生产

  • ApplicationContext实现了BeanFactory接口,也有getBean的方法,底层也是通过BeanFactory来获得。

  • 相对于BeanFactory,ApplicationContext会自动注册Bean,也会加载环境变量,实现Spring的事件监听等等;ApplicationContext做的事更多。

13.Spring IOC容器的加载过程

四个形态

概念态---<Bean信息>---> 定义态----BeanDefinition---->纯净态----DI---->成熟态

对应Bean的生命周期

实例化 --> 属性注入 ---> 实例化

概念态---->定义态

  1. 实例化一个ApplicationContext的对象

  2. 调用bean工厂后置处理器完成扫描;

  3. 循环解析扫描出来的类信息;

  4. 实例化一个BeanDefinition对象来存储解析出来的信息

  5. 把实例化好的beanDefinition对象put到beanDefinitionMap当中缓存起来以便后面实例化bean;

  6. 再次调用其他bean工厂后置处理器

定义态----BeanDefinition---->纯净态

  1. 当然spring还会干很多事情,比如国际化,比如注册BeanPostProcessor等等,如果我们只关心如何实例化一个bean的话那么这一步就是spring调用finishBeanFactoryinitialization方法来实例化单例的bean,实例化之前spring要做验证需要遍历所有扫描出来的类,依次判断这个bean是否Lazy,是否prototype,是否 abstract等等;

  2. 如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法;

  3. 推断完构造方法之后spring调用构造方法反射实例化一个对象;注意我这里说的是对象、对象、对象;这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入,所以不是一个完整的bean;10:spring处理合并后的beanDefinition

纯净态----DI---->成熟态

  1. Spring处理合并的BeanDefinition

  2. 判断是否需要完成属性注入

  3. 如果需要,则开始注入

初始化

  1. 判断bean的类型回调Aware接口。

  2. 调用生命周期回调方法

  3. 如需要代理完成代理

创建完成

  1. 放到单例池中去。

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

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

相关文章

进阶篇06——锁

概述 全局锁 表级锁 表锁 元数据锁 元数据锁是系统自动加的&#xff0c;不需要我们手动执行命令添加。 意向锁 意向锁和元数据锁一样&#xff0c;也是在加行锁的时候自动给表加上相应的意向锁&#xff0c;不需要我们手动添加。 行级锁 行锁 读锁和读锁兼容&#xff0c;写锁…

易舟云财务软件:开启云记账新时代

在数字化浪潮的推动下&#xff0c;财务管理正经历着深刻的变革。易舟云财务软件&#xff0c;作为一款引领时代的云记账平台&#xff0c;以其卓越的功能和便捷的操作&#xff0c;为企业带来了全新的财务管理体验。 云记账&#xff0c;财务管理的未来趋势 云记账&#xff0c;即基…

免费试用【汇通动态域名】体验test.htdns.cn

汇通动态域名下载地址&#xff1a; http://www.htsoft.com.cn/htsoft/htdnssoft.html 下载后汇通动态域名是绿色软件&#xff0c;不用安装&#xff0c;直接运行htdns.exe 点注册 二级域名地方改成您自己要的域名&#xff0c;我输入的是test,点保存&#xff0c;提示让您输入密…

2024年618成交额达7428亿 淘宝京东618交易额数据对比排名

2024年618年中大促已经基本落下帷幕&#xff0c;作为上半年最重要的电商节日&#xff0c;今年的618交易额有多少&#xff1f;今年的交易数据有哪些变化&#xff1f;我们来一起看一下&#xff01; 根据星图监测数据显示&#xff0c;2024年618期间&#xff08;天猫5月20日20: 00-…

Python 中的 Pandas(数据分析与处理)

Pandas 是 Python 中最受欢迎的数据处理库之一&#xff0c;其名字源自于“Panel Data”&#xff08;面板数据&#xff09;的缩写。它提供了三种主要的数据结构&#xff1a;Series &#xff0c; DataFrame &#xff0c; Panel&#xff08;在新版本已经被弃用&#xff09; 数…

海外盲盒APP开发,盲盒出海热!

当下&#xff0c;盲盒作为一种热门的娱乐休闲模式&#xff0c;在全球消费市场中都非常火热&#xff0c;各种热门盲盒商品刚一上线就受到了秒杀&#xff0c;受到了各地年轻消费者的追捧&#xff01; 盲盒全球化对于我国盲盒企业来说是一个新的机会&#xff0c;有助于我国盲盒快…

华为云下Ubuntu20.04中Docker的部署

我想用Docker拉取splash&#xff0c;Docker目前已经无法使用&#xff08;镜像都在国外&#xff09;。这导致了 docker pull 命令的失败&#xff0c;原因是timeout。所以我们有必要将docker的源设置在国内&#xff0c;直接用国内的镜像。 1.在华为云下的Ubuntu20.04因为源的原因…

uniapp+unocss报错Error [ERR_REQUIRE_ESM]: require() of ES Module

uniappvue3使用unocss报错 vite.config.ts代码&#xff1a; import { defineConfig } from "vite"; import uni from "dcloudio/vite-plugin-uni"; import AutoImport from "unplugin-auto-import/vite"; import Unocss from unocss/vite;expo…

Python 基础:文件

目录 一、从文件中读取数据1.1 读取整个文件1.2 逐行读取 二、写入文件2.1 写入空文件2.2 写入多行2.3 附加到文件 遇到看不明白的地方&#xff0c;欢迎在评论中留言呐&#xff0c;一起讨论&#xff0c;一起进步&#xff01; 本文参考&#xff1a;《Python编程&#xff1a;从入…

java-Object 底层实现

### 4. Object类的底层实现 #### 4.1 内存布局 在Java虚拟机中&#xff0c;每个对象都有一个头部&#xff08;Header&#xff09;&#xff0c;包含对象的元数据和同步信息。对象头部包括两个主要部分&#xff1a; - **Mark Word**&#xff1a;用于存储对象的哈希码、GC年龄、…

[modern c++] 类型萃取 type_traits

前言&#xff1a; #include <type_traits> type_traits 又叫类型萃取&#xff0c;是一个在编译阶段用于进行 类型判断/类型变更 的库&#xff0c;在c11中引入。因为其工作阶段是在编译阶段&#xff0c;因此被大量应用在模板编程中&#xff0c;同时也可以结合 constexpr…

如何理解shell命令 cd $(dirname $0)

理解命令 cd $(dirname $0) 需要逐步拆解和分析每个部分的功能&#xff1a; $0&#xff1a; 在shell脚本中&#xff0c;$0 代表脚本的名称。这个变量包含了脚本的完整路径或相对路径。 dirname $0&#xff1a; dirname 是一个命令&#xff0c;用于去掉路径中的文件名部分&…

【CT】LeetCode手撕—141. 环形链表

目录 题目1- 思路2- 实现⭐141. 环形链表——题解思路 3- ACM实现 题目 原题连接&#xff1a;141. 环形链表 1- 思路 模式识别 模式1&#xff1a;判断链表的环 ——> 快慢指针 思路 快指针 ——> 走两步慢指针 ——> 走一步判断环&#xff1a;若快慢相遇则有环&a…

大模型推理优化技术概述

大模型推理优化技术概述 KVcache一句话总结&#xff1a;KV cache背景KV cache 计算过程PageAttention概述背景&#xff1a; MHD、MQA、GQA注意力机制MHAMQAGQA Flash Attention KVcache一句话总结&#xff1a; KV cache其实就是通过空间换取时间的方式&#xff0c;通过缓存Atte…

QTday5 2024-06-19

作业要求&#xff1a; 1.思维导图 2.整理代码&#xff1a;TCP服务器 作业1&#xff1a;思维导图 作业2&#xff1a;整理代码 运行代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QList>…

信息安全技术基础知识-经典题目

【第1题】 1.在信息安全领域&#xff0c;基本的安全性原则包括机密性(Confidentiality)、完整性(Integrity)和 可用性(Availability)。机密性指保护信息在使用、传输和存储时 (1) 。信息加密是保证系统机密性的常用手段。使用哈希校验是保证数据完整性的常用方法。可用性指保证…

边学边赛拿冠军!北邮学子勇夺昇腾AI原生创新算子挑战赛金奖

导读 如何从零开始学习算子开发&#xff1f;昇腾AI原生创新算子挑战赛冠军“法宝”大揭秘。 “0xCCCCCCCC团队夺冠&#xff01;” 2024年5月9日&#xff0c;在首届昇腾AI原生创新算子挑战赛S1赛季决赛现场&#xff0c;来自北京邮电大学0xCCCCCCCC团队的孙明志和梁昊骞以总分第…

金蝶BI方案与奥威BI:智能、高效的数据分析组合

在当今数据驱动的时代&#xff0c;企业对于快速、准确、全面的数据分析需求日益增长。金蝶BI方案和奥威BI SaaS平台正是为满足这一需求而精心打造的智能数据分析工具。 方案见效快 金蝶BI方案以其高效的数据处理能力&#xff0c;能够快速地将海量数据转化为有价值的信息。通过…

uniapp 微信小程序自定义分享图片

场景&#xff1a;微信小程序用户&#xff0c;点击小程序里商品的分享按钮时&#xff0c;想要不同的商品展示不用的分享内容&#xff0c;比如分享图片上展示商品的图片、价格等信息。分享的UI图如下&#xff1a; 实现方法&#xff1a; 1. 分享按钮&#xff1a;<button open-…

Debian 时间同步处理

1.NTP授时的基本框架 时间同步在Debian环境使用NTP服务实现&#xff0c;在Debian平台&#xff0c;NTP是一个双向的协议——Debian&#xff0c;linux在设计时与git类似&#xff0c;有去中心化的考量。一些拥有固定IP的Debian设备&#xff0c;Debian鼓励这些用户加入NTP 服务池&…