【框架源码】Spring源码核心注解Conditional和应用

news2025/1/30 16:21:27

1.什么是@Conditional注解

  • @Conditional来源于spring-context包下的一个注解。
  • 通过@Conditional配置一些条件判断,当所有条件都满足时,被该@Conditional注解标注的目标才会被Spring处理。
  • 例如根据当前环境、系统属性、配置文件等条件来决定是否注册某个Bean或执行某个组件。

  • 应用场景

    • 在某个特定的环境下,需要注册一个特定的Bean,常用的是当bean不存在的时候才注册。
    • 根据配置文件中的某个属性来决定是否注册Bean。
    • 根据环境选择配置类,比如当前系统的操作系统类型、版本等条件来决定是否要执行。

2.@Conditional注解源码解析

  • 通过他的注解内部可以发现,他就是一个纯功能性注解,他并没有依赖于其他注解,类上只有三个元注解。
@Target({ElementType.TYPE, ElementType.METHOD})  //注解作用范围在接口、类、枚举、注解、方法
@Retention(RetentionPolicy.RUNTIME) //保留到运行期,jvm加载class文件之后,仍然存在
@Documented  //生成javadoc文档
public @interface Conditional {

  /**
   * All {@link Condition} classes that must {@linkplain Condition#matches match}
   * in order for the component to be registered.
   */
  Class<? extends Condition>[] value();
}
  • value:Condition类型的数组,Condition是一个接口,表示一个条件判断,内部有个方法返回true或false
  • 当所有Condition条件都成立,@Conditional的结果才成立

疑问:那这个Condition又是个啥?

  • Condition本身是个接口,源码中matches方法判断条件是否匹配,方法中有两个参数:

    • context 上下文,获取容器中的bean的信息

    • metadata:获取被@Conditional标注的对象上的所有注解信息

    public interface Condition {
      //判断条件是否匹配
      boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    }
    
  • 我们再来看看ConditionContext的源码

public interface ConditionContext {

  //返回bean定义注册器,用于获取Bean定义的注册表,可以用来注册和获取bean定义的各种配置信息
  BeanDefinitionRegistry getRegistry();

  //用于获取Bean工厂,可以用来获取或操作Bean实例,相当于一个ioc容器对象
  ConfigurableListableBeanFactory getBeanFactory();

  //用于获取环境变量和属性值等配置信息
  Environment getEnvironment();

  //用于获取资源文件,比如XML文件、图片、文本等
  ResourceLoader getResourceLoader();

 //用于获取类加载器,可以用来加载类或资源文件
  ClassLoader getClassLoader();

}
  • 这里面主要的是BeanDefinitionRegistry ,返回bean定义注册器,用于获取Bean定义的注册表,也是我们一会要用到的。

  • BeanDefinitionRegistry 源码

public interface BeanDefinitionRegistry extends AliasRegistry {

	//用于向Bean定义注册表中注册一个Bean定义,参数beanName表示Bean的名称,beanDefinition表示Bean的定义信息
  void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);

	//从Bean定义注册表中移除指定名称的Bean定义,参数beanName表示要移除的Bean名称
  void removeBeanDefinition(String beanName) ;

	//获取指定名称的Bean定义,参数beanName表示要获取的Bean名称
  BeanDefinition getBeanDefinition(String beanName) ;

	//判断指定名称的Bean定义是否存在于注册表中,参数beanName表示要判断的Bean名称 
  boolean containsBeanDefinition(String beanName);

	//获取所有Bean定义的名称,返回一个String数组
  String[] getBeanDefinitionNames();

	//获取Bean定义的数量。
  int getBeanDefinitionCount();

	//判断指定名称的Bean是否已经被使用,参数beanName表示要判断的Bean名称。如果该名称已经被使用,则返回true,否则返回false
  boolean isBeanNameInUse(String beanName);

}
  • BeanDefinition简介
    • BeanDefinition是Spring容器中最重要的概念之一,他是容器创建和管理Bean实例的基础,对Bean的定义信息的抽象和封装
    • 描述一个Bean的定义信息,包括Bean的名称、类型、作用域、属性等信息
    • 可以对Bean的创建和管理进行详细的配置和控制,例如可以指定Bean的作用域、是否懒加载、是否自动注入等属性。
  • BeanDefinition的用途
    • 定义Bean的基本信息,包括Bean的名称、类型、作用域等。
    • 定义Bean的属性信息,包括Bean的属性名称、类型、值等。
    • 定义Bean的生命周期信息,包括Bean的初始化方法、销毁方法等。
    • 定义Bean等依赖关系,包括Bean之间的依赖关系、注入方式等。
    • 定义Bean等AOP信息,包括切面、通知、切点等。

