SpringBoot条件注解底层原理

一、简介

相信大家在学springBoot自动装配的时候会遇到下面这些条件注解,当存在其指定的条件,才会把对应的bean注入到IOC容器中。本博客旨在揭开其神秘的面纱!
在这里插入图片描述
其实说白了,springBoot的这些注解只是针对普通spring框架中@Condition注解的扩展,使其功能更加强大罢了!下面我们以分析@ConditionalOnClass为例子,简单介绍一下它的实现原理。

二、源码分析

2.1@ConditionalOnClass的上方标注了@Condition注解,我们只需要看其配置的条件类即可!

在这里插入图片描述

2.2通过uml类图可以看到其继承了Condition接口

在这里插入图片描述
在父类的SpringBootCondition中实现了核心的matches方法,其中圈出来的部分是个抽象方法,需要子类自己单独实现,这样我们接着看OnClassCondition#getMatchOutcome就行了!
在这里插入图片描述

2.3接着分析getMatchOutcome

首先我们可以看到OnClassCondition的这个方法的getMatchOutcome,会处理@ConditionalOnClass、@ConditionalOnMissingClass这两个注解!我们看第一个大if代码块就行!
图中的圈出来的代码就很有意思,底层通过classloader尝试去加载注解配置的类,如果加载异常就说明这个类不存在,于是就放进onMissingClasses中!
后续逻辑也很清晰明了,有缺损的class那么自然不符合注入条件,那么会返回match=false的ConditionOutcome!

在这里插入图片描述

2.4回到父类SpringBootCondition中的matches方法

很显然如果第三步存在缺损的class(onMissingClasses列表不为空),那么就会返回false,告诉spring容器不要注入这个bean
在这里插入图片描述

三、普通的Spring怎么处理Condition注解的

二中我们只分析到了SpringBoot中的源码,看到matches方法返回为false,至于为什么这个方法返回为false就不注入这个bean的逻辑还的看普通的spring源码,咱们怀着探索精神也去了解一下:

3.1Spring在启动的时候会自带一个叫ConfigurationClassPostProcessor的BeanFactory后置处理器

具体调用的时机是在refresh方法中的invokeBeanFactoryPostProcessors,具体源码我就不带大家追了,直接看ConfigurationClassPostProcessor#processConfigBeanDefinitions这个方法吧,再这个方法中我们也只需要关心他是怎么处理配置类的,也就是我圈出来的部分!
在这里插入图片描述

3.2上图圈出来的部分最后会调用到ConfigurationClassParser#processConfigurationClass

其方法的第一行就是处理@Condition注解的逻辑
在这里插入图片描述

3.3接着我们直接看shouldSkip方法

如果shouldSkip返回为true那么就不放进configurationClasses这个map中后续也不会加载其BeanDefinition,也就不会把这个Bean放入IOC容器中!可以在shouldSkip中看到调用了Condition的matches方法。matches方法返回为false也就是不满足Condition的条件,shouldSkip才会返回true!
在这里插入图片描述

四、其他条件注解的简单介绍

  • 4.1@ConditionalOnBean:底层会通过BeanFactory来尝试获取条件bean是否存在
  • 4.2@ConditionalOnProperty:底层会通过Environment获取properties文件中配置的属性的值
  • 4.3@ConditionOnJava:这个注解是用java版本来当充当判断条件的,里面比较有意思的是如何获取当前项目的java版本,针对老版本的springboot是通过是否存在某个类来判断的,新版本的springboot是通过存在某个类和类方法来进行判断的
  • 4.4@ConditionalOnWebApplication:底层是通过是否存在GenericWebApplicationContext这个类以及其作用域有session这个作用域等其他条件来判断出是servlet应用,如果有reactive.HandlerResult这个类加上其他条件来判断是否是Reactive的web应用。

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

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

相关文章

「图像 merge」无中生有制造数据

在进行一个新项目的时候,往往缺少一些真实数据,导致没办法进行模型训练,这时候就需要算法工程师自行制作一些数据了,比如这篇文章分享的 bag 目标检测,在检测区域没有真实的 bag数据 此时,就可以采用图像拼…

自学SLAM(6)相机与图像实践:OpenCV处理图像与图像拼接(点云)

前言 如果写过SLAM14讲第一次的作业,或者看过我之前的运行ORB_SLAM2教程应该都安装过OpenCV了,如果没有安装,没关系,可以看我之前的博客,里面有如何安装OpenCV。 链接: 运行ORB-SLAM2(含OpenCV的安装&…

【蓝桥每日一题]-倍增(保姆级教程 篇1)

今天讲一下倍增 目录 题目:忠诚 思路: 题目:国旗计划 思路: 查询迭代类倍增: 本质是一个一个选区间使总长度达到 M,类似凑一个数。而我们会经常用不大于它最大的二的次幂,减去之后,再重复这…

代码随想录算法训练营第23期day41|01背包问题、01背包问题——滚动数组、416. 分割等和子集

目录 一、01背包理论基础 1.二维dp数组01背包 1)确定dp数组以及下标的含义 2)确定递推公式 3)dp数组如何初始化 4)确定遍历顺序 5)举例推导dp数组 2.一维dp数组(滚动数组) 1&#xf…

