自定义ConditionalOnXX注解(二)
一、前言
在之前的文章《自定义ConditionalOnXX注解》中,介绍了Conditional注解的实现原理和实现自定义Conditional注解的基础方法,但是有些场景我们需要用一个ConditionalOnXX注解来实现多条件的与(AND)或(OR)非(NOT)逻辑,本文就是介绍这种复杂场景的应用。
二、自定义注解合并多条件
假设有一个bean MyBean,我们想通过当前操作系统标识来控制其是否注入到Spring容器中。
首先创建windows和mac系统的condition
OnWindowsCondition
/**
* @author Ship
* @version 1.0.0
* @description:
* @date 2023/01/31 10:20
*/
public class OnWindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return SystemUtils.IS_OS_WINDOWS;
}
}
OnMacCondition
/**
* @author Ship
* @version 1.0.0
* @description:
* @date 2023/01/31 10:20
*/
public class OnMacCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return SystemUtils.IS_OS_MAC;
}
}
2.1 与(AND)合并条件
SpringBoot提供了一个抽象类AllNestedConditions,具体用法其类注释写的比较清楚了如下:
/**
* {@link Condition} that will match when all nested class conditions match. Can be used
* to create composite conditions, for example:
*
* <pre class="code">
* static class OnJndiAndProperty extends AllNestedConditions {
*
* OnJndiAndProperty() {
* super(ConfigurationPhase.PARSE_CONFIGURATION);
* }
*
* @ConditionalOnJndi()
* static class OnJndi {
* }
*
* @ConditionalOnProperty("something")
* static class OnProperty {
* }
*
* }
* </pre>
* <p>
* The
* {@link org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase
* ConfigurationPhase} should be specified according to the conditions that are defined.
* In the example above, all conditions are static and can be evaluated early so
* {@code PARSE_CONFIGURATION} is a right fit.
*
* @author Phillip Webb
* @since 1.3.0
*/
public abstract class AllNestedConditions extends AbstractNestedCondition {
}
只需要新建一个condition类继承AllNestedConditions,重写构造方法并添加条件即可,需要注意的是构造方法里的ConfigurationPhase枚举分为两种情况,具体用哪个取决于Condition注解的使用场景。
ConfigurationPhase.PARSE_CONFIGURATION: 用于控制配置类是否生效
ConfigurationPhase.REGISTER_BEAN: 用于控制Bean是否加载
创建条件类OnWindowsAndMacCondition
package cn.sp.condition.nested;
import cn.sp.condition.OnMacCondition;
import cn.sp.condition.OnWindowsCondition;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.context.annotation.Conditional;
/**
* @author Ship
* @version 1.0.0
* @description: 只有当所有条件都满足时,bean才会被加载
* @date 2023/01/31 10:27
*/
public class OnWindowsAndMacCondition extends AllNestedConditions {
public OnWindowsAndMacCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@Conditional(OnWindowsCondition.class)
static class OnWindows{
}
@Conditional(OnMacCondition.class)
static class OnMac{
}
}
自定义注解@ConditionalOnWindowsAndMac
/**
* @author Ship
* @version 1.0.0
* @description: 条件之是windows且mac系统
* @date 2023/01/31 10:19
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(value = OnWindowsAndMacCondition.class)
public @interface ConditionalOnWindowsAndMac {
}
2.2 或(OR)合并条件
创建条件类OnWindowsOrMacCondition
/**
* @author Ship
* @version 1.0.0
* @description: 只要有一个条件满足时,bean就会被加载
* @date 2023/01/31 10:27
*/
public class OnWindowsOrMacCondition extends AnyNestedCondition {
public OnWindowsOrMacCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@Conditional(OnWindowsCondition.class)
static class OnWindows{
}
@Conditional(OnMacCondition.class)
static class OnMac{
}
}
自定义注解@ConditionalOnWindowsOrMac
/**
* @author Ship
* @version 1.0.0
* @description: 条件之是windows或mac系统
* @date 2023/01/31 10:19
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(value = OnWindowsOrMacCondition.class)
public @interface ConditionalOnWindowsOrMac {
}
2.3 非(NOT)合并条件
创建条件类OnNotWindowsCondition
/**
* @author Ship
* @version 1.0.0
* @description: 只有当所有条件都不满足时,bean才会被加载
* @date 2023/01/31 10:27
*/
public class OnNotWindowsCondition extends NoneNestedConditions {
public OnNotWindowsCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@Conditional(OnWindowsCondition.class)
static class OnWindows {
}
}
自定义注解@ConditionalOnNotWindows
/**
* @author Ship
* @version 1.0.0
* @description: 条件之不是windows系统
* @date 2023/01/31 10:19
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(value = OnNotWindowsCondition.class)
public @interface ConditionalOnNotWindows {
}
三、测试验证
TestConfiguration配置类添加了MyBean的注入方法
@Configuration
public class TestConfiguration {
@ConditionalOnWindowsAndMac
// @ConditionalOnWindowsOrMac
// @ConditionalOnNotWindows
@Bean
public MyBean myBean() {
System.out.println("Initialized bean:myBean...");
return new MyBean();
}
}
@ConditionalOnWindowsAndMac测试
本人机器是Mac系统,启动项目控制台没有任何输出,表明结果正常,毕竟没有既是windows又是mac的系统。
@ConditionalOnWindowsOrMac测试
将myBean()方法打上@ConditionalOnWindowsOrMac注解,启动项目控制台输出如下:
2023-01-31 20:51:25.584 INFO 16669 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 967 ms
Initialized bean:myBean...
2023-01-31 20:51:25.955 INFO 16669 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2023-01-31 20:51:25.965 INFO 16669 --- [ main] cn.sp.SpringExtensionApplication : Started SpringExtensionApplication in 2.118 seconds (JVM running for 3.965)
说明MyBean被加载了,条件生效。
@ConditionalOnNotWindows测试
将myBean()方法打上@ConditionalOnNotWindows注解,启动项目控制台也打印出了[Initialized bean:myBean...],说明MyBean被加载了,条件生效。
文章代码已上传至github,点击查看。
自定义ConditionalOnXX注解(二)的更多相关文章
- 自定义ConditionalOnXX注解
一.Conditional注解介绍 对SpringBoot有足够了解的小伙伴应该都用过Conditional系列注解,该注解可用在类或者方法上用于控制Bean的初始化. 常用的Conditional注 ...
- asp.net mvc3 数据验证(三)—自定义数据注解
原文:asp.net mvc3 数据验证(三)-自定义数据注解 前两节讲的都是asp.net mvc3预先设定的数据注解,但是系统自由的数据注解肯定不适合所有的场合,所以有时候我们需要 ...
- spring-cloud: eureka之:ribbon负载均衡自定义配置(二)
spring-cloud: eureka之:ribbon负载均衡自定义配置(二) 有默认配置的话基本上就是轮询接口,现在我们改用自定义配置,同时支持:轮询,随机接口读取 准备工作: 1.eureka服 ...
- SpringBoot自定义Condition注解
最近碰到个这样的需求,需要同一套代码适配个版本数据库(数据库不同,且部分表的字段及关联关系可能会不同),即这套代码配置不同的数据库都能跑.项目采用的框架为SpringBoot+Mybatis. ...
- 【Spring Cloud】Spring Cloud之自定义@SpringCloudProfile注解实现@Profile注解的功能
一.为什么会想到定义@SpringCloudProfile这样的注解 首页提一下@Profile注解:它主要用与Spring Boot多环境配置中,指定某个类只在指定环境中生效,比如swagger的配 ...
- springcloud项目实现自定义权限注解进行接口权限验证
一般在项目开发中会根据登录人员的权限大小对接口也会设置权限,那么对接口权限是怎么实现的呢,大多数都是用自定义权限注解,只需要在接口上加上一个注解就可以实现对接口的权限拦截,是否对该接口有权调用 接下来 ...
- 自定义校验注解ConstraintValidator
一 前言 系统执行业务逻辑之前,会对输入数据进行校验,检测数据是否有效合法的.所以我们可能会写大量的if else等判断逻辑,特别是在不同方法出现相同的数据时,校验的逻辑代码会反复出现,导致代码冗余, ...
- [译]SpringMVC自定义验证注解(SpringMVC custom validation annotations)
在基于SpringMVC框架的开发中,我们经常要对用户提交的字段进行合法性验证,比如整数类型的字段有个范围约束,我们会用@Range(min=1, max=4).在实际应用开发中,我们经常碰到一些自己 ...
- 自定义view(二)
这里是自定义view(二),上一篇关于自定义view的一些基本知识,比如说自定义view的步骤.会涉及到哪些函数以及如何实现自定义属性,同时实现了一个很基础的自定义控件,一个自定义的计时器,需要看的人 ...
- jsr-303 参数校验—自定义校验注解
1.为什么要自定义? 通过上篇学习,了解到很多常用注解了,但是呢,总是有那么些需求.... 2.案例分析(手机号格式) 2.1.需要验证的实体 Bean public class LoginVo ...
随机推荐
- SAP Gateway Trace
最近在SAP PE项目上遇到一个需求要求记录所有的ODATA(含S4/CLOUD API)的报文. Below T-codes recording logging and tracing: /IWFN ...
- 一个Promise指定多个成功或者失败的回调详解
// 当一个Promise指定多个成功或者失败的回调:都会调用吗? 会的 let p = new Promise((resolve, reject) => { resolve('第一种成功1') ...
- 【发现一个问题】extjs-gpl-7.0: 当修改 store 对象的字段后,再次 loadPage() 后字段映射错误。
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 因为查询中需要每次返回数目不确定的 fields ,这就需 ...
- 从嘉手札<2023-10-16>
一.商君书 1)更法 商鞅和甘龙.杜挚同秦孝公商量变法. 后两者认为变法会动移已有的社会结构,"圣人不易民而教,知者不变法而治""法古无过,循礼无邪" 但商鞅( ...
- Protobuf之proto基础语法
目录 1.说明 2.字段类型 3.字段规则 4.字段编号 5.注释 6.类型 6.1.message 6.2.service 7.枚举enum 8.保留字段 9.import 9.1.protoc指令 ...
- Swift中发布-订阅框架Combine的使用
Combine简介 Combine是一个苹果用来处理事件的新的响应式框架,支持iOS 13及以上版本. 你可以使用Combine去统一和简化在处理类似于target-action,delegate,k ...
- Java并发(六)----线程start、run、state方法
1.start 与 run 调用 run public static void main(String[] args) { Thread t1 = new Thread("t1&quo ...
- electron nodejs idea 的 Terminal 默认是操作系统的 cmd.exe,他默认是GBK
问题1:idea 的 Terminal 默认是操作系统的 cmd.exe,他默认是GBK,尽量不要通过手段更改了,没意义.若要在控制台输出中文,最简单的方法是运行:chcp 65001 &&a ...
- .NET Core开发实战(第18课:日志框架:聊聊记日志的最佳姿势)--学习笔记(下)
18 | 日志框架:聊聊记日志的最佳姿势 除了使用 CreateLogger 指定 logger 的名称,实际上还可以借助容器来构造 logger,通常情况下我们会定义自己的类 namespace L ...
- Python Rich:美化终端显示效果
Rich库的功能就像它的名字一样,使Python编程更加丰富(rich),它帮助开发者在控制台(命令行)输出中创建丰富.多彩和具有格式化的文本. 本篇总结了如何使用Rich库让我们的命令行工具更加美观 ...