1. pom文件<optional>标签

在Java开发中,大家肯定在pom文件中添加过依赖(现在没有,以后也肯定会有的),不知道大家对<optional>标签的了解有多少,或者是你没看下面内容,都不知道optional单词应该放在什么地方,没关系我会讲,听不懂还可以搜索别的优质博客。

<optional>标签在pom文件中长这样:

<dependency>
<groupId>com.handsometaoa</groupId>
<artifactId>sms-utool</artifactId>
<version>1.0-SNAPSHOT</version>
<optional>true</optional> <!-- 在这里 -->
</dependency>

它的作用是:当其他模块依赖当前模块时,不会传递依赖 optional 标签值为true的依赖文件,可结合下图理解:

B模块依赖C模块,并提供了BHelloUtils类,其中调用了C模块CHelloUtils的cSayHello方法,并注意(加粗)B模块pom文件中C依赖项的optional标签值为true

现在A模块依赖B模块,当调用BHelloUtils中bSayHello方法,程序会进行报错,提示找不到CHelloUtils,这里就验证了optional的作用。

那我们应该如何调整程序?在A模块pom文件添加C依赖。

2. optional hutool应用实例

空口无凭,Hutool 工具包实现了很多好用的工具,他的扩展工具包就依赖很多了第三方工具包,例如:

2.1 验证

怎么验证?拿emoji举例,没添加emoji-java依赖,EmojiUtil会爆红(找不到依赖项)。

为什么我们使用hutool工具时,没添加emoji-java也没显示错误?由于Java是动态加载,在未使用时不会报错。

2.2 设计原因

Hutool开发者考虑到扩展中的内容我们一般不会用到,假如Hutool pom中为默认或者<optional>false</optional>,当我们引入hutool工具,会相应引入额外的其他依赖(本质上不会使用),也可能会导致依赖冲突(hutool 中依赖版本为1.1.1,自己项目中版本为 1.0.9)。

3. ConditioalOnClass

ConditioalOnClass:就是当前类路径下存在该类,才会使标有该注解的类或方法生效

3.1 测试代码结构总览

sms-unite-sdk中配置类可以这样写,就能实现阿里云、腾讯云短信二选一。

@Configuration
public class SmsConfig { @Bean
@ConditionalOnClass(name = "com.aliyun.sms.SmsServiceImpl")
public SmsService ailiyunSmsService() {
System.out.println("aliyun smsService init");
return new com.aliyun.sms.SmsServiceImpl();
} @Bean
@ConditionalOnMissingBean(SmsService.class)
@ConditionalOnClass(name = "com.tencent.sms.SmsServiceImpl")
public SmsService tencentSmsService() {
System.out.println("tx smsService init");
return new com.tencent.sms.SmsServiceImpl();
} }

4. 关于Spring 自动装配

2.7.x之前:resources 下增加META-INF文件夹,创建spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.handsometaoa.config.SmsConfig

2.7.x之后:resources 下增加META-INF文件夹,在其下创建spring文件夹,最后创建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件

com.handsometaoa.config.SmsConfig

为了兼容,可以同时写:

在pom文件中

    <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>2.7.18</spring-boot.version>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-expression</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<optional>true</optional> <!-- 注意这里,用户引用此模块,spring会自动使用用户的版本 -->
</dependency> <!-- 省略其他 -->
</dependencies>

5. Demo代码

https://github.com/handsometaoa/condition_on_class-demo (可结合代码、本地执行进行理解)