解决Ts中的error.stack报错property ‘stack‘ does not exist on type ‘unknown typescript

我用的Ts版本是5.x,所以在使用的时候出现了这个问题 解决方式: 将error先转一遍就好了 参考链接: 你真的会处理TS中的Error么 - 掘金 (juejin.cn) Announcing TypeScript 4.4 - TypeScript (microsoft.com)

Canoe UDS诊断技术

Canoe UDS诊断 汽车诊断技术概述诊断术语OBD诊断CAN诊断协议诊断周期UDS诊断服务Diagnostic Request和Response诊断服务介绍 诊断文件CDD介绍诊断安全访问服务(security Access)介绍 如何在Canoe UDS诊断实战CANoe 开启诊断功能Canoe 诊断实战 汽车诊断技术概述 汽车诊断技术是…

尚硅谷大数据项目《在线教育之实时数仓》笔记005

视频地址:尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P031 P032 P033 P034 P035 P036 P037 P038 P039 P040 第9章 数仓开发之DWD层 P031 DWD层设计要点: (1)DWD层的设计依…

ajax-axios发送 get请求 或者 发送post请求带有请求体参数

/* axios v0.21.1 | (c) 2020 by Matt Zabriskie */ !function(e,t){"object"typeof exports&&"object"typeof module?module.exportst():"function"typeof define&&define.amd?define([],t):"object"typeof export…

单链表经典算法

移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 思路:(1)创建三个结构体指针,分别代表一条新链表的头newhead,…

面试10000次依然会问的【ReentrantLock】,你还不会?

引言 在并发编程的世界中,ReentrantLock扮演着至关重要的角色。它是一个实现了重入特性的互斥锁,提供了比synchronized关键字更加灵活的锁定机制。ReentrantLock属于java.util.concurrent.locks包,是Java并发API的一部分。 与传统的synchro…

隐私保护多领域推荐的紧密度共聚类联邦概率偏好分布模型

论文链接 Federated Probabilistic Preference Distribution Modelling with Compactness Co-Clustering for Privacy-Preserving Multi-Domain Recommendation 引言 这篇论文提出的概率偏好分布是通过使用高斯分布来表示用户和项目的偏好。在论文中,作者提出了一…

10.MySQL事务(上)

个人主页:Lei宝啊 愿所有美好如期而遇 目录 前言: 是什么? 为什么? 怎么做? 前言: 本篇文章将会说明什么是事务,为什么会出现事务?事务是怎么做的? 是什么? 我…

Nginx反向代理和负载均衡

文章目录 前言一、Nginx介绍二、Nginx的作用1.正向代理2.反向代理3.负载均衡之轮询4.负载均衡之加权轮询 三、Nginx安装1.Nginx下载2.启动Nginx3.检查Nginx是否启动成功4.配置监听5.关闭nginx 前言 比如公司项目刚刚上线的时候,并发量小,用户使用的少&a…

ElementuiPlus的table组件实现行拖动与列拖动

借助了插件sortablejs。这种方法只适合做非树状table。如果想实现树状table&#xff0c;并且可拖动。可以试一下aggridVue3这个插件 <template><div class"draggable" style"padding: 20px"><el-table row-key"id" :data"t…

计算机组成与结构-计算机体系结构

计算机体系结构 指令系统 Flynn分类法 SISD&#xff08;单指令流单数据流&#xff09; 结构 控制部分&#xff1a;一个处理器&#xff1a;一个主存模块&#xff1a;一个 代表 单处理器系统 SIMD&#xff08;单指令流多数据流&#xff09; 结构 控制部分&#xff1a;一个处理…

CleanMyMac2024破解版如何下载?

CleanMyMac作为一款专业的苹果电脑清理软件&#xff0c;它不仅仅能单纯的卸载不用、少用的应用&#xff0c;同时还支持&#xff1a;1、清理应用程序的数据文件&#xff0c;将应用重置回初始状态&#xff0c;减少空间占用&#xff1b;2、自动检查应用更新&#xff0c;保持应用的…

Python画图之动态爱心

Python画出动态爱心&#xff08;有趣小游戏&#xff09; 一、效果图二、Python代码 一、效果图 二、Python代码 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 480 # 画布的高 CANVAS_CENTER_X CANV…

【PID专题】MATLAB如何实现PID?

MATLAB是一种非常强大的工具&#xff0c;用于实现和分析PID&#xff08;比例-积分-微分&#xff09;控制器。在MATLAB中&#xff0c;您可以使用控制系统工具箱来设计、模拟和调整PID控制系统。 以下是一般步骤&#xff0c;演示如何在MATLAB中实现PID控制&#xff1a; 1. 打开MA…

PHP进销存ERP系统源码

PHP进销存ERP系统源码 系统介绍&#xff1a; 扫描入库库存预警仓库管理商品管理供应商管理。 1、电脑端手机端&#xff0c;手机实时共享&#xff0c;手机端一目了然。 2、多商户Saas营销版 无限开商户&#xff0c;用户前端自行注册&#xff0c;后台管理员审核开通 3、管理…

【服务器】Java连接redis及使用Java操作redis、使用场景

一、Java连接redis-No-SQL 1、导入依赖 在你的项目里面导入redis的pom依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version> </dependency> 2、连接redis 连接redis //…