介绍
今天要分享的是Spring的注解@Conditional,@Conditional是一个条件注解,它的作用是判断Bean是否满足条件,如果满足条件,则将Bean注册进IOC中,如果不满足条件,则不进行注册,这个注解在SpringBoot中衍生出很多注解,比如@ConditionalOnProperty
,@ConditionalOnBean
,@ConditionalOnClass
等等,在SpringBoot中,这些注解用得很多。
文件服务场景
假设我们在开发过程中,我们的文件全部托管在云服务厂商的OSS上,代码逻辑也没有预留扩展,那么当用户需要私有化部署,我们可能就需要更改文件存储这边的逻辑,这样的设计是不合理的。
编码实现
以下通过编码实现不同文件系统的逻辑实现隔离,统一提供接口的方案,一般我们都会将配置信息写在配置文件中,在配置文件中,使用storageType代表文件存储类型。
文件上传接口
/**
* 功能说明: 文件上传接口
* <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,如果不符合,自然不能注册进。
MinioStorageCondition或者FastDFSStorageCondition
,然后进行匹配,不满足条件的则不会被注册。
总结
上面对@Conditional的使用,原理等进行简单的介绍,@Conditional注解在SpringBoot中用得还是比较多的,特别是它衍生出来的一些注解,这些注解都是基于它来进行二次封装的,在SpringBoot中,对于很多starter,里面几乎都会有@Conditional和@Conditional衍生注解的使用,我们后续会挑选出一些来说。
今天的分享就到这里,感谢你的观看,我们下期见!