【面试专题】Spring篇①

📃个人主页:个人主页

🔥系列专栏:Java面试专题

 

目录

 

1.你知道 Spring 框架中有哪些重要的模块吗?

2. 谈谈你对 IOC 的认识。

3. 谈谈你对 AOP 的认识。

4.在实际写代码时,有没有用到过 AOP?用过的话是在什么地方或者什么场景下?

5.Spring中的事务是如何实现的

6.Transaction 在哪些情况下可能会失效?

7.说说你对 Spring 中的 Bean 的理解。

8. 有哪些方法往 Spring 容器中添加 Bean。

9.Spring框架中的单例bean是线程安全的吗?

10.Spring的bean的生命周期


1.你知道 Spring 框架中有哪些重要的模块吗?

(1)核心层
Core Container:核心容器,这个模块是Spring最核心的模块,其他的都需要依赖该模块。


(2)AOP层
AOP:面向切面编程,它依赖核心层容器,目的是在不改变原有代码的前提下对其进行功能增强
Aspects:AOP是思想,Aspects是对AOP思想的具体实现


(3)数据层
Data Access:数据访问,Spring全家桶中有对数据访问的具体实现技术
Data Integration:数据集成,Spring支持整合其他的数据层解决方案,比如Mybatis
Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现


(4)Web层
提供创建 Web 应用程序的能力


(5)Test层
Spring主要整合了Junit来完成单元测试和集成测试
 

2. 谈谈你对 IOC 的认识。

IoC(Inversion of Control)是控制反转的意思,这是一种面向对象编程的设计思想。在不采用这种思想的情况下,我们需要自己维护对象与对象之间的依赖关系,很容易造成对象之间的耦合度过高,在一个大型的项目中这十分的不利于代码的维护。IoC则可以解决这种问题,它可以帮我们维护对象与对象之间的依赖关系,降低对象之间的耦合度。

说到IoC就不得不说DI(Dependency Injection),DI是依赖注入的意思,它是IoC实现的实现方式,就是说IoC是通过DI来实现的。由于IoC这个词汇比较抽象而DI却更直观,所以很多时候我们就用DI来代替它,在很多时候我们简单地将IoC和DI划等号,这是一种习惯。而实现依赖注入的关键是IoC容器,它的本质就是一个工厂。

在具体的实现中,主要由三种注入方式:

  1. 构造方法注入

    就是被注入对象可以在它的构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。然后,IoC Service Provider会检查被注入的对象的构造方法,取得它所需要的依赖对象列表,进而为其注入相应的对象。构造方法注入方式比较直观,对象被构造完成后,即进入就绪状态,可以马上使用。

  2. setter方法注入

    通过setter方法,可以更改相应的对象属性。所以,当前对象只要为其依赖对象所对应的属性添加setter方法,就可以通过setter方法将相应的依赖对象设置到被注入对象中。setter方法注入虽不像构造方法注入那样,让对象构造完成后即可使用,但相对来说更宽松一些, 可以在对象构造完成后再注入。

  3. 接口注入

    相对于前两种注入方式来说,接口注入没有那么简单明了。被注入对象如果想要IoC Service Provider为其注入依赖对象,就必须实现某个接口。这个接口提供一个方法,用来为其注入依赖对象。IoC Service Provider最终通过这些接口来了解应该为被注入对象注入什么依赖对象。相对于前两种依赖注入方式,接口注入比较死板和烦琐。

总体来说,构造方法注入和setter方法注入因为其侵入性较弱,且易于理解和使用,所以是现在使用最多的注入方式。而接口注入因为侵入性较强,近年来已经不流行了。

🍉扩展阅读🍉

如何使用 IOC

在 Spring5 之后,注解代替配置文件成了编程的主流趋势,下面展示如何使用注解实现 IOC。

首先创建一个配置文件类 MainConfig,这个类使用 @Configuration 修饰,声明它是个配置类:

