你好,我是刘牌!
介绍
今天要共享的是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衍生注解的运用,咱们后续会挑选出一些来说。
今天的共享就到这儿,感谢你的观看,咱们下期见!