当前位置: 首页 > news >正文

SpringSecurity6 | 自动配置(下)

在这里插入图片描述
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Java从入门到精通
✨特色专栏: MySQL学习
🥭本文内容:SpringSecurity6 | 自动配置(下)
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: Leo知识库,欢迎大家访问

✨✨ 粉丝福利订阅✨✨

在这里插入图片描述
Leo哥收集了一些关于面试以及其他学习资源,这里分享给大家,各位卷王快收下吧!!!

目录

    • 1.前言
    • 2.问题引出
    • 3.再看自动装配
      • 3.1run方法到注解解读器
      • 3.2加载Bean
    • 6.参考文献
    • 7.总结

学习参考 :

  • 讲师:孙帅老师
  • 课程:孙哥说SpringSecurity6

image-20231030235443828

1.前言

大家好,我是Leo哥🫣🫣🫣,上一节我们揭开了为什么引入依赖之后就会进行登录鉴权这一神秘面纱,了解复习了关于SpringBoot的自动配置以及如何一步一步的通过自动配置让我们请求加上认证权限。本次我们接着讨论关于自动配置相关问题。好了,话不多说让我们开始吧😎😎😎。

2.问题引出

既然我们知道了有关SpringBoot自动装配的一些基本流程。具体的方法调用路径或者叫配置路径是这样的:首先是三个核心的注解:

@SpringBootApplication-> @EnableAutoConfiguration>@Import(AutoConfigurationImportSelector)

然后通过@Import注解去加载他的所有配置文件到SpringBoot中。这样加载到SpringSecurity的核心文件。最终调用到上边的方法,导致所有的方法都得进行登录认证。

那么这些个注解尤其是**@Import**是如何生效的呢,具体是怎么生效的呢,在什么时候被加载呢,其实上一篇文章我们已经有了一些简单的了解,这节课我们随着Leo哥的视角通过源码方式来深入学习一下。

3.再看自动装配

3.1run方法到注解解读器

我们找到我们项目的启动类。

image-20231117232122451

然后通过Ctrl + 鼠标左键,点进去run方法。

image-20231117232424261

我们查看这个里面的构造方法:

image-20231118123722315

然后我们找到run()方法

image-20231118124312944

image-20231118124041959

可以看到这个prepareContext这个方法。它接受6个参数,分别是bootstrapContextcontextenvironmentlistenersapplicationArguments和printedBanner,并对这些参数进行处理以准备上下文。

然后我们通过Ctrl + 鼠标左键,点到prepareContext这个里面去查看。

image-20231118124238053

那么他在这里做了什么准备工作呢,我们来简单分析一下:

它的功能是在Spring应用启动过程中准备并设置应用上下文(ApplicationContext)

  1. 设置环境并处理应用上下文:
    • context.setEnvironment(environment): 将配置环境设置到应用上下文中。
    • postProcessApplicationContext(context): 对应用上下文进行后处理,可能涉及一些自定义配置或修改。
    • addAotGeneratedInitializerIfNecessary(this.initializers): 如果需要,添加Ahead-of-Time (AOT) 生成的初始化器到应用的初始化器列表中。
    • applyInitializers(context): 应用之前添加的所有初始化器到应用上下文。
  2. 通知监听器上下文已准备好:
    • listeners.contextPrepared(context): 通知Spring应用运行监听器,上下文已准备完成。
    • bootstrapContext.close(context): 关闭引导上下文。
  3. 启动信息日志:
    • 如果启用了启动日志(this.logStartupInfo),则记录启动信息和配置文件信息。
  4. 注册Spring Boot特定的单例Bean:
    • 向Bean工厂注册springApplicationArgumentsspringBootBanner(如果存在的话)。
  5. 处理Bean工厂配置:
    • 设置允许循环引用(setAllowCircularReferences)和允许Bean定义覆盖(setAllowBeanDefinitionOverriding),根据配置决定。
  6. 懒加载和属性源排序处理:
    • 如果启用了懒加载(this.lazyInitialization),则添加相关的BeanFactoryPostProcessor。
    • 添加一个用于属性源排序的BeanFactoryPostProcessor。
  7. 加载应用的源:
    • 如果没有使用AOT生成的工件,那么将从getAllSources()获取所有源,并使用load(context, sources.toArray(new Object[0]))加载它们。
  8. 通知监听器上下文已加载:
    • listeners.contextLoaded(context): 通知监听器上下文加载完成。

