Java后端高频面经——Spring、SpringBoot、MyBatis
-
Spring定义一个Bean有哪些方法?依赖注入有哪些方法?
(1)定义Bean的方法
-
注解定义Bean,@Component
用于标记一个类作为Spring的bean。当一个类被@Component注解标记时,Spring会将其实例化为一个bean,并将其添加到Spring容器中。
-
配置文件定义Bean
(2)依赖注入的方法
- 字段(Field):最直接地在类的字段上使用。
public class MyClass {@Autowiredprivate MyDependency myDependency; }
- 构造器(Constructor):在构造器上使用,用于构造器注入。
public class MyClass {private MyDependency myDependency;@Autowiredpublic MyClass(MyDependency myDependency) {this.myDependency = myDependency;} }
- 方法(Method):也可以在一个方法上使用,通常是一个 setter 方法。
public class MyClass {private MyDependency myDependency;@Autowiredpublic void setMyDependency(MyDependency myDependency) {this.myDependency = myDependency;} }
-
-
介绍IOC、AOP、反射
(1)IOC
Spring IOC容器通过
①封装对象的创建(将对象的创建过程交给Spring管理,从而实现了控制反转)和生命周期管理(管理对象的初始化和销毁过程),
②使用依赖注入来解耦对象之间的依赖关系(通过 Spring 容器将类 A 所依赖的 B 的实例注入到 A 中,这样 A 和 B 不再直接依赖,而是通过容器来提供),
③利用反射和配置元数据动态地创建和管理对象(当 Spring 容器启动时,它会根据配置文件或注解(元数据)扫描类的信息,通过反射技术实例化对象,而不需要编写具体的
new
代码。反射让 Spring 能够动态地操作类的构造函数、方法等), ④同时提供作用域管理功能(对象的生命周期和可见性范围。Spring 提供了多种作用域,容器会根据作用域来管理对象的实例化、销毁等过程。Singleton(单例)、Prototype(原型)、Request、Session、Application 等作用域)。
(2)AOP
面向切面编程,AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装起来,以减少系统的重复代码,降低模块间的耦合度。
两个例子:权限校验拦截器、动态切换数据源。
Spring AOP的实现依赖于动态代理技术。动态代理是在运行时动态生成代理对象,而不是在编译时。
注解 @Aspect 用于定义切面,标注在切面类上。 @Pointcut 定义切点,标注在方法上,用于指定连接点。 @Before 在方法执行之前执行通知。 @After 在方法执行之后执行通知。 @Around 在方法执行前后都执行通知。 (3)反射
允许在运行时动态地查询和操作类、方法、字段等信息,并且能够通过反射来调用类中的方法或修改类的属性。反射机制的核心原理是:通过
Class
类来获取类的结构信息,并且使用这些信息在运行时动态地操作类的对象。IOC、DI、动态代理就是用到了反射。①获取class对象:可以通过类的
Class
对象来访问类的信息。Class<?> clazz = Class.forName("Person"); //括号里的内容可以是程序运行时才输入的内容
②查询类的结构信息:通过
Class
对象,可以获取类的构造方法、方法、字段、接口、父类等信息。Method[] methods = clazz.getMethods(); // 获取所有公共方法 Field[] fields = clazz.getFields(); // 获取所有公共字段 Constructor[] constructors = clazz.getConstructors(); // 获取所有公共构造函数
③动态创建对象
Constructor<?> constructor = clazz.getConstructor(); // 获取无参构造 Object instance = constructor.newInstance(); // 使用构造函数创建对象实例
④调用方法
Method method = clazz.getDeclaredMethod("myMethod", String.class); method.setAccessible(true); // 如果是私有方法,需要设置访问权限 method.invoke(obj, "parameter"); // 调用方法
-
介绍动态代理、静态代理?
代理模式是设计模式中的一种,它通过提供代理对象来控制对原对象的访问。代理对象充当中介,通常在请求实际操作之前或之后做一些额外的工作(例如检查权限、缓存结果、延迟加载等)。
控制访问:代理可以控制对实际对象的访问,增加额外的功能(如安全性、权限管理、日志记录等)。
延迟加载:通过代理,可以延迟初始化或执行耗时的操作,直到真正需要时才执行。
性能优化:代理对象可以缓存结果,减少重复计算或请求,提高性能。
增强功能:代理对象可以在不修改原对象代码的情况下,为其增加新的功能,如事务管理、日志记录等。
(1)动态代理
动态代理是在运行时创建代理对象,代理对象在运行时被动态地生成,因此不需要在编译时就确定代理类。Java 提供了两种方式来实现动态代理:
- JDK 动态代理
- 通过
java.lang.reflect.Proxy
类和InvocationHandler
接口动态生成代理类。JDK 动态代理要求目标类实现一个接口。
- 通过
- CGLIB(Code Generation Library)代理
- 通过字节码生成技术,动态创建目标类的子类来实现代理。CGLIB 代理不要求目标类实现接口,而是通过继承目标类来实现代理。
(2)静态代理
代理类是在编译时就已经写好并且确定的。是由开发者手动编写的,并且在程序运行之前就已经存在。例如,你在编写代码时就知道你需要一个
Proxy
类,它会代理RealSubject
类的方法。在静态代理中,代理类和目标类的关系是固定的,编译时就已经确定。 代理模式是JAVA的一种设计模式,而AOP是Spring框架中的一个特性,是使用了动态代理来实现的。
- JDK 动态代理
-
Spring的循环依赖的原因以及解决方法;(众安)
循环依赖指的是两个类中的属性相互依赖对方:例如 A 类中有 B 属性,B 类中有 A属性,从而形成了一个依赖闭环。
Spring中的循环依赖问题有三种情况:
- 第一种:通过构造方法进行依赖注入时产生的循环依赖问题。
- 第二种:通过setter方法进行依赖注入且是在多例(原型)模式下产生的循环依赖问题。
- 第三种:通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题。
单例模式适用于全局唯一的资源管理,如配置管理、日志记录、数据库连接池等。它的特点是保证类在全局范围内只有一个实例,所有地方都使用同一个对象。
多例模式适用于需要多个独立实例的场景,如用户会话、任务调度、订单管理等。每个实例有自己的状态和行为,不共享数据。
只有【第三种方式】的循环依赖问题被 Spring 解决了,其他两种方式在遇到循环依赖问题时,Spring都会产生异常。
(1)Spring实例化Bean:Spring尝试创建A的实例,发现A依赖B,因此需要实例化B。Spring在创建B时,发现B依赖A,但此时A还没有完成初始化,所以Spring会创建A的空对象并将其放入
singletonObjects
一级缓存中并开始创建B。(3)循环依赖暴露
- 当Spring尝试创建B时,由于A还没有完全初始化,Spring会把A实例(未完全初始化)提前暴露到
earlySingletonObjects
二级缓存中,这时A成为一个半初始化的Bean。 - B可以通过
earlySingletonObjects
二级缓存获得这个提前暴露的A对象,从而完成B的依赖注入。
(3)初始化Bean
-
依赖注入完成后,Spring继续初始化B(如调用
@PostConstruct
等),然后将B放入三级singletonFactories
缓存中,表示B已经完全初始化。 -
Spring继续完成A的初始化工作,注入B,完成生命周期的其他部分,并将A放入三级
singletonFactories
缓存中,表示A也已经完全初始化。
(4)总结
- 在依赖注入过程中,Spring通过
earlySingletonObjects
二级缓存提供了B对A的依赖,通过singletonFactories
三级缓存提供了A对B的依赖,从而打破了循环依赖。
-
列举几个Spring常用的注解?(美团)
注解 作用 @Autowired 自动装配bean,当Spring容器中存在与要注入的属性类型匹配的bean时,它会自动将bean注入到属性中 @Component Spring会将一个类实例化为一个bean,并将其添加到Spring容器中。 @Configuration 用于标记一个类作为Spring的配置类,配置类可以包含@Bean注解的方法,用于定义和配置bean,作为全局配置。 @Bean 用于标记一个方法作为Spring的bean工厂方法,当一个方法被@Bean注解标记时,Spring会将该方法的返回值作为一个bean,并将其添加到Spring容器中 @Service 用于标记服务层的bean,是@Component注解的特例,一般标记在业务service的实现类。 @Repository 用于标记数据访问层的bean,它也是@Component注解的特例。 @Controller 用于标记控制层的bean,它也是@Component注解的特例。 -
spring、springboot、SpringMVC的区别及关系?(康泰)
Spring 是一个全面的应用开发框架,提供了全面的基础设施和功能支持。
Spring MVC 是 Spring 框架中的一个模块,专门用于 Web 开发,采用 MVC 模式来处理 Web 请求和响应。它依赖于 Spring 框架的核心功能,如 IoC 和 AOP。
Spring Boot 是一个基于 Spring 的项目,它封装了 Spring 和其他相关技术(如 Spring MVC、Spring Data、Spring Security 等),提供自动配置、快速项目启动器、内嵌服务器三大功能,使开发者能够快速启动和构建 Spring 应用。
- 自动配置
- 快速项目启动器,通过引入不同的 Starter,可以快速集成常用的框架和库(如数据库、消息队列、Web 开发等),极大地提高了开发效率。
- 内嵌服务器(Tomcat、Jetty、Undertow),无需额外配置,即可将应用打包成可执行的 JAR 文件,方便部署和运行。
Spring+Spring MVC = Spring Boot
-
springboot的自动配置原理?(美团、得物)springBoot启动机制,启动之后做了哪些步骤?(B站)
-
SpringBoot重要注解
@SpringBootApplication 用于标注主应用程序类,标识一个Spring Boot应用程序的入口点,同时启用自动配置和组件扫描。 @Controller 标识控制器类,处理HTTP请求。 @RestController 结合@Controller和@ResponseBody,返回RESTful风格的数据。 @Service 标识服务类,通常用于标记业务逻辑层。 @Repository 标识数据访问组件,通常用于标记数据访问层。 @Component 通用的Spring组件注解,表示一个受Spring管理的组件。 @Autowired 用于自动装配Spring Bean。 @Value 用于注入配置属性值。 @RequestMapping 用于映射HTTP请求路径到Controller的处理方法。 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 简化@RequestMapping的GET、POST、PUT和DELETE请求。 @Configuration 用于指定一个类为配置类,其中定义的bean会被Spring容器管理。 -
怎么用原生的MyBatis去查询?
(1)配置MyBatis: 在配置文件中配置数据源、MyBatis的Mapper文件位置等信息。
(2)创建实体类:创建与数据库表对应的实体类,字段名和类型需与数据库表保持一致。
public class User {private Long id;private String username,private String email,// Getters and setters }
(3)编写SQL映射文件:在resources目录下创建XML文件,定义SQL语句和映射关系。
<mapper namespace="com.example.dao.UserMapper"><select id="selectUserById" resultType="com.example.model.User">SELECT * FROM users WHERE id = #{id}</select> </mapper>
(4)编写DAO接口:创建DAO接口,定义查询方法。
public interface UserMapper {User selectUserById(Long id); }
(5)编写具体的SQL查询语句:在XML文件中编写对应的SQL语句。
(6)调用查询方法:在服务层或控制层中调用DAO接口中的方法进行查询。
// 在Service层中调用 User user = userMapper.selectUserById(1);
-
MyBatis里的 # 和 $ 的区别?
-
Mybatis 在处理 #{}时,会创建预编译的 SQL 语句,将 SQL 中的 #{} 替换为?号,在执行 SQL 时会为预编译 SQL 中的占位符(?)赋值,调用 PreparedStatement 的 set 方法来赋值,预编译的 SQL 语句执行效率高,并且可以防止SQL注入,提供更高的安全性,适合传递参数值。
-
Mybatis 在处理 ${} 时,只是创建普通的 SQL语句,然后在执行 SQL语句时 MvBatis 将参数直接拼入到 SQL里,不能防止 SQL注入,因为参数直接拼接到 SQL语句中,如果参数未经过验证、过滤,可能会导致安全问题。
比如:
<select id="getUserByUsername" resultType="User">SELECT * FROM users WHERE username = '${username}' </select>
在这个查询中,
${username}
会直接被传入的username
值替换,假如传入的username
是恶意的,例如"' OR 1=1"
,查询语句就变成了:SELECT * FROM users WHERE username = '' OR 1=1
这就是典型的 SQL 注入,因为
$
直接拼接了参数值,导致不安全的 SQL 被执行。大多数情况下都应该使用
#
,特别是涉及到用户输入的值时。它可以安全地处理用户输入,避免 SQL 注入。只有在确实需要拼接动态 SQL 的结构部分(如表名、列名)时,才应该使用$
。
-
MybatisPlus和Mybatis的区别?(百度)
MybatisPlus是一个基于MyBatis的增强工具库。
- CRUD操作:MybatisPlus通过继承BaseMapper接口,提供了一系列内置的快捷方法,使得CRUD操作更加简单,无需编写重复的SQL语句。
- 代码生成器:MvbatisPlus提供了代码生成器功能,可以根据数据库表结构自动生成实体类、Mapper接口以及XML映射文件,减少了手动编写的工作量。
- 通用方法封装:MybatisPlus封装了许多常用的方法,如条件构造器、排序、分页查询等,简化了开发过程,提高了开发效率。
- 分页插件:MybatisPlus内置了分页插件,支持各种数据库的分页查询,开发者可以轻松实现分页功能,而在传统的MyBatis中,需要开发者自己手动实现分页逻辑。
- 多租户支持:MvbatisPlus提供了多租户的支持,可以轻松实现多租户数据隔离的功能。
- 注解支持:MvbatisPlus引入了更多的注解支持,使得开发者可以通过注解来配置实体与数据库表之间的映射关系,减少了XML配置文件的编写。
相关文章:

Java后端高频面经——Spring、SpringBoot、MyBatis
Spring定义一个Bean有哪些方法?依赖注入有哪些方法? (1)定义Bean的方法 注解定义Bean,Component 用于标记一个类作为Spring的bean。当一个类被Component注解标记时,Spring会将其实例化为一个bean࿰…...

扩散模型中三种加入条件的方式:Vanilla Guidance,Classifier Guidance 以及 Classifier-Free Guidance
扩散模型主要包括两个过程:前向扩散过程和反向去噪过程。前向过程逐渐给数据添加噪声,直到数据变成纯噪声;反向过程则是学习如何从噪声中逐步恢复出原始数据。在生成过程中,模型从一个随机噪声开始,通过多次迭代去噪&a…...

Banana Pi OpenWRT One Wifi6 OpenWrt社区官方开源路由器评测
第一款不可破解、开源、版权软件、符合 FCC、CE 和 RoHS 的维修权路由器 OpenWRT项目今年已经20岁了,为了纪念这一时刻,Banana Pi OpenWrt One/AP-24.XY路由器开发系统已经上市。这是OpenWRT团队与硬件公司的第一个联合项目。选择 Banana Pi,…...

9.1go结构体
Go不是完全面向对象的,没有类的概念,所以结构体应该承担了更多的责任。 结构体定义 使用 type 和 struct 关键字定义: type Person struct { Name string Age int } 字段可以是任意类型,包括其他结构体或指针。 字段名以大写…...

Manus全球首个通用Agent,Manus AI:Agent应用的ChatGPT时刻
文章目录 前言Manus AI: 全球首个通用AgentManus AI: 技术架构与创始人经历AI Agent的实现框架与启示AI Agent的发展预测行业风险提示 前言 这是一篇关于Manus AI及其在通用人工智能领域的应用和前景的报告,主要介绍了Manus AI的产品定位、功能、技术架构、创始人经…...

【SAP-PP】生产版本维护
一、基本概念 生产版本:用于定义一种产品,不同的生产方式,包含物料清单(BOM)和工艺路线的信息,给生产带来更多的灵活性。在做产品需求计划时和产品生产时(创建生产订单、生产订单下达前和生产订…...

软考 中级软件设计师 考点笔记总结 day01
文章目录 软考1.0上午考点下午考点 软考1.11、数值及其转换2、计算机内数据表示2.1、定点数 - 浮点数2.2、奇偶校验 和 循环冗余校验 (了解)2.3、海明码 (掌握)2.4、机器数 软考1.0 上午考点 软件工程基础知识: 开发模型、设计原则、测试方…...

K8s控制器Deployment详解
回顾 ReplicaSet 控制器,该控制器是用来维护集群中运行的 Pod 数量的,但是往往在实际操作的时候,我们反而不会去直接使用 RS,而是会使用更上层的控制器,比如说 Deployment。 Deployment 一个非常重要的功能就是实现了 Pod 的滚动…...

【微知】Centos如何迁移到Anolis系统的失败记录?(yum -y install centos2anolis、centos2anolis.py)
背景 本文记录如何从centos 8迁移到anolis系统。 详细步骤 下载迁移repo wget https://mirrors.openanolis.cn/anolis/migration/anolis-migration.repo -O /etc/yum.repos.d/anolis-migration.repo下载centos2anolis工具包 yum -y install centos2anolis安装额外工具包 …...

在 macOS 上使用 CLion 进行 Google Test 单元测试
介绍 Google Test(GTest)是 Google 开源的 C 单元测试框架,它提供了简单易用的断言、测试夹具(Fixtures)和测试运行机制,使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…...

Python SQLite3 保姆级教程:从零开始学数据库操作
Python SQLite3 保姆级教程:从零开始学数据库操作 本文适合纯新手!无需任何数据库基础,跟着步骤操作即可掌握 SQLite3 的核心用法。 目标:让你像用记事本一样轻松操作数据库! 目录 什么是 SQLite3?环境准…...

深度解析:视频软编码与硬编码的优劣对比
视频编码 一、基本原理与核心技术 压缩原理 通过时空冗余消除实现数据压缩: 空间冗余:利用帧内预测(如DC/角度预测)消除单帧内相邻像素相似性。时间冗余:运动估计与补偿技术(ME/MC)减少连续帧间…...

Azure云生态系统详解:核心服务、混合架构与云原生概念
核心服务:深入掌握Azure SQL Database、Azure Database for PostgreSQL、Azure Database for MySQL的架构、备份恢复、高可用性配置(如Geo-Replication、自动故障转移组、异地冗余备份)。混合架构:熟悉Azure Arc(管理混…...

人工智能之数学基础:正交矩阵
本文重点 正交矩阵是线性代数中一个重要的特殊矩阵,它在许多领域都有广泛的应用。 什么是正交矩阵 如图所示,当矩阵A满足如上所示的条件的时候,此时我们就可以认为是正交矩阵,需要注意一点矩阵A必为方阵。 正交矩阵的充要条件 …...

分布式锁—7.Curator的分布式锁
大纲 1.Curator的可重入锁的源码 2.Curator的非可重入锁的源码 3.Curator的可重入读写锁的源码 4.Curator的MultiLock源码 5.Curator的Semaphore源码 1.Curator的可重入锁的源码 (1)InterProcessMutex获取分布式锁 (2)InterProcessMutex的初始化 (3)InterProcessMutex.…...

【笔记】STM32L4系列使用RT-Thread Studio电源管理组件(PM框架)实现低功耗
硬件平台:STM32L431RCT6 RT-Thread版本:4.1.0 目录 一.新建工程 二.配置工程 编辑 三.移植pm驱动 四.配置cubeMX 五.修改驱动文件,干掉报错 六.增加用户低功耗逻辑 1.设置唤醒方式 2.设置睡眠时以及唤醒后动作 编辑 3.增加测试命…...

C++什么是深复制和浅复制,构造函数和析构函数,哪一个可以写成虚函数,为什么?
在C之中深复制是指对于值类型复制它的值,对于指针类型不仅仅复制指针指向的值,还会重新分配一个内存空间用于放置复制的值(对动态分配的内存进行重新分配和内存复制),这种深复制不会出现悬空指针的问题,但是…...

从连接到交互:SDN 架构下 OpenFlow 协议的流程与报文剖析
在SDN架构中,交换机与控制器之间的通信基于 OpenFlow协议,其设计目的是实现控制平面与数据平面的解耦。以下是 交换机连接控制器 和 数据包进入交换机触发交互 的详细流程及协议报文分析: 一、交换机连接控制器的流程(初始化阶段&…...

第七课:Python反爬攻防战:Headers/IP代理与验证码
在爬虫开发过程中,反爬虫机制成为了我们必须面对的挑战。本文将深入探讨Python爬虫中常见的反爬机制,并详细解析如何通过随机User-Agent生成、代理IP池搭建以及验证码识别来应对这些反爬策略。文章将包含完整的示例代码,帮助读者更好地理解和…...

Golang学习笔记_47——访问者模式
Golang学习笔记_44——命令模式 Golang学习笔记_45——备忘录模式 Golang学习笔记_46——状态模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 编译器实现2. 财务系统3. UI组件系统 四、Go语言实现示例完整实现代码执行结果 五、…...

软件高级架构师 - 软件工程
补充中 测试 测试类型 静态测试 动态测试 测试阶段 单元测试中,包含性能测试,如下: 集成测试中,包含以下: 维护 遗留系统处置 高水平低价值:采取集成 对于这类系统,采取 集成 的方式&…...

IDEA 基础配置: maven配置 | 服务窗口配置
文章目录 IDEA版本与MAVEN版本对应关系maven配置镜像源插件idea打开服务工具窗口IDEA中的一些常见问题及其解决方案IDEA版本与MAVEN版本对应关系 查找发布时间在IDEA版本之前的dea2021可以使用maven3.8以及以前的版本 比如我是idea2021.2.2 ,需要将 maven 退到 apache-maven-3.…...

Qt之QGraphicsView图像操作
QGraphicsView图像操作:旋转、放大、缩小、移动、图层切换 1 摘要 GraphicsView框架结构主要包含三个主要的类QGraphicsScene(场景)、QGraphicsView(视图)、QGraphicsItem(图元)。QGraphicsScene本身不可见,是一个存储图元的容器,必须通过与之相连的QGraphicsView视图来显…...

人工智能之数学基础:对线性代数中逆矩阵的思考?
本文重点 逆矩阵是线性代数中的一个重要概念,它在线性方程组、矩阵方程、动态系统、密码学、经济学和金融学以及计算机图形学等领域都有广泛的应用。通过了解逆矩阵的定义、性质、计算方法和应用,我们可以更好地理解和应用线性代数知识,解决各种实际问题。 关于逆矩阵的思…...

嵌入式开发之串行数据处理
前题 前面几篇文章写了关于嵌入式软件开发时,关于串行数据处理的一些相关内容,有兴趣的可以看看《嵌入式开发:软件架构、驱动开发与串行数据处理》、《嵌入式软件开发之生产关系模型》和《嵌入式开发之Modbus-RTU协议解析》相关的内容。从业十…...

机器学习(六)
一,决策树: 简介: 决策树是一种通过构建类似树状的结构(颠倒的树),从根节点开始逐步对数据进行划分,最终在叶子节点做出预测结果的模型。 结构组成: 根节点:初始的数据集…...

结合unittest和pytest进行虚拟数据库测试
使用 pytest 和 MagicMock 模拟数据库操作,并测试假设的 create_user 函数,将用户添加到数据库中。 代码实现 from datetime import date from typing import List, Optional from unittest.mock import MagicMock from pydantic import BaseModel, Fi…...

Spring Boot 监听器(Listeners)详细教程
Spring Boot 监听器(Listeners)详细教程 目录 Spring Boot 监听器概述监听器核心概念最佳使用场景实现步骤高级配置详细使用场景总结 1. Spring Boot 监听器概述 Spring Boot 监听器(Listeners)基于 Spring Framework 的事件机制…...

工具介绍《githack》以及Git 命令行
一、Githack 工具介绍 Githack 是一个用于检测和利用网站 .git 目录泄露漏洞的安全工具。当网站错误配置导致 .git 目录可公开访问时,攻击者可通过该工具下载 .git 中的版本控制文件,并重建完整的项目源代码。 核心用途 检测 .git 目录泄露漏洞。从泄…...

【hello git】git rebase、git merge、git stash、git cherry-pick
目录 一、git merge:保留了原有分支的提交结构 二、git rebase:提交分支更加整洁 三、git stash 四、git cherry-pick 共同点:将 一个分支的提交 合并到 到另一个上分支上去 一、git merge:保留了原有分支的提交结构 现有一个模型…...