@Conditional注解的使用场景和源码解析

 更新时间:2023年11月28日 09:49:32   作者:搬山道猿  
这篇文章主要介绍了@Conditional注解的使用场景和源码解析,@Conditional是一个条件注解,它的作用是判断Bean是否满足条件,如果满足条件,则将Bean注册进IOC中,如果不满足条件,则不进行注册,需要的朋友可以参考下

介绍

今天要分享的是Spring的注解@Conditional,@Conditional是一个条件注解,它的作用是判断Bean是否满足条件,如果满足条件,则将Bean注册进IOC中,如果不满足条件,则不进行注册,这个注解在SpringBoot中衍生出很多注解,比如@ConditionalOnProperty,@ConditionalOnBean,@ConditionalOnClass等等,在SpringBoot中,这些注解用得很多。

文件服务场景

下面我们演示一些@Conditional的使用,在软件开发中,文件系统是必须的,但是系统的特点不一样,有些用户希望将文件保存在自己的服务器上,有些用户则没这种要求,这时候,文件可以保存在云上,也可以保存在自建文件系统上,那么面对不同用户的需求,我们的软件也要能够适配不同的环境,只需要简单的配置即可。

假设我们在开发过程中,我们的文件全部托管在云服务厂商的OSS上,代码逻辑也没有预留扩展,那么当用户需要私有化部署,我们可能就需要更改文件存储这边的逻辑,这样的设计是不合理的。

我们想一想,文件存储的代码逻辑是不同的,各个文件系统的实现方式和使用API各不相同,但是它们有一个共性,那就是能够上传文件,下载文件的,所以我们就应该抽象出一个公共接口,下面有不同的实现,比如Minio的文件上传下载等逻辑就使用Minio API去实现,FastDFS就使用FastDFS,OSS就使用OSS,下面我们就编写对应的代码。

编码实现

以下通过编码实现不同文件系统的逻辑实现隔离,统一提供接口的方案,一般我们都会将配置信息写在配置文件中,在配置文件中,使用storageType代表文件存储类型。

文件上传接口

在StorageService接口中,只简单定义了两个方法init()和put(),init()就是做一些初始化操作,比如参数配置,连接等,put()就是上传文件接口。

/**
 * 功能说明: 文件上传接口
 * <p>
 * Original @Author: steakliu-刘牌, 2023-04-03  09:54
 * <p>
 */
public interface StorageService {
    /**
     * 初始化文件存储
     */
    void init();
    /**
     * 上传文件
     * @param file
     */
    void put(MultipartFile file);
}

具体文件系统实现

以下是Minio的具体实现,在类上面使用了@Conditional注解,value值为MinioStorageCondition。

@Component
@Conditional(value = MinioStorageCondition.class)
public class MinioStorageService implements StorageService {
 
    @Override
    public void init() {
        // 初始化操作
    }
 
    @Override
    public void put(MultipartFile file) {
        
    }
}

MinioStorageCondition条件判断

MinioStorageCondition的作用就是判断条件是否匹配,它实现Condition接口,要使用@Conditional,其判断类必须要实现Condition接口,然后自己实现matches方法逻辑,以下就是判断storageType是否为minio,如果为minio,那么就返回true,就代表要创建MinioStorageService这个bean,为false则不创建。

public class MinioStorageCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String storageType = context.getEnvironment().getProperty("storageType");
        return "minio".equals(storageType);
    }
}

源码解析

spring在扫描bean的时候,会判断对应的bean是否有@Conditional注解,如果有,则会进入value中的类,进去判断是否符合条件,如果符合,则返回true,就能够注册,实际上如果符合条件,那么就能将BeanDefinition注册进BeanFactory,如果不符合,自然不能注册进。

如下是源码的时序图

从上面的时序图中可以看出,整个过程涉及的类还是挺多的,不过这还不是完整流程,只是从扫描类开始,Spring会扫描工程路径下的类,这个路径可以通过@ComponentScan进行指定,如果是SpringBoot项目,则就为当前工程,然后筛选出需要注册的bean并注册到BeanFactory,对于标注有@Conditional注解的类,会进入@Conditional中value的类中,就是上面的MinioStorageCondition或者FastDFSStorageCondition,然后进行匹配,不满足条件的则不会被注册。

@Conditional的具体流程也比较简单,就不一一赘述,可以看着上面的时序图去看源码实现。

总结

上面对@Conditional的使用,原理等进行简单的介绍,@Conditional注解在SpringBoot中用得还是比较多的,特别是它衍生出来的一些注解,这些注解都是基于它来进行二次封装的,在SpringBoot中,对于很多starter,里面几乎都会有@Conditional和@Conditional衍生注解的使用,我们后续会挑选出一些来说。

到此这篇关于@Conditional注解的使用场景和源码解析的文章就介绍到这了,更多相关@Conditional注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 全面解析SpringBoot配置文件

    全面解析SpringBoot配置文件

    这篇文章主要为大家全面的解析SpringBoot-配置文件,文中附含详细的图文示例代码,以便同学们能更好的理解,有需要的同学可以借鉴参考下
    2021-09-09
  • java多线程数据分页处理实例讲解

    java多线程数据分页处理实例讲解

    在本篇内容里小编给大家分享了一篇关于java多线程数据分页处理实例讲解内容,有兴趣的朋友们可以学习下。
    2021-01-01
  • java类型生命周期的详细解析

    java类型生命周期的详细解析

    以下是对java中的类型生命周期进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • Java下SpringBoot创建定时任务详解

    Java下SpringBoot创建定时任务详解

    这篇文章主要介绍了Java下SpringBoot创建定时任务详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 利用ScriptEngineManager实现字符串公式灵活计算的方法

    利用ScriptEngineManager实现字符串公式灵活计算的方法

    今天小编就为大家分享一篇利用ScriptEngineManager实现字符串公式灵活计算的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Java中ArrayList的removeAll方法详解

    Java中ArrayList的removeAll方法详解

    这篇文章主要给大家介绍了关于Java中ArrayList的removeAll方法的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来看看吧。
    2017-07-07
  • java实现人员信息管理系统

    java实现人员信息管理系统

    这篇文章主要为大家详细介绍了java实现人员信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Spark 集群执行任务失败的故障处理方法

    Spark 集群执行任务失败的故障处理方法

    这篇文章主要为大家介绍了Spark 集群执行任务失败的故障处理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • SpringBoot中的@Component注解源码

    SpringBoot中的@Component注解源码

    在SpringBoot中,@Component注解用于标识一个类为Bean,并由Spring进行管理,它需要配合@ComponentScan注解使用,后者负责扫描包含@Component的类,并进行自动装配,本文给大家介绍SpringBoot中的@Component注解源码,感兴趣的朋友一起看看吧
    2024-01-01
  • 详解SpringBoot中@PostMapping注解的用法

    详解SpringBoot中@PostMapping注解的用法

    在SpringBoot中,我们经常需要编写RESTful Web服务,以便于客户端与服务器之间的通信,@PostMapping注解可以让我们更方便地编写POST请求处理方法,在本文中,我们将介绍@PostMapping注解的作用、原理,以及如何在SpringBoot应用程序中使用它
    2023-06-06

最新评论