SpringBoot作为当今开发的主流框架,作为一名java开发是不可能的不了解的,这个东西是典型的用起来很简单,但是了解到原理之后就会不自觉地感叹,真TMNB!

本文主要讲解其自动装配的原理,以及我们日常中怎么去用到这块的内容。

一、Conditional注解

        首先我们先建立一个Student对象,里面没有任何属性

public class Student {
}

然后我们建立一个命题:

如果项目中导入了fastjson,则会将Student放入IOC当中,如果没有,则不加载。

@SpringBootApplication
public class SpringbootConditionApplication {public static void main(String[] args) {SpringApplication.run(SpringbootConditionApplication.class, args);}}

如上图所示, 这是springboot的启动类(引导类),在这里我们先简单讲一下SpringApplication的run方法

可以看到run方法是有返回值的,对象为ConfigurableApplicationContext,是一个配置上下文对象,spring中的IOC就是一个上下文对象,于是我们可以看到通过这个上下文对象可以获得我们的环境以及IOC当中的Bean。

于是我们可以将代码这样写

@SpringBootApplication
public class SpringbootConditionApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);// 获取名为student的beanObject student = context.getBean("student");System.out.println(student);}}

这时候,我们再编写一个StudentConfig的类对student进行配置,如下

@Configuration
public class StudentConfig {@Beanpublic Student student(){return new Student();}
}

这时候我们启动项目,可以看到项目直接启动成功

但这并没有满足我们的要求,就是在项目中有导入了fastjson才会将student加载的要求,这时候就要用到Condition注解 。Conditional作用就是当你注册bean时,可以对这个bean添加一定的自定义条件,当满足这个条件时,注册这个bean,否则不注册

我们来看下Conditional的代码

这个注解里只定义了一个Class类型的数组,这没什么,重点在于泛型要求为Condition

然后我们看下Condition的这个接口

这个接口只定义了一个方法名为matches,返回值为一个boolean,这个时候我们不难猜出,当Conditional注解中的值为true则会执行标注的方法,这里我们再写一个类实现Condition接口 ,可以看到默认的返回值是为 false,然后我们再对它稍加改造

public class ClassOnCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 定义一个布尔值boolean flag;try {// 通过反射找到fastjson的类Class<?> aClass = Class.forName("com.alibaba.fastjson.JSON");// 找到了则返回trueflag = true;} catch (ClassNotFoundException e) {// 找不到则返回falseflag = false;}return flag; }
}

最后别忘了在StudentConfig中指定我们刚刚编写的类

@Configuration
public class StudentConfig {@Bean@Conditional(ClassOnCondition.class)public Student student(){return new Student();}
}

然后我们把项目中的依赖注释掉

启动项目,果不其然报错了,显示找不到student这个bean

这个时候肯定有机智的小朋友可能会提问了,这个路径写死了不就很耦合吗,这不搞个动态加载?

那这里呢,我们就可以定义一个注解,叫ConditionalOnClass,其中定义一个数组,因为设置的条件可以有多个

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassOnCondition.class)
public @interface ConditionalOnClass {String[] value();
}

这个时候,我们来把StudentConfig中的注解改成我们自定义的,并传入值

@Configuration
public class StudentConfig {@Bean
//    @Conditional(ClassOnCondition.class)@ConditionalOnClass("com.alibaba.fastjson.JSON")public Student student(){return new Student();}
}

最后呢,我们在把之前定义的ClassOnCondition进行修改,不过在修改之前,稍微讲一下这两个入参:

ConditionContext:这个对象是个上下文对象,可以用它获取环境,ioc以及类加载器

AnnotatedtypeMetadata:注解元对象,可以获得注解中传入的值

我们将代码修改成下图所示

public class ClassOnCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 定义一个布尔值boolean flag;try {// 通过注解名获取其中的值Map<String, Object> map = metadata.getAnnotationAttributes(ConditionalOnClass.class.getName());// 获取value的值String[] classNames = (String[]) map.get("value");for (String className : classNames) {Class<?> aClass = Class.forName(className);}flag = true;} catch (ClassNotFoundException e) {// 找不到则返回falseflag = false;}return flag;}
}

取消掉fastjson的依赖果然还是报错了

加入之后又成功获取了

二、springboot中对Conditional注解的运用

那面试的时候,面试官可能就会问spring中是怎么做到限制的

这个时候

本文实例的springboot版本为2.6.1,我们可以找到这个工程,spring-boot-autoconfigure

找到这个工程的condition文件夹,可以看到其中有 很多的相关的注解,

就比如:ConditionOnProperty:当配置文件中有相对应的键值对,则会执行相应方法

那这些都是springboot给我们定义好了的,我们可以直接使用,效果和我们刚刚自定义的是一样

然后我们以kafka作为例子举例,看看springboot是如何做的

找到这个类,我们来看其中的代码