3.@Conditional注解案例实战

  • 需求背景:现在系统有两套数据源,模拟篮球远动员,一个正式的,一个替补的,只有当正式的不能上场时,替补的才会上场。

  • 编码实战

    创建篮球运动员实体Bean

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class BasketballPlayers {
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private int age;
    
        /**
         * 性别
         */
        private String sex;
    
    }
    

    创建Bean的配置类

    public class BasketballPlayersConfig {
    
        @Bean("lixiang")
        public BasketballPlayers BasketballPlayers1(){
            return new BasketballPlayers("李祥",18,"男");
        }
        @Bean("zhangsan")
        public BasketballPlayers BasketballPlayers2(){
            return new BasketballPlayers("张三",18,"男");
        }
    
    }
    

    自定义Condition类

    public class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            BeanDefinitionRegistry registry = conditionContext.getRegistry();
            //不存在,才返回true
            boolean flag = !registry.containsBeanDefinition("lixiang");
            return flag;
        }
    }
    

    在这里插入图片描述

    测试代码

    public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            //扫描指定的包,包括子包
            context.scan("com.lixiang");
            //里面完成初始化操作,核心方法
            context.refresh();
            Map<String, BasketballPlayers> beansOfType = context.getBeansOfType(BasketballPlayers.class);
            System.out.println(beansOfType);
        }
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

股票量价关系基础知识3

成交量变化的表现形式 成交量变化的表现形式主要有以下几种 一、缩量 一般界定当日成交量低于前一交易日成交量10%以上为缩量。 缩量往往发生在上升途中的回调末期、上涨末期以及股价下跌的中后期。一般下跌趋势中的缩量阶段&#xff0c;往往意味着股价仍未见底&#xff0c;不能…

服务攻防-中间件安全CVE复现IISApacheTomcatNginx漏洞复现

目录 一、导图 二、ISS漏洞 中间件介绍> 1、短文件 2、文件解析 3、HTTP.SYS 4、cve-2017-7269 三、Nignx漏洞 中间件介绍> 1、后缀解析漏洞 2、cve-2013-4547 3、cve-2021-23017 无 EXP 4、cve-2017-7529 意义不大 四、Apache漏洞 中间件介绍> 1、漏…

AcWing算法提高课-1.3.5买书

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 小明手里有n元钱全部用来买书&#xff0c;书的价格为10元&#xff0c;20元&#xff0c;50元&#xff0c;100元。 问小明有多少种买…

【Python--读写模式全解】

读写模式 读写模式语法读取写入追加 小结 读写模式 open() 函数常用形式是接收两个参数&#xff1a;文件名(file)和模式(mode)。 # 读写文件最好用 with...open...操作&#xff0c;这样最安全 # 而且还不需要关闭文件 with open(path,r)as f:f.read() # 一次读取整个文件&…

如何调用API数据接口来获取想要的数据

API&#xff08;Application Programming Interface&#xff09;是连接不同软件和服务的桥梁&#xff0c;允许不同的应用程序之间共享和交换数据。API接口被广泛应用于各种场景&#xff0c;如&#xff1a; 1.移动应用程序&#xff1a;许多移动应用程序使用API接口与服务器通信…

量子计算——新兴领域的前沿技术

随着人类社会文明的不断进步&#xff0c;计算技术也在不断发展。传统计算机在过去的几十年中快速发展&#xff0c;计算速度、存储能力等方面发生了天翻地覆的变化。但随着大数据、人工智能、区块链等新兴领域的迅速崛起&#xff0c;传统计算机的发展似乎面临了瓶颈。在这样的背…

花3个月面过京东测试岗,拿个25K不过分吧?

背景介绍 计算机专业&#xff0c;代码能力一般&#xff0c;之前有过两段实习以及一个学校项目经历。第一份实习是大二暑期在深圳的一家互联网公司做前端开发&#xff0c;第二份实习由于大三暑假回国的时间比较短&#xff08;小于两个月&#xff09;&#xff0c;于是找的实习是在…

java简单接触

文章目录 常用的DOS命名计算机语言的发展史javajava的历史java的版本java的特性和优势JDK、JRE、JVMjava程序的运行机制 常用的DOS命名 # 盘符切换 C:\Users\Administrator>D: D:\> # 查看当前目录下的所有文件 dir # 切换目录 cd change screen # 返回上一级目录 cd ..…

