Spring理解,重要概念及图解,2023秋招spring常见八股文

news2025/1/16 21:07:09

按照自己的需求,找到自己不会的地方去解决

1.Spring的核心

1)Spring的两大核心:IoC和AOP

Spring框架包含众多模块,如Core、Testing、Data Access、Web Servlet等,其中Core是整个Spring框架的核心模块。Core模块提供了IoC容器、AOP功能、数据绑定、类型转换等一系列的基础功能,而这些功能以及其他模块的功能都是建立在IoC和AOP之上的,所以IoC和AOP是Spring框架的核心。

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

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

AOP(Aspect Oriented Programing)是面向切面编程思想,这种思想是对OOP的补充,它可以在OOP的基础上进一步提高编程的效率。简单来说,它可以统一解决一批组件的共性需求(如权限检查、记录日志、事务管理等)。在AOP思想下,我们可以将解决共性需求的代码独立出来,然后通过配置的方式,声明这些代码在什么地方、什么时机调用。当满足调用条件时,AOP会将该业务代码织入到我们指定的位置,从而统一解决了问题,又不需要修改这一批组件的代码。

2)IOC容器:BeanFactory和ApplicationContext

1.两种工厂的创建方式:

2.两种工厂的关系(区别)

底层图解:

总结

3)DI依赖注入

依赖注入有三种常见的注入方式:构造函数注入、Setter方法注入和接口注入。下面分别展示这三种注入方式的代码体现。

  1. 构造函数注入:

public class MyApplication {
    private MessageService messageService;
​
    // 通过构造函数注入依赖
    public MyApplication(MessageService messageService) {
        this.messageService = messageService;
    }
​
    public void processMessage(String message) {
        // 使用依赖对象
        messageService.sendMessage(message);
    }
}
  1. Setter方法注入:

public class MyApplication {
    private MessageService messageService;
​
    // 通过Setter方法注入依赖
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }
​
    public void processMessage(String message) {
        // 使用依赖对象
        messageService.sendMessage(message);
    }
}
  1. 接口注入:

public interface MessageServiceInjector {
    MyApplication getApplication();
}
​
public class EmailServiceInjector implements MessageServiceInjector {
    public MyApplication getApplication() {
        // 创建依赖对象
        MessageService messageService = new EmailService();
​
        // 创建应用程序并注入依赖
        MyApplication application = new MyApplication(messageService);
​
        return application;
    }
}

在接口注入中,我们定义了一个MessageServiceInjector接口,它包含一个getApplication方法,用于获取MyApplication对象。然后,我们创建了一个EmailServiceInjector类,实现了MessageServiceInjector接口,并在getApplication方法中创建了依赖对象messageService,并将其注入到MyApplication对象中。

通过以上三种方式,我们可以将依赖对象注入到目标类中,实现依赖的解耦和灵活替换。具体选择哪种注入方式,取决于具体的需求和设计。

2.AOP和动态代理关系

动态代理于AOP基本逻辑关系:

OOP编程的垂直性造成代码冗余,不方便管理;

解决代码冗余这类问题的思维是AOP面向切面编程思想;

实现这一思想,就要用动态代理技术;代理技术直接使用很麻烦,所以不会直接用,而是使用spring Aop技术框架来解决该类问题,aop框架底层就用到动态代理技术。

通过AOP例子理解AOP

下面是一个简单的Java AOP代码示例:

  1. 定义一个切面类,实现切面逻辑:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
​
@Aspect
@Component
public class LoggingAspect {
​
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeAdvice() {
        System.out.println("Before executing the method");
    }
}
  1. 创建一个服务类,该类中的方法将被切面所拦截:

import org.springframework.stereotype.Service;
​
@Service
public class UserService {
​
    public void addUser(String username) {
        System.out.println("Adding user: " + username);
    }
}
  1. 创建一个配置类,启用AOP并扫描切面和服务类:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
​
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.example")
public class AppConfig {
​
}
  1. 创建一个主类,加载配置类并获取服务类的实例:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
​
public class MainApp {
​
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
​
        userService.addUser("John");
​
        context.close();
    }
}