当图中1的含义为项目中没有KafkaTemplate的字节码文件,则下面的2都不会执行

当1满足时,我们看2(含义为当IOC容器中没有KafkaTemplate时,则会执行标注的方法)

这就是SpringBoot当中对Conditional注解的用法,下一张我们会讲解如何切换springboot中的Enable注解。

SpringBoot--自动装配原理详解及应用之Conditional注解相关推荐

  1. springboot 整合redis_springboot自动装配原理详解

    1)传统ssm整合redis的时候 需要在xml的配置文件中 进行大量的配置Bean 我们在这里使用springboot来代替ssm的整合,只是通过xml的形式来整合redis 第一步:加入配置 &l ...

  2. Spring Boot自动装配原理详解

    目录 1.环境和依赖 1.1.spring boot版本 1.2.依赖管理 2.自动装配 2.1.流程概述 2.2.三大步前的准备工作 2.2.1.注解入口 2.2.2.获取所有配置类 2.3.获取过 ...

  3. 【理解springboot自动装配原理】

    理解springboot自动装配原理: 最近读了小马哥(mercyblitz)Springboot编程思想(核心篇),有了一些心得和感悟,分享给大家: 1. 官网介绍了激活自动装配的方法: * 文档提 ...

  4. SpringBoot自动装配原理浅析

    Springboot自动装配原理 SpringBoot是当下J2EE最为流行的框架,它有着轻量,快捷等特点,让程序员们可以专注在业务逻辑的编写上,而不用花太多的力气在一些环境的配置,整合组件的配置上面 ...

  5. 面试终极宝典:Springboot自动装配原理

    Springboot的自动装配过程,网上大多都是罗列代码,即使看完了,也还存在很多的疑点.下面,这是我总结的在面试过程中介绍SpringBoot自动装配原理的话术,拿来即用就可. Springboot ...

  6. 刨析 SpringBoot 自动装配原理,其实很简单

    J3 SpringBoot # 源码 # 自动装配 一日我在愉快得遨游时,看到有鱼友在问:SpringBoot 中引入了 Nacos 依赖为啥就可以直接使用 Nacos 中的相关功能呀! 认真思考了一 ...

  7. 淘宝(SpringBoot自动装配原理)

    什么是 SpringBoot 自动装配 通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能 SpringBoot 是如何实现自动装配的 SpringBoot 的核心注解 S ...

  8. 详解SpringBoot自动装配原理

    文章目录 一.从RedisAutoConfiguration源码分析自动装配 二.@EnableConfigurationProperties注解 三.@Import注解 3.1 类导入 3.2 Im ...

  9. SpringBoot自动装配原理解析——面试可以这样会回答

    1. 前言 SpringBoot是目前软件中最主流的框架,无论是工作还是面试基本都有它的身影,SpringBoot主要解决了传统spring的重量级xml配置Bean,实现了自动装配:所以,我们也常在 ...

最新文章

  1. 大学生学单片机怎么入门?
  2. 乌云爆告之双十一电商的安全警示
  3. 80%的人都混淆的BI和报表之不同
  4. 终于把单点登录完整流程图画明白了!史上最完整的CAS单点登录完整图解!
  5. 老BOJ 11 Counting
  6. 高精度倾斜摄影建模解决方案
  7. Python 的文件IO相关操作说明
  8. [HDU 2191] 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
  9. git remote 命令的用法
  10. hbase基础操作命令
  11. 0.Java介绍(Java语言特点,什么是JDK、JRE、JVM,Java开发注意事项和细节说明,Java转义字符)
  12. kdj买卖指标公式源码_KDJ买卖副图指标 源码 通达信 贴图
  13. 信息安全与密码学概论
  14. 张晓龙2018微信公开课
  15. uniapp的navigateTo页面跳转参数传递问题
  16. SQL点滴25—T-SQL面试语句,练练手
  17. 【转】为什么360这种软件存活至今?程序员:打不死的小强,春风吹又生
  18. 2022年6月的顶级黑客
  19. hbase踩坑记录(二):Can not resolve promote.cache-dns.local, please check your network
  20. 强化学习——day12 多臂老虎机问题MAB

热门文章

  1. python100例详解-Python编程之属性和方法实例详解
  2. 语音识别电路设计图集锦 - 嵌入式类电子电路图 - 电子发烧友网
  3. java类对象的内部结构图解(java对象模型精讲)
  4. 带桭字的名字_带芙字的名字 好名字从出生就伴随我们一生 必须雅致
  5. express-art-template模板引擎(详细)
  6. 节点操作大全(二)~操作节点的属性
  7. 算法-查找数组两个数据相加等于目标值
  8. SpringSecurity系列(四) Spring Security 实现权限树形菜单
  9. 服务器资源评估文档,服务器存储资源评估
  10. 【堆】leetcode215:第k大元素