当前位置: 首页 > 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设备的未来…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...