在上述示例中,切面类 LoggingAspect 使用 @Aspect 注解标记为切面,并使用 @Before 注解定义了一个前置通知,该通知会在执行 com.example.service 包下的任何方法之前执行。服务类 UserService 中的 addUser 方法会被切面所拦截,在方法执行之前会打印一条日志。配置类 AppConfig 使用 @EnableAspectJAutoProxy 注解启用了AOP,并通过 @ComponentScan 注解扫描了切面和服务类。主类 MainApp 加载配置类,并获取服务类的实例,然后调用 addUser 方法。

运行主类 MainApp,将会输出以下内容:

Before executing the method
Adding user: John

这表明切面逻辑在方法执行之前被调用,成功拦截了服务类的方法。

3.spring中bean的安全问题

补充:成员方法才存在线程安全问题

  • spring中的bean如果是无状态的(一般情况是),则是线程安全的;

  • spring中的bean如果是有状态的,则需要标注@Scope("prototype"),意思是允许多个实例

    相反的@Scope("singleton"),意思是IOC容器中只允许创建一个实例

4.事务(来保证操作的原子性)

补充:事务是数据库中的概念,但spring对事务进行了拓展

  • 在Spring框架中,一般需要在以下情况下使用事务

  1. 数据库操作:当需要进行数据库的增删改操作时,可以使用事务来确保操作的一致性和完整性。例如,插入用户信息和同时插入用户订单信息,这两个操作应该放在同一个事务中,要么都成功,要么都失败。

  2. 多个服务方法调用:当一个服务方法中调用了多个其他服务方法,并且这些方法需要保证一致性,可以使用事务来统一管理。例如,用户下单操作需要调用库存服务和支付服务,这些服务操作应该在同一个事务中。

  3. 并发操作:当多个并发请求需要修改同一份数据时,需要使用事务来保证数据的一致性。例如,多个用户同时对同一商品进行抢购,需要使用事务来控制商品库存的减少和订单的生成。

  4. 异常处理:当方法执行过程中发生异常,需要回滚之前的操作,可以使用事务来实现回滚。例如,用户购买商品时,如果支付过程中发生异常,需要回滚订单和库存的操作。