关于ConditionalOnClass注解的更多相关文章

  1. springboot的@ConditionalOnClass注解

    大家好,我是"良工说技术". 今天给大家带来的是springboot中的@ConditionalOnClass注解的用法.上次的@ConditionalOnBean注解还记得吗? ...

  2. Spring Conditional注解使用小结

    今天我们来总结下Conditional注解的使用. Conditional注解 增加配置类Config package condition; import org.springframework.co ...

  3. 【玩转SpringBoot】用好条件相关注解,开启自动配置之门

    自动配置隐含两层含义,要搞清楚 上帝让程序员的发量减少,是为了让他变得更聪明,如果有一天聪明到了极点,那就是绝顶聪明. 据说在大脑高速运转下,这样更有利于散热,不至于核心温度过高而产生告警. 聪明的大 ...

  4. SpringBoot自动化配置之四:@Conditional注解详解

    前言 之前在分析spring boot 源码时导出可见@ConditionalOnBean 之类的注解,那么它到底是如何使用的以及其工作流程如何,我们这里就围绕以下几点来分析: @Conditiona ...

  5. 玩转SpringBoot用好条件相关注解,开启自...

    官方提供的常用条件注解 因为Spring的核心是基于bean的,所以这些条件注解主要是影响bean的注册. 因为注册的bean不同了,最后对外呈现的行为就不同了.不就是自动配置了. 一.最常用的应该是 ...

  6. 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三)

    注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 如何分析SpringBoot源码模块及结构?--SpringBoot源码(二) 上一篇分析了SpringBoo ...

  7. Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件

    本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 图 2 第二章目录结构图 第 2 章 Spr ...

  8. Spring boot ConditionalOnClass原理解析

    Spring boot如何自动加载 对于Springboot的ConditionalOnClass注解一直非常好奇,原因是我们的jar包里面可能没有对应的class,而使用ConditionalOnC ...

  9. 死磕Spring之AOP篇 - Spring AOP注解驱动与XML配置

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  10. 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

随机推荐

  1. 鸿蒙系统(HarmonyOS)全局弹窗实现

    全局弹窗相对于自定义弹窗有以下优点: 封装更彻底,一行代码就能调用 跟组件耦合度低,只需要传入组件的UIContext对象,不需要跟自定义弹窗一样需要在组件内部实例化CustomDialogContr ...

  2. JavaScript之Blob对象基本用法及分片上传示例

    Blob基本用法 创建 通过Blob的构造函数创建Blob对象: new Blob(blobParts[, options]) blobParts: 数组类型, 数组中的每一项连接起来构成Blob对象 ...

  3. 【合合TextIn】深度解析智能文档处理技术与应用

    一.智能文档处理介绍 智能文档处理(Intelligent Document Processing, IDP)是利用人工智能(AI).机器学习(ML).计算机视觉(CV).自然语言处理(NLP)等技术 ...

  4. .net core8 使用JWT鉴权(附当前源码)

    说明 该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发). 该系统文章,我会尽量说的非常详细,做到不管新手.老手都能看懂. 说明:OverallAuth2 ...

  5. 使用 Debugger 断点 如果打开了断点调试 就会跳转空白页面

    <!DOCTYPE html> <html> <header> <title>test</title> </header> &l ...

  6. prometheus+grafana配置流程

    prometheus+grafana配置流程 首先,安装对应的exporter 查看prometheus支持的所有exporters https://prometheus.io/docs/instru ...

  7. WTConv:小参数大感受野,基于小波变换的新型卷积 | ECCV'24

    近年来,人们尝试增加卷积神经网络(CNN)的卷积核大小,以模拟视觉Transformer(ViTs)自注意力模块的全局感受野.然而,这种方法很快就遇到了上限,并在实现全局感受野之前就达到了饱和.论文证 ...

  8. 云原生爱好者周刊:K8s Security SIG 发布 Kubernetes 策略管理白皮书

    云原生一周动态要闻: Istio 1.13 发布 CNCF 宣布 2021 年云原生调查结果 运行时安全项目 Falco 添加可扩展插件框架 Grafana 8.3.6 发布 开源项目推荐 文章推荐 ...

  9. 全局负载均衡、CDN内容分发的原理与实践

    CDN简介 CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分发. ...

  10. linux 基础(8)例行任务

    我们的 linux 系统,有时会自动进行线上更新,会定时升级locate用到的数据库.用户也会"在每天0点备份数据"或者"每天8点分析登录文件",管理这些例行任 ...