主要作用: 识别入口类,读取入口类的所有内容包括注解在内。并注册到注解解读器announationreader中,方便后续注解进行解析。

通过getAllSources()获取所有源信息,也就是我们当前的入口类信息,然后把这些source放到一个set集合中,最后去加载load,接下来我们点开load方法继续查看。

image-20231118125037298

  1. 首先,它检查logger是否处于调试模式(debugEnabled)。如果处于调试模式,它会记录一条调试日志,显示正在加载的源(sources)。
  2. 然后,它创建一个BeanDefinitionLoader实例。这个实例是用于加载Bean定义的。它使用getBeanDefinitionRegistry(context)方法获取BeanDefinitionRegistry,然后使用createBeanDefinitionLoader()方法创建一个BeanDefinitionLoader实例。
  3. 如果beanNameGenerator属性不为null,它将beanNameGenerator设置为loader的属性。
  4. 如果resourceLoader属性不为null,它将resourceLoader设置为loader的属性。
  5. 如果environment属性不为null,它将environment设置为loader的属性。
  6. 最后,调用loader的load()方法来加载Bean定义。

到这里,前面的工作已经基本完成了:读取入口类中重要的信息,包括注解包括入口类本身。将入口类中的注解注册到注解解读器annotationreader当中。

3.2加载Bean

真正解析Bean的工作是从refreshContext当中进行的。

image-20231118125314882

首先通通过prepareContext方法进行准备,然后通过refreshContext进行装载工作,那么他具体是怎么进行转载的呢,下面我们点进去这个方法继续查看。

image-20231118125430218

这部分代码涉及应用上下文的刷新动作。这里我逐行解释一下:

注册关闭钩子(shutdown hook):

  • if (this.registerShutdownHook): 首先检查一个布尔标志this.registerShutdownHook,判断是否需要注册一个shutdown hook。这个标志通常是在Spring Boot的配置中设置的,用以确定我们是否希望在JVM关闭时能够自动清理和关闭Spring上下文。
  • shutdownHook.registerApplicationContext(context): 如果需要注册shutdown hook,这行代码执行注册操作。具体来说,shutdownHook是一个管理器(可能是Spring Boot中的一个组件),负责注册和执行关闭Spring应用上下文的逻辑。当JVM进程结束时,这个shutdown hook将得到执行。

最后跑到了一个applicationContext的refresh方法当中。

image-20231118125721796

刷新应用上下文:

refresh(context)

这是调用ApplicationContext的

refresh()

方法,该方法是启动和重新启动Spring上下文的核心方法。它会执行以下关键步骤:

  • 准备上下文环境(比如设置必要的属性源、验证必要的环境变量等)。
  • 实例化和初始化所有的Bean,包括Spring配置中声明的Bean以及注解声明的Bean。
  • 如果有的话,运行BeanFactory后处理器。
  • 触发任何实现ApplicationContextAware接口的Bean,让它们能够感知到自己所处的ApplicationContext。
  • 最后,发送上下文刷新事件,这将通知所有监听器上下文已经完全初始化和可用。

这个refreshContext方法的目的是确保SpringBoot应用中的ApplicationContext处于最新状态,具备服务请求的能力。这通常发生在应用启动时,或者需要重新加载上下文配置的任何时候。

接下来会进行Bean处理的13方法,其中一个比较关键的方法: invokeBeanFactoryPostProcessors

image-20231118125934988

我们点过去这个方法