总之,一般需要在涉及到数据库操作、多个服务方法调用、并发操作和异常处理的场景下使用事务。事务可以确保操作的一致性和完整性,提供可靠的数据访问和更新机制。

  • 步骤

    1. 开启事务:在执行一组操作之前,通过调用数据库的事务管理器来开启一个事务。

    2. 执行操作:在事务中执行一组相关的操作,如插入、更新、删除等。

    3. 提交事务:如果所有操作都成功执行,通过调用事务管理器的提交方法来提交事务,将操作的结果永久保存到数据库中。

    4. 回滚事务:如果有任何操作失败或发生异常,通过调用事务管理器的回滚方法来回滚事务,撤销已经执行的操作,保持数据库的一致性。

  • .spring支持编程式事务声明式事务是实现事务管理的两种主要方式。(重点)**

    1. 编程式事务:编程式事务是通过编写代码来管理事务的方式。在编程式事务中,开发人员需要手动编写事务的开启、提交和回滚等逻辑。通常,编程式事务使用的是底层的事务管理API,如JDBC的事务管理API。以下是一个使用编程式事务的示例:

    Connection conn = null;
    try {
        conn = dataSource.getConnection();
        conn.setAutoCommit(false); // 开启事务
        // 执行数据库操作
        // ...
        conn.commit(); // 提交事务
    } catch (SQLException e) {
        if (conn != null) {
            try {
                conn.rollback(); // 回滚事务
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        e.printStackTrace();
    } finally {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    1. 声明式事务:声明式事务是通过配置的方式来管理事务的方式。在声明式事务中,开发人员只需要在配置文件或注解中声明事务的属性,框架会自动根据配置来管理事务。常见的使用声明式事务的框架有Spring的事务管理机制。以下是一个使用声明式事务的示例:

    @Transactional
    public void doTransaction() {
        // 执行数据库操作
        // ...
    }

    在上述示例中,使用了@Transactional注解来声明事务,并将事务逻辑封装在doTransaction方法中。框架会根据注解的配置来管理事务的开启、提交和回滚等操作。

    总的来说,编程式事务需要手动编写事务管理的代码,灵活性较高,但工作量较大;而声明式事务通过配置的方式来管理事务,简化了开发人员的工作,但灵活性相对较低。选择使用哪种方式取决于具体的需求和项目的特点。

5.Spring事务失效的场景(都是代码执行出现异常,事务却没有回滚)

  • 异常捕获处理,自己处理了异常,没有抛出,解决:手动抛出

  • 抛出检查异常,配置rollbackFor属性为Exception

  • 非public方法导致的事务失效,改为public

详细解释:

第一种:异常捕获处理,自己处理了异常,没有抛出,解决:手动抛出(左图改成右图)

                    事务失效的情况                                                                  改正后

第二种:抛出检查异常,配置rollbackFor属性为Exception

第三种:public方法导致的事务失效,改为public

6.spring中bean的生命周期

7.三级缓存 (具体解决流程看视频解析)

可以解决spring中注入引起循环依赖问题

构造方法中的循环依赖问题需要配合@Lazy懒加载注解解决

8.spring中的常用注解

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

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

相关文章

进程的挂起状态

进程的挂起状态详解 当我们谈论操作系统和进程管理时,我们经常听到进程的各种状态,如“就绪”、“运行”和“阻塞”。但其中一个不那么常被提及,但同样重要的状态是“挂起”状态。本文将深入探讨挂起状态,以及为什么和在何时进程…

linux中安装nodejs,卸载nodejs,更新nodejs,git,linux中安装nginx并配置

文章目录 node的安装与卸载(更新版本)卸载nodejs安装新版本node git安装与拉取代码安装解决 linux git 每次推拉(push/pull)代码都要输入用户名密码的问题 nginx 安装、配置和卸载安装nginx配置**.conf 文件内容 nginx 卸载 注意,我的是Ubunt…

【Linux】root和子用户都能执行的命令,sudo无法执行(已解决)

全流程帖子 https://ask.oceanbase.com/t/topic/35604437/7 1.问题 如题,在编译miniob的时候遇到如下错误 [muvm-cnt8:~/code/miniob]$ sudo bash build.sh init build.sh init HEAD is now at 5df3037d Merge branch release-2.1.12-stable-pull into patches-2.…

一文搞定全进程间通讯(IPC)八大方式-管道、命名管道、信号、信号量、消息队列、共享内存+内存映射、套接字

进程间通讯(IPC) 参考 / 引用: 如何在Linux下的进行多进程编程(初步) - 知乎 (zhihu.com)。浅析进程间通信的几种方式(含实例源码) - 知乎 (zhihu.com)。 linux基础——linux进程间通信&#…

从零开始,使用C语言实现扫雷小游戏

扫雷 1. 前言2. 准备工作3. 设计思路4. 定义数组5. 初始化6. 打印7. 布置雷8. 排查雷9. 完整代码 1. 前言 大家好,我是努力学习游泳的鱼。今天我们会用C语言实现一个经典的windows小游戏:扫雷。扫雷是一款单机小游戏,我上中学时特喜欢在电脑…

网易24届内推

【网易】2024届网易互联网秋季校园招聘内推开始啦!给你分享我的专属内推邀请函:https://bole.campus.163.com/campus/home?projectId55&type99&isShare1&boleId7b842acc7c2b42db&boleType2&signatured5f2a3dc23bed70777a8be1a14b49…

简单了解IPv4编址

目录 一、IPv4地址 二、进制转换 三、有类IPv4 四、无类IPv4 3.1 子网掩码 3.2 地址规划 3.3 VLSM可变长子网掩码 五、私有IPv4地址 六、IPv4报文格式 七、IP地址解析 一、IPv4地址 IPv4地址由“网络位主机位”构成,所谓的网络位就是我们通常所指的网段区…

python 列表extend方法和+(拼接)的区别

1.extend方法会直接作用于原始列表,会修改原始列表的值 a [10, 20, 30] b [1, 2, 3]print(a b) print(a) a.extend(b) print(a) 2.extend接收到的参数是一个可迭代的对象(iterable),不管是list,tuple,str,dict,set a [10, 20, 30] b {"name&qu…

公司内部网段多管控乱,该如何规范跨网文件传输交换?

古往今来,高筑墙一直是有效的防御措施。从边塞长城到护城河外的高高城墙,都是利用隔离地域的形式实现保护安全域的效果。这样一来,城内的安全域可以在遇到危险时受到有效保护。 在企业网络安全防护方面,网络安全域隔离也是网络安全…

3D点云处理:圆柱侧面点云展开为平面 凹凸缺陷检测(附源码)

文章目录 1. 基本内容展开部分推导2. 展开流程3. 代码实现4. 应用文章目录:3D视觉个人学习目录微信:dhlddxB站: Non-Stop_目标:对采集的圆柱面点云展开为平面;应用:可用于检测圆柱侧面的凹凸缺陷;1. 基本内容 圆柱的侧面展开原理是将一个圆柱体(或柱体)的侧面展开成一个…

el-table实现纯前端导出(适用于el-table任意表格)

2023.9.1今天我学习了如何使用el-table实现前端的导出功能,该方法的好处有无论你的el-table长什么样子,导出之后就是什么样子。 1.安装三个插件 npm install file-save npm install xlsx npm install xlx-style 2.创建Export2Excel.js // 根据dom导出表…

Windows右键添加用 IDEA 打开

1.安装IDEA时 安装时会有个选项来添加,如下: 勾选即可 2.修改注册表 安装时未勾选,可以把下面代码中程序路径改为自己的,保存为对应的 idea.reg文件,双击即可 Windows Registry Editor Version 5.00[HKEY_CLASSES…

问题记录:jenkins添加节点时Launch method没有Launch agents via SSH选项

jenkins问题记录 在jenkins主页,左侧点击Manage Jenkins,找到plugins选项,搜索如下插件安装: 安装完插件后,即可看到ssh选项出来了

2023开学礼《乡村振兴战略下传统村落文化旅游设计》西学图灵许少辉八一新书

2023开学礼《乡村振兴战略下传统村落文化旅游设计》西学图灵许少辉八一新书

Linux工具

一、yum yum可以看作一个客户端(应用商店)、应用程序,它如何知道去哪里下载软件? yum也是一个指令/程序,可以找到它的安装路径。 在list中可以看到yum能安装的所有软件,通过管道找到想要的,yum …

ChatGPT 总结前端HTML, JS, Echarts都包含哪些内容

AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Excel 2021 实操,函数,图表,大屏可视化 案例实战 http://t.csdn.cn/zBytu

数据视觉化探秘:了解有效传达的几种常见图表

当涉及向观众传达复杂的数据时,数据可视化图表成为了无价的工具。本文为大家介绍几种常用的数据可视化图表,以便更好地展示和理解数据。 折线图 这是最基础的图表类型之一,通过连续的折线连接数据点,呈现数据随时间或顺序的变化…

极米投影仪好用吗?极米RS Pro 3的真实体验效果怎么样?

随着智能投影仪的不断普及,现在大多数的年轻家庭在布局客厅的时候也不再以传统的电视为主,投影仪代替电视已然成为了一种常态,投影仪的体积更小、不用固定安装、也不会占用太大的空间,并且可以随意投射出百寸以上的画面大小&#…

《论文阅读21》Equivariant Multi-View Networks

一、论文 研究领域:计算机视觉 | 多视角数据处理中实现等变性论文:Equivariant Multi-View Networks ICCV 2019 论文链接视频链接 二、论文简述 在计算机视觉中,模型在不同视角下对数据(例如,点云、图像等&#xff0…

XXE漏洞利用技巧(由简入深)-----portswigger(XXE部分WP)

什么是XXE XXE(XML External Entity:xml外部实体注入),它出现在使用XML解析器的应用程序中。XXE攻击利用了XML解析器的功能,允许应用程序从外部实体引用加载数据。攻击者可以通过构造恶意的XML实体引用来读取本地文件…