FE_本地存储LocalStorage和SessionStorage

localStorage和sessionStorage一样都是用来存储客户端临时信息的对象。他们均只能存储字符串类型的对象。localStorage生命周期是永久&#xff0c;这意味着除非用户主动在浏览器上清除localStorage信息&#xff0c;否则这些信息将永远存在。sessionStorage的失效时间为当前会话…

Wine运行器3.2.2——修复一些问题

不写太多啥了&#xff0c;详细介绍看这里就行&#xff1a;https://bbs.deepin.org/post/248098 更新内容 ※1. 修改源地址&#xff08;迁出 Gitlink&#xff09;&#xff1b; ※2. 修复非 X86 架构运行器主页面虚拟机工具禁用的问题&#xff1b; 3、部分组件支持选择最优源。 …

C语言——数据类型

1. 变量 1.1变量的概念 变量就是在程序中可以发生变化的量&#xff0c;变量有类型。 变量的类型决定了变量存储占用的空间&#xff0c;以及如何解释存储的位模式。(1字节8位) 1.2定义格式 存储类型 数据类型 变量名&#xff1b;例如&#xff1a;(auto) int a; 变量名是标识…

Unity2d光源的使用

将项目升级为2dURP 安卓UPR插件 新建URP配置文件 (只有完成第一步操作之后才会有创建的选项) 右键>Create>Rendering>URP Asset (with 2D Renderer) 修改Project Settings(项目设置里面的相关设置) Edit>Project Settings>Graphics>设置Scriptable R…

组件弹框传值

1.引入组件 // 编辑干部弹窗 import edit from "../../components/rm/edit.vue"; 2.注册组件 components: {edit,}, 3.使用组件 <edit ref"edit" :visible.sync"editVisible" :rmid"UpFileData.id" :width"editWidth"…

股票量价关系基础知识4

价量配合与价量背离 在股票市场中&#xff0c;价的变化会引起量的变化&#xff0c;量的变化又会引起价的波动。从整体来看&#xff0c;价量关系主要存在两种情况&#xff1a;价量配合和价量背离。 一、价量配合 &#xff08;一&#xff09;基本概念 价量配合&#xff0c;是指股…

leecode255——二叉树的所有路径代码及示例

&#x1f50e;递归法&#xff1a; 既然是递归法&#xff0c;递归三部曲&#xff1a; &#xff08;1&#xff09;确定终止条件: 对二叉树的路径&#xff0c;遍历到叶子节点结束。本题要找到叶子节点才开始处理后续流程&#xff0c;那什么时候算是找到了叶子节点&#xff0c;即…

尚硅谷JUC

文章目录 1. 什么是JUC1.1 JUC简介1.2 进程和线程基本概念2.1 Synchronized2.1.1 Synchronized关键字2.1.2 synchronized实现三个线程卖30张票 2.2 Lock2.2.1 什么是Lock2.2.2 使用Lock实现买票功能2.2.3 两者的区别 3. 线程间通信及定制化通信3.1 使用synchronized实现线程之间…

【Windows线程开发】Windows线程同步技术

我们在上一章节中讲解了关于Windows的线程基础&#xff0c;相信大家已经对线程有了基本的概念。这一章节中&#xff0c;我们来讲讲线程同步技术&#xff0c;包括加锁技术&#xff08;原子锁和互斥体&#xff09;和事件&#xff0c;信号灯。 文章目录 一.原子锁二.互斥体三.事件…

SpringCloud-网关 Gateway

网关Gateway 一、网关初识二、网关的使用1.创建项目并引入依赖2.编写网关配置3.启动服务并测试 三.查看网关路由规则列表四.路由服务的负载均衡五.断言和过滤1.断言Predicate1.1.The Path Route Predicate Factory(路径断言工厂&#xff09;1.2.The After Route Predicate Fact…

【27】linux进阶——rpm软件包的管理

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

基于SSM+MySQL的支教管理系统

目录 1、系统介绍 2、系统功能展示 3、运行环境 4、运行效果 5、运行配置 6、下载地址 1、系统介绍 本系统是基于SSM(SpringSpringMVCMyBatis)框架开发的支教管理系统&#xff0c;系统共有超级管理员&#xff0c;系统管理员&#xff0c;支教学校&#xff0c;志愿者这四大…