image-20231118130018787

  1. invokeBeanFactoryPostProcessors 方法接收一个 ConfigurableListableBeanFactory 类型的参数 beanFactory

  2. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()) 这一行调用了 PostProcessorRegistrationDelegate 类的 invokeBeanFactoryPostProcessors 方法,传入了两个参数,即当前的 beanFactory 和获取的一些BeanFactory后处理器列表(通过 getBeanFactoryPostProcessors() 获取)。

  3. 接下来的注释提到了检测 LoadTimeWeaver 并准备进行织入(weaving)。具体地说,它通过以下条件进行检查:

    • NativeDetector.inNativeImage() 确保不在本机镜像环境下。
    • beanFactory.getTempClassLoader() == null 确保临时类加载器为空。
    • beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME) 确保BeanFactory中包含名为 LOAD_TIME_WEAVER_BEAN_NAME 的bean。
  4. 如果以上条件都满足,那么会执行以下两个操作:

    • beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)) 添加一个 LoadTimeWeaverAwareProcessor 的Bean后处理器。
    • beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())) 设置临时类加载器为 ContextTypeMatchClassLoader 类的实例,该实例使用当前的 beanFactory 的类加载器。

    总结:

    经常refresh()的层层调用2进到AbstractApplicationContext类中refresh0方法,该方法主要有13
    个步骤用于对bean对象进行解析加载,其中第5步invokeBeanFactoryPostProcessors()进行核心加
    载类上的**@Configurer**、@Bean@Import等注解。

6.参考文献

  • https://springdoc.cn/spring-security/servlet/architecture.html
  • http://springboot.fun/

7.总结

以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。

如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。

ToLeoJavaer公众号 (微信搜索程序员Leo)

相关文章:

SpringSecurity6 | 自动配置(下)

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏&#xf…...

6、传统CV之均值滤波

在前5节,从最基础的像素开始了介绍,并且着重介绍了像素局部性、RGB图片和YUV图片以及通道的概念。 其实写那么多,很多细节知识也不用都学会,只需要知道计算机在处理图片时,看到的都是一堆像素,而这一堆像素,都是以数据点的形式存放在计算机中的。 为了更好的展示图像和…...

快速搭建本地的chatgpt

快速搭建本地的chatgpt 参考:一篇文章教你使用Docker本地化部署Chatgpt(非api,速度非常快!!!)及裸连GPT的方式(告别镜像GPT)-CSDN博客 前提是linux下 已安装docker 命…...

分布式下多节点WebSocket消息收发

1、使用场景 2、疑问 第一次发送请求后,通过N1,W2,到达service2,建立websocket连接。 1、接下来发送的消息,通过Ngixn后和网关gateway后还能落在service2上面吗? 如果不能落在service2上,需要怎…...

LeetCode算法题解(动态规划)|LeetCode509. 斐波那契数、LeetCode70. 爬楼梯、LeetCode746. 使用最小花费爬楼梯

一、LeetCode509. 斐波那契数 题目链接:509. 斐波那契数 题目描述: 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是&#xff1a…...

【图像处理】:Otsu算法最大类间方差法(大津算法:附源码)

这里写自定义目录标题 数学原理算法评价参考链接 数学原理 以灰度图像为例,对于图像MN大小的矩阵,即图像中的像素,每一个值即为像素值,其中灰度图像像素值在(0~255)之间。 主要实现前景(即目标)和背景的分割: 主要公式…...

【uni-app】设置背景颜色相关

1. 全局页面背景色设置&#xff1a; 在App.vue的style样式表中设置 <style> page {background-color: #F0AD4E; } </style> 2. 顶部导航栏背景色设置&#xff1a; 在pages.json页面路由中&#xff0c;globalStyle设置 "globalStyle": {"navi…...

工厂模式-C++实现

工厂模式是一个创建型设计模式&#xff0c;即“对象创建模式”&#xff0c;通过这种模式可以绕开new&#xff0c;来避免对象创建过程中&#xff0c;也就是new的方法造成的紧耦合&#xff0c;从而支持对象创建的稳定。 工厂模式中引入了一个工厂类&#xff0c;该工厂负责根据客…...

