你能不能手敲出Spring框架?

Spring最成功的地方在于创始人Rod Johnson提出的IOC、AOP核心理念,反而不是其本身的技术。技术上今天可以有Spring春天,明天就可以有Autumn秋天。

核心理念有多重要?就如1871年巴黎公社的失败。公社在对抗法国zf和普鲁士占领军的背景下成立,最初成功掌握了巴黎。然而,没有清晰的行动纲领和核心指导,加上对外部威胁的应对不足,公社最终被镇压,存在时间不足可怜的三个月。

在这里插入图片描述

本文收录在我开源的《Java学习面试指南》中,一份覆盖Java程序员所需掌握的Java核心知识、面试重点。希望收到大家的 ⭐ Star ⭐支持。GitHub地址:https://github.com/hdgaadd/JavaGetOffer,相信你看了一定不会后悔。

文章目录

    • 1. Spring IOC和AOP
      • 1.1 Spring IOC
      • 1.2 Spring AOP
      • 1.3 AOP的原理
      • 1.4 JDK和CGCLIB动态代理
    • 2. Spring循环依赖
      • 2.1. 解决Spring循环依赖

1. Spring IOC和AOP

1.1 Spring IOC

面试官:你说下对Spring IOC的理解?

Spring IOC其实是一种通过描述来创建和获取对象的技术,相比于最原始的通过new来创建对象,所有的对象都交由Spring IOC进行管理,我们管这些对象称为Spring Bean。

Spring Bean可以看成是班级里的学生,那IOC容器就是容纳学生的班级。每个Bean的分类、不同的生命周期,包括Prototype、Singleton、Request、Session、Global session都可以在IOC容器里进行管理。这其实是一种控制反转的思想,我们程序员把控制对象的权限都交由了靠谱的Spring IOC容器。

通过XML方式我们可以向Spring IOC描述我需要一个A对象。当Spring启动时这个Bean也就自动注入到IOC容器等待我们的使用。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bean1" class="org.springframework.beans.factory.ConcurrentBeanFactoryBenchmark$ConcurrentBean"scope="prototype"><property name="date" value="2004/08/08"/></bean></beans>

现在商业公司通过以上XML的方式已经是很少见了,Spring Boot提供了另一种通过注解来描述Bean的方式。Spring Boot底层基于注解的IOC容器是AnnotationConfigApplicationContext,这个留到我后续的文章再来讲解。

// 通过注解的方式来创建Bean
@Configuration
public class TokenConfig {/*** 设置token的类型**/@Beanpublic TokenStore tokenStore() {return new JwtTokenStore(jwtAccessTokenConverter()); // 设置token类型为JWT}
}

1.2 Spring AOP

面试官:AOP呢?

在整个软件编程的历史长河中,最先面世的一种编程范式叫做面向过程编程。但随着软件系统越来越复杂,面向过程编程越来越难以管理软件的复杂性。于是面向对象编程OOP诞生,它致力于解决困扰前者的软件复杂性问题。

但面向对象编程并不是银弹,它存在一些弊端,例如我们需要为整个项目的所有对象都引入一个公共行为:打印对象每个方法的执行耗时。如果采用OOP需要把公共行为的代码都重复贴到每个对象的类里。。。

现在救世主来了,AOP面向切面编程弥补了OOP的缺陷。

通过Spring AOP,我们可以为每个对象约定一套流程,为对象方法执行前执行后织入一些行为。如果是日志的话,在对象方法执行后触发就可以了。

Spring AOP提供了多个注解,我们来看看。

  1. @Before。前置通知,在方法执行之前执行。
  2. @After。后置通知,在方法执行之后执行。
  3. @AfterReturning。返回通知,方法不抛出异常,正常退出方法时执行。
  4. @AfterThrowing。异常通知,方法抛出异常后执行 。
  5. @Around。环绕通知,围绕着方法执行,可以自定义在方向执行前、执行后执行一段逻辑,自由度更高
  6. @Pointcut。切点。定义了要拦截的对象。
// 防重复提交的切面
@Aspect
@Component
public class SubmitAspect {@Pointcut("@annotation(banRepeatSubmit)")public void pointCut(BanRepeatSubmit banRepeatSubmit) {}@Around("pointCut(banRepeatSubmit)")public Object around(ProceedingJoinPoint proceedingJoinPoint, BanRepeatSubmit banRepeatSubmit) throws Throwable {// 防止对象方法重复执行}
}

1.3 AOP的原理

面试官:那AOP的原理是什么?

在使用上文的六种注解时,这些注解是封装在一个由@AspectJ注解修饰的类,我们管这个类叫做切面

Spring AOP扫描到@Pointcut定义的切点时,就会自动为该Bean创建一个代理。而Spring Boot目前底层的代理模式有两种:JDK动态代理、CGLIB动态代理。

如果被代理的对象实现了接口,则Spring会使用JDK动态代理;如果被代理对象没有实现接口,则Spring会使用CGLIB动态代理。原因是JDK动态代理要求被代理对象必须实现至少一个接口。

JDK动态代理通过生成代理对象的字节码文件,使要拦截的方法跳转到invoke()方法,而在invoke()里就是在切面里定义的各种拦截逻辑。

而CGLIB是通过生成代理类的子类实现,同时修改字节码文件让子类方法覆盖代理类的方法,从而实现对拦截方法的代理。

另外Spring AOP还集成了AspectJ,一种编译织入的方式来代理对象。

1.4 JDK和CGCLIB动态代理

面试官:JDK和CGCLIB动态代理哪个更快?

两者的生命周期可以分为创建对象阶段、实际运行阶段,我们要根据具体情况具体分析。

