自定义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 ...
随机推荐
- 基于Apache PDFBox的PDF数字签名
在Java语言环境中完成数字签名主要基于itext-pdf.PDFBox两种工具,itext-pdf受商业限制,应用于商业服务中需要购买授权.PDFBox是apache基金会开源项目,基于apache ...
- git提交出现running pre-commit hook: lint-staged
现象 今天提交代码的时候出现了 > running pre-commit hook: lint-staged Stashing changes... [started] Stashing cha ...
- Ant Design Vue中Table的选中详解
<template> <a-table :columns="columns" :data-source="data" :row-selecti ...
- ABP vNext系列文章10---分布式事务集成netcore.Cap
最近项目中要用到分布式事务功能,调研了DTM和Cap,最终确定用Cap来实现,Cap支持最终一致性,项目中采用MQ作为消息中间件,数据库用的mysql,集成步骤如下: 1.在需要发布消息的服务中引入如 ...
- IdentityServer4 系列文章01---密码授权模式
IdentityServer4实现.Net Core API接口权限认证(快速入门) 什么是IdentityServer4 官方解释:IdentityServer4是基于ASP.NET Core实 ...
- 基于.Net Core3.1 MVC + EF Core的项目(一)框架的初步搭建
项目暂时分为六大块,结构如图所示 代码地址是 https://github.com/hudean/VacantCloud- 里面有许多没有完成,不过一些大致的内容都写的差不多了,权限认证依赖注入 ...
- Java中YYYY-MM-dd在跨年时出现的bug
先看一张图: Bug的产生原因: 日期格式化时候,把 yyyy-MM-dd 写成了 YYYY-MM-dd Bug分析: 当时间是2019-08-31时, public class DateTest { ...
- 超级AI助手:全新提升!中文NLP训练框架,快速上手,海量训练数据
"超级AI助手:全新提升!中文NLP训练框架,快速上手,海量训练数据,ChatGLM-v2.中文Bloom.Dolly_v2_3b助您实现更智能的应用!" 1.简介 目标:基于py ...
- parser.add_argument()用法——命令行选项、参数和子命令解析器
argparse是一个Python模块:命令行选项.参数和子命令解析器.通过使用这种方法,可以在使用 1.argparse简介: argparse 模块是 Python 内置的一个用于命令项选项与参数 ...
- C++ Boost库 操作字符串与正则
字符串的查找与替换一直是C++的若是,运用Boost这个准标准库,将可以很好的弥补C++的不足,使针对字符串的操作更加容易. 字符串格式转换: #include <iostream> #i ...