安装应用与免安装应用差异对比

差异 安装的程序和免安装的应用程序之间有以下几个方面的差别&#xff1a; 安装过程&#xff1a;安装的程序需要通过一个安装程序或安装脚本进行安装。这个过程通常会将应用程序的文件和依赖项复制到指定的目录&#xff0c;并进行一些配置和注册操作。免安装的应用程序则不需要…...

FiscoBcos使用Go调用合约

环境&#xff1a; fisco2.8.0 go 1.17 go-sdk 1.0.0 solidity 0.4.25 前言 请提前启动好四个fisco节点。 请准备好一个属于此fisco节点的账户私钥【待会调用合约和部署合约会用到】 此文章将讲解 官方文档使用gosdk部署helloworld合约并调用其方法 合约开发样例 官网提示 G…...

自然语言处理(NLP)-spacy简介以及安装指南(语言库zh_core_web_sm)

spacy 简介 spacy 是 Python 自然语言处理软件包&#xff0c;可以对自然语言文本做词性分析、命名实体识别、依赖关系刻画&#xff0c;以及词嵌入向量的计算和可视化等。 1.安装 spacy 使用 “pip install spacy" 报错&#xff0c; 或者安装完 spacy&#xff0c;无法正…...

CTF-PWN-tips

文章目录 overflowscanfgetreadstrcpystrcat Find string in gdbgdbgdb peda Binary ServiceFind specific function offset in libc手工自动 Find /bin/sh or sh in library手动自动 Leak stack addressFork problem in gdbSecret of a mysterious section - .tlsPredictable …...

《Effective C++》条款21

必须返回对象时&#xff0c;别妄想返回其reference 如果你的运算符重载函数写成了返回reference的形式&#xff1a; class A { public:A(int a,int b):x(a),y(b){}friend const A& operator*(const A& a, const A& b); private:int x;int y; }; const A& opera…...

决策树,sql考题,30个经典sql题目

大数据&#xff1a; 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&#x…...

【ES6.0】- 扩展运算符(...)

【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

关于Java中的深拷贝与浅拷贝

Java中的深拷贝和浅拷贝是针对对象和数组等引用数据类型的复制操作。 浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a; 对于基本数据类型&#xff0c;浅拷贝直接复制其值。对于引用数据类型&#xff0c;浅拷贝只复制对原对象的引用&#xff0c;而不是复制对象本身。因…...

13.真刀实枪做项目---博客系统(页面设计)

文章目录 1.预期效果1.1博客列表页效果1.2博客详情页效果1.3博客登陆页效果1.4博客编辑页效果 2.实现博客列表页2.1实现导航栏2.2实现版心2.3实现个人信息2.4实现博客列表2.5博客列表页完整代码 3.实现博客正文页3.1引入导航栏3.2引入版心3.3引入个人信息3.4实现博客正文3.5博客…...

VScode 配置用户片段

文件->首选项->配置用户片段->新建全局用户片段 后续就可以通过vv3来直接生成下面的代码 {// Place your 全局 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // description. Add comma separated ids of the l…...

Fedora 项目近日发布了 Fedora Linux 39

导读几经推迟之后&#xff0c;Fedora 项目近日发布了 Fedora Linux 39&#xff0c;这是红帽公司赞助的面向大众的 GNU/Linux 发行版的最新稳定版本&#xff0c;采用了最新的技术和开源应用程序。 Fedora Linux 39 由 Linux 内核 6.5 支持&#xff0c;并提供了一些最新的桌面环境…...

Uniapp连接iBeacon设备——实现无线定位与互动体验(理论篇)

目录 前言&#xff1a; 一、什么是iBeacon技术 二、Uniapp连接iBeacon设备的准备工作 硬件设备&#xff1a; 三、Uniapp连接iBeacon设备的实现步骤 创建Uniapp项目&#xff1a; 四、Uniapp连接iBeacon设备的应用场景 室内导航&#xff1a; 五、Uniapp连接iBeacon设备的未来…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...