  1. 实际运行阶段,CGLIB性能比JDK运行性能更高
  2. 创建对象阶段,基于两者的原理,CGLIB花费在创建对象的时间要比JDK多。JDK只需创建代理类的字节码,CGLIB既要修改源代码的字节码文件,又要生成代理类的子类的字节码文件。

综上所述,对于需要创建大量对象的场景,JD动态代理K比CGLIB动态代理效率更高,反之CGLIB效率更高。

2. Spring循环依赖

2.1. 解决Spring循环依赖

面试官:知道怎么解决Spring循环依赖吗?

谈到循环依赖,大多数人都是望而生畏。一旦发生了循环依赖,说明了这部分软件设计的职责划分出现了问题,而且要修复起来不是一件容易的事。如果是屎山代码,那可就头大了。。。

如下例子,对象A的成员变量引用了对象B,而对象B的成员变量引用了对象A。也就是说,对象A的初始化完成要先完成对象B的初始化,但对象B的初始化完成又要先完成对象A的初始化,形成了一个永远无法实现的环。

    class A {B b = new B();}class B {A a = new A();}

Spring设计出了三个级别的缓存。一级缓存存放实例化、初始化的bean、二级缓存存放已实例化但没有初始化的bean、三级缓存存放创建bean的工厂对象

例如现在有对象A依赖对象B,对象B依赖对象A。

Spring首先从三级缓存获得实例化的A、B;接着让A进入二级缓存,同时将未初始化的B注入A,这就得到了实例化、初始化的A,此时A就会进入一级缓存;最后一步,只需要再把初始化的A注入到B,此时循环依赖解决。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

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

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

相关文章

英伟达开源 3400 亿巨兽:98% 合成数据训出最强开源通用模型,性能对标 GPT-4o

NVIDIA 最近开源了其大型语言模型 Nemotron-4 340B&#xff0c;这是一个具有划时代意义的模型&#xff0c;它使用了高达 98% 的合成数据进行训练&#xff0c;并且在性能上与 GPT-4 相当。Nemotron-4 340B 包括基础模型、指令模型和奖励模型&#xff0c;支持 4K 上下文窗口、50 …

回答网友的一个Delphi问题

网友想在grid 中 加一个水印&#xff0c;俺就给他写了个例子。先靠效果&#xff1a; 这个例子 包含下面几步&#xff1a; 1、创建背景 dg_bmp:Tbitmap.Create; w: Image1.Picture.Bitmap.width; h: Image1.Picture.Bitmap.height; dg_bmp.width: w*2; dg_bmp.height: …

从入门到高手的99个python案例(2)

51. 列表和数组比较 - 列表通用&#xff0c;NumPy数组高效。 import numpy as np normal_list [1, 2, 3] np_array np.array([1, 2, 3]) print(np_array.shape) # 输出 (3,), 数组有形状信息 52. Python的内置模块datetime - 处理日期和时间。 from datetime import…

数据库MySQL——从0到1入门教程

Q:为什么需要MySQL&#xff1f; A:网络服务中&#xff0c;我们需要存储、管理大量的数据&#xff0c;并确保数据的安全、实现增删改查操作的高效&#xff0c;因此需要一个系统用来专门管理数据&#xff0c;以实现上述的高性能要求&#xff0c;数据库管理系统应需而生 八股如下…

自动化数据驱动?最全接口自动化测试yaml数据驱动实战

前言 我们在做自动化测试的时候&#xff0c;通常会把配置信息和测试数据存储到特定的文件中&#xff0c;以实现数据和脚本的分离&#xff0c;从而提高代码的易读性和可维护性&#xff0c;便于后期优化。 而配置文件的形式更是多种多样&#xff0c;比如&#xff1a;ini、yaml、…

pdf structuredClone is not defined 解决

问题 部分手机系统的浏览器 pdf v2版本会出现 structuredclone is not defined 的报错&#xff0c;这是因为浏览器过低 解决 查看structuredClone的浏览器兼容性 structuredClone api 文档 polyfill 网站下方有个 polyfill的网址入口 可以解决低版本的兼容问题 相应网址…

笨蛋学算法之LeetCodeHot100_3_最长连续序列(Java)

package com.lsy.leetcodehot100;import java.util.Arrays; import java.util.HashSet; import java.util.Set;public class _Hot3_最长连续序列 {public static int longestConsecutive(int[] nums) {//创建set去重//对重复的数字进行去重Set<Integer> set new HashSet…

融合心血管系统(CVS)多视角信号的新架构新策略

随着深度学习的发展和传感器的广泛采用&#xff0c;自动多视角融合&#xff08;MVF&#xff09;在心血管系统&#xff08;CVS&#xff09;信号处理方面取得了进展。然而&#xff0c;普遍的MVF模型架构通常将同一时间步骤但不同视角的CVS信号混合成统一的表示形式&#xff0c;忽…

redis的四种模式部署应用

这里写目录标题 redis应用redis单机部署redis主从redis哨兵Cluster模式 redis应用 redis单机部署 关闭防火墙[rootzyq ~]#: yum -y install wget make gcc gcc-c ...... [rootzyq ~]#: wget https://download.redis.io/redis-stable.tar.gz --2024-01-01 19:41:14-- https:/…

TypeScript 进阶,深入理解并运用索引访问类型提升代码质量

欢迎回来继续我们的“TypeScript进阶技巧”系列。上次我们深入探讨了如何使用Extract和Exclude实用类型来优化TypeScript的类型处理&#xff08; 《如何利用 TypeScript 的 Extract 提升类型定义与代码清晰度》和 《如何利用 TypeScript 的 Exclude 提升状态管理与代码健壮性》…

论文阅读笔记:Cross-Image Relational Knowledge Distillation for Semantic Segmentation

论文阅读笔记&#xff1a;Cross-Image Relational Knowledge Distillation for Semantic Segmentation 1 背景2 创新点3 方法4 模块4.1 预备知识4.2 跨图像关系知识蒸馏4.3 Memory-based像素到像素蒸馏4.4 Memory-based像素到区域蒸馏4.5 整体框架 5 效果 论文&#xff1a;http…

Redis和Docker

Redis 和 Docker 是两种不同的技术&#xff0c;它们各自解决不同的问题&#xff0c;但有时会一起使用以提供更高效和灵活的解决方案。 Redis 是一个开源的内存数据结构存储系统&#xff0c;可以用作数据库、缓存和消息代理。它设计为解决MySQL等关系型数据库在处理大量读写访问…

MySQL数据操作与查询-T5 MySQL函数

一、数学函数和控制流函数 1、数学函数 &#xff08;1&#xff09;abs(x) 计算x的绝对值。 1 select abs(‐5.5),abs(10) &#xff08;2&#xff09;pow(x,y) 计算x的y次方的值。 1 select pow(2,8),pow(8,2) &#xff08;3&#xff09;round(x) 和 round(x,y) 对数字x进…

php遇到的问题

1、 underfined at line 3 in xxx.php , 错误提示&#xff0c;注释这行代码 // error_reporting(DEBUG ? E_ALL : 0); 目录&#xff1a;config/config.php

Ubuntu20.04部署Qwen2.openvino流程

下载代码 里面包含依赖 git clone https://github.com/OpenVINO-dev-contest/Qwen2.openvino.gitpython环境配置 创建虚拟环境 conda create -name qwen2openvino python3.10 conda activate qwen2openvino安装依赖 pip install wheel setuptools pip install -r requirem…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(二)

第三节 GB/T19001-2016 标准正文 本节为ISO9001:2015 标准条款的正文内容&#xff0c;各条款中的术语参照上节内容理解时&#xff0c;会很轻松。本节不再一一对各条款讲解。 引 言 0.1 总 则 采用质量管理体系是组织的一项战略决策&#xff0c;能够帮助其提高整体绩效…

这个网站有点意思,可做SPRINGBOOT的启动图

在 SpringBoot 项目的 resources 目录下新建一个 banner.txt 文本文件&#xff0c;然后将启动 Banner 粘贴到此文本文件中&#xff0c;启动项目&#xff0c;即可在控制台展示对应的内容信息。 下面这个工具很好用&#xff0c;收藏精哦

PFA 反应罐内衬特氟龙 润滑绝缘行业加工 匠心工艺

PFA反应罐别名也叫反应瓶&#xff0c;储样罐&#xff0c;清洗罐等。可作为样品前处理实验中消解样品和中低压溶样的反应容器&#xff0c;广泛应用于半导体分析、新材料、新能源、同位素分析等。 PFA反应罐规格参考&#xff1a;250ml、300ml、350ml、500ml、1L等。 产品特点&…

官网首屏:太漂亮了,真是着了它的魔,上了它的道。

大气的企业官网致力于提供用户友好的界面和优质的用户体验。网页经过精心设计和开发&#xff0c;旨在展示客户的品牌形象和产品信息&#xff0c;并为用户提供便捷的服务和沟通渠道。 官网设计追求简洁、美观、易用的原则&#xff0c;以吸引用户的注意力并提供清晰的导航和信息…

手机丢失不惊慌,华为手机已升级至楼层级设备查找!

出门总是丢三落四&#xff0c;手机丢了怎么办&#xff1f;不要怕&#xff0c;只要你的华为手机升级至云空间新版本&#xff0c;就可以进行楼层级设备查找&#xff0c;现在可以查看到具体的楼层了&#xff01; 之前有手机丢失过的朋友&#xff0c;肯定有相似的经历&#xff0c…