import org.springframework.context.annotation.Configuration;@Configuration
public class MainConfig {
}

创建具体的 Student 类:

public class Student {private String name;private int age;public int getAge() {return age;}public String getName() {return name;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}
}

在未使用 IOC 之前,创建对象实例的方式是通过 new()。比如创建 Student 类时通过 Student student = new Student() 这行代码。而使用 IOC 的话需要把 Student 这个类交给 Spring 容器。在 MainConfig 类中增加以下代码:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MainConfig {@Beanpublic Student student(){return new Student();}
}

被 Spring 容器管理的 Bean 可以通过 @Autowired 注解和 annotationConfigApplicationContext.getBean("student",Student.class); 的方式获取到 Bean 对象。

3. 谈谈你对 AOP 的认识。

AOP(Aspect-Oriented Programming:面向切面编程)翻译为面向切面编程,能够将那些与业务无关的逻辑封装起来,从而减少系统的重复代码,降低模块之间的耦合度,同时也具备着更强的可扩展能力。

AOP的术语

  • 连接点(join point):对应的是具体被拦截的对象,因为Spring只能支持方法,所以被拦截的对象往往就是指特定的方法,AOP将通过动态代理技术把它织入对应的流程中。

  • 切点(point cut):有时候,我们的切面不单单应用于单个方法,也可能是多个类的不同方法,这时,可以通过正则式和指示器的规则去定义,从而适配连接点。切点就是提供这样一个功能的概念。

  • 通知(advice):就是按照约定的流程下的方法,分为前置通知、后置通知、环绕通知、事后返回通知和异常通知,它会根据约定织入流程中。

  • 目标对象(target):即被代理对象。

  • 引入(introduction):是指引入新的类和其方法,增强现有Bean的功能。

  • 织入(weaving):它是一个通过动态代理技术,为原有服务对象生成代理对象,然后将与切点定义匹配的连接点拦截,并按约定将各类通知织入约定流程的过程。

  • 切面(aspect):是一个可以定义切点、各类通知和引入的内容,SpringAOP将通过它的信息来增强Bean的功能或者将对应的方法织入流程。

Spring AOP

AOP可以有多种实现方式,而Spring AOP支持如下两种实现方式。

  • JDK动态代理:这是Java提供的动态代理技术,可以在运行时创建接口的代理实例。Spring AOP默认采用这种方式,在接口的代理实例中织入代码。

  • CGLib动态代理:采用底层的字节码技术,在运行时创建子类代理的实例。当目标对象不存在接口时,Spring AOP就会采用这种方式,在子类实例中织入代码。

4.在实际写代码时,有没有用到过 AOP?用过的话是在什么地方或者什么场景下?

记录操作日志,缓存,spring实现的事务

我曾经写过一个自定义日志的功能是通过 AOP 实现,核心是:使用aop中的环绕通知+切点表达式(找到要记录日志的方法)通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,保存到数据库。

5.Spring中的事务是如何实现的

Spring提供了两种事务管理方式:编程式事务管理和声明式事务管理。

编程式事务管理需要在代码中显式地声明事务的开始和结束,并手动处理事务的提交或回滚。这种方式比较灵活,但也比较繁琐。

声明式事务管理则是通过配置来实现事务管理,不需要在代码中显式地声明事务的开始和结束。声明式事务管理可以使用XML或注解方式进行配置。XML方式需要在Spring的配置文件中定义事务管理器和事务切面,而注解方式则使用@Transactional注解来标记需要进行事务管理的方法。

6.Transaction 在哪些情况下可能会失效?

①当用 Transactional 修饰非 public 方法时,Transactional 注解是不会生效的。

因为底层cglib是基于父子类来实现的,子类是不能重载父类的private方法的,所以无法很好的利用代理

②如果在一个类的内部调用了事务方法,Transactional 也不会生效。

开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。

这是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
 

③默认情况下只会在捕获了 RuntimeException 后 Transactional 注解才会生效,如果在代码中捕获了异常后未抛出,则 Transactional 失效。

7.说说你对 Spring 中的 Bean 的理解。

Spring 中的 Bean 简单来讲就是一个个被 Spring 容器管理的 Java 对象,我们写了一个类之后,这个类只是一个单纯的 Java 类,可以通过 new() 的方式去创建它。当我们把这个类添加到 Spring 的容器里之后,这个类就变成了 Bean,由 Spring 容器管理,可以通过自动注入的方式去使用。

8. 有哪些方法往 Spring 容器中添加 Bean。

常用的添加 Bean 的方式主要有以下几种方法:

  • @Bean: 写一个普通的类时最常用的添加 Bean 的方式
  • @ComponentScan + @Controller @Service @Component @Repository:@ComponentScan 用来扫描后面的四个注解,被后面四个注解修饰的类如果被 @ComponentScan 扫描到,就会注册到 Spring 容器中。
  • @Import:通过导入的方式注入 Bean。
  • @ImportBeanDefinitionRegister:和 Import 类似,可以指定 Bean 的名称。

9.Spring框架中的单例bean是线程安全的吗?

不是线程安全的
Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。因为一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。

10.Spring的bean的生命周期

①通过BeanDefinition获取bean的定义信息
②调用构造函数实例化bean
③bean的依赖注入
④处理Aware接口(BeanNameAware、 BeanFactoryAware、ApplicationContextAware)

⑤Bean的后置处理器BeanPostProcessor-前置
⑥初始化方法(InitializingBean、init-method)

⑦Bean的后置处理器BeanPostProcessor-后置
⑧销毁bean

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

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

相关文章

iOS开发Swift-1-Xcode创建项目

1.创建项目 双击Xcode App,选择Create a new Xcode project。 选择创建一个iOS普通的App项目。选择Single View App,点击Next。 填写项目名,组织名称等,点击next。 选择好文件的存储路径,点击create。 2.为前端添加组件…

学习笔记|认识数码管|控制原理|数码管实现0-9的显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第九集:数码管静态显示

文章目录 1.认识数码管2.控制原理十进制转换为任意进制其它进制转十进制 3.数码管实现0-9的显示1.用数组定义0-9的内码段码跟位码的区别2.尝试用延时实现0-9的循环显示3.用按键控制数字的加或者减。 总结课后练习: 1.认识数码管 数码管按段数可分为七段数码管和八段…

leetcode189. 轮转数组

题目: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例: 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2…

PowerDesigner学习笔记

备注:文章主要对概念数据模型进行深入分析 1.对各种模型图初步认识 1.1.概念数据模型 (CDM) (Conceptual Data Model) 对数据和信息进行建模,利用实体-关系图(E-R图)的形式组织数据,检验数据设计的有效性和合理性。 …

【数据结构-链表-01】反转链表

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

多个开源姿态检测模型项目,上手即用,实测可行!

编辑:OAK中国 项目来源:oakchina.cn 喜欢的话,请多多👍⭐️✍ ▌前言 Hello,大家好,这里是OAK中国,我是助手君。 我发现今年有不少朋友都想做姿态检测,正好我们也有不少客户做过这…

结构体(个人学习笔记黑马学习)

1、结构体的定义和使用 #include <iostream> using namespace std; #include <string>struct Student {string name;int age;int score; }s3;int main() {//1、struct Student s1;s1.name "张三";s1.age 18;s1.score 100;cout << "姓名&a…

Python中小数据池知识最详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一、id&#xff0c;is&#xff0c; 在Python中&#xff0c;id是什么&#xff1f; id是内存地址&#xff0c;比如你利用i…

【Unity小技巧】手戳一个简单易用的游戏UI框架(附源码)

文章目录 前言整套框架分为三大部分素材效果框架代码调用源码参考完结 前言 开发一款游戏美术成本是极其高昂的&#xff0c;以我们常见的宣传片CG为例&#xff0c;动辄就要成百上千万的价格&#xff0c;因此这种美术物料一般只会放在核心剧情节点&#xff0c;引爆舆论&#xf…

生产环境部署与协同开发 Git

目录 一、前言——Git概述 1.1 Git是什么 1.2 为什么要使用Git 什么是版本控制系统 1.3 Git和SVN对比 SVN集中式 Git分布式 1.4 Git工作流程 四个工作区域 工作流程 1.5 Git下载安装 1.6 环境配置 设置用户信息 查看配置信息 二、git基础 2.1 本地初始化仓库 ​编辑…

Java 中数据结构LinkedList的用法

LinkList 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按线性的顺序存储数据&#xff0c;而是在每一个节点里存到下一个节点的地址。 链表可分为单向链表和双向链表。 一个单向链表包含两个值: 当前节点…

创新指南|CEO如何应对生成式AI带来的4大颠覆创新机遇

生成式AI是一种快速发展的颠覆式创新&#xff0c;可以帮助企业创新商业模式、提高效率和解锁商业价值。本研究介绍如何应对生成式AI技术带来的挑战和机遇&#xff0c;以及如何先发利用这种技术来超越竞争和组织创造力和效率。如果您想了解更多关于生成式AI的企业创新战略&#…

【C++深入浅出】初识C++下篇(auto关键字、范围for、nullptr指针)

目录 一. 前言 二. auto关键字 2.1 auto的引入 2.2 auto简介 2.3 auto的使用细则 2.4 auto不能推导的场景 三. 基于范围的for循环(C11) 3.1 范围for的语法 3.2 范围for的原理 3.3 范围for的使用条件 四. 指针空值nullptr(C11) 一. 前言 上期我们介绍了c新增的两个重…

网络基础知识socket编程

目录 网络通信概述网络互连模型&#xff1a;OSI 七层模型TCP/IP 四层/五层模型数据的封装与拆封 IP 地址IP 地址的编址方式IP 地址的分类特殊的IP 地址如何判断2 个IP 地址是否在同一个网段内 TCP/IP 协议TCP 协议TCP 协议的特性TCP 报文格式建立TCP 连接&#xff1a;三次握手关…

服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写的参考笔记

2023/8/29 19:21:11 服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写 2023/8/29 19:22:25 在服务器端使用Django WebSocket和客户端使用Uniapp的情况下&#xff0c;以下是代码示例来实现服务器端和客户端之间的群组互发消息。 …

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯&#xff08;包括后端实现心跳检测&#xff09; 前言一、Web Socket 简绍1 为什么用 websocket&#xff1f; 二、代码实现1、前端&#xff08;html&#xff09;1.1、无前端向后端发送消息1.2、有前端向后端发送消息 2、后端具体…

springboot整合jquery实现前后端数据交互

一 实施逻辑 1.1 前端 <!doctype html> <html lang"en"><head><meta charset"UTF-8"><meta name"Generator" content"EditPlus"><meta name"Author" content""><meta n…

C# 生成唯一ID

1.首先通过nuget安装yitter.idgenerator 下面的三行代码搞定

win11 docker-desktop安装记录

win11安装Docker踩坑实录 马上开始正式工作了&#xff0c;需要用到docker&#xff0c;以前在win10上安装过&#xff0c;新电脑是win11&#xff0c;心想肯定会遇到坑&#xff0c;就浅浅记录一下 首先看一下安装要求 需要wsl2 那么就先进行 wsl的更新 wsl --update注意这里网络…

【STM32】串口初步使用

本文只作为学习笔记&#xff0c;对串口进行一个简单的介绍&#xff0c;正确的使用方式还需要进行实际的调试 通信的类型&#xff1a; 同步 异步 单工 双工 串行 并行 STM32的串口通信&#xff1a; 配置片上外设的控制寄存器&#xff0c;通信双方进行相同的配置&#xff0c;…