首页 > 其他分享 >自定义ConditionalOnXX注解(二)

自定义ConditionalOnXX注解(二)

时间:2023-01-31 21:25:55浏览次数:58  
标签:01 ConditionalOnXX 自定义 31 Conditional public 2023 注解 class

一、前言

  在之前的文章《自定义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);
 *    }
 *
 *    &#064;ConditionalOnJndi()
 *    static class OnJndi {
 *    }
 *
 *    &#064;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,点击查看

标签:01,ConditionalOnXX,自定义,31,Conditional,public,2023,注解,class
From: https://www.cnblogs.com/2YSP/p/17080784.html

相关文章

  • 通过自定义注解和反射实现策略模式
    通过自定义注解和反射实现策略模式​ 今天在写一个工单系统时,工单审批通过后,需要根据不同的工单类型选择不同的处理方式非常适合用自定义注解+反射来实现,研究了一番,......
  • Taro 自定义地图并接入高德sdk
    小程序项目有用到需要自定义地图的需求,于是记录下操作流程1、引入高德地图sdk包下载地址:https://lbs.amap.com/api/wx/download2、项目中导入并初始化//导入impor......
  • mavon-editor自定义添加颜色选择器
    mavon-editor原本是没有带颜色选择器的,产品提出的需求,只好自定义一个了这里是看了源码再加上看别人的博客,然后加了个插槽,我使用的是elementui的颜色选择器el-color-picke......
  • 【转载】 spring 利用注解类添加日志到mysql
    一、前言我们写完一个项目,运维时,如果出现了bug,我们需要查看控制台的日志,但是那个日志无关方法太多,查找不是很方便,还有就是一个项目上线之后,我们需要记录谁操作了那些功能,......
  • grafana 自定义dashboard Variables
    Variables 示例VariablesDependenciesdashboard显示  ......
  • 微信小程序自定义导航栏机型适配
    自定义微信小程序头部导航栏,有几种方式方式一{"navigationStyle":"custom"//将navigationStyle从默认default改为custom}定义此方法后,头部的导航栏会去掉,导航......
  • vue3实现禁用物理按键返回,但是可以通过自定义app-bar的返回按钮返回
    1.注意app-bar是一个所有页面都会用到的顶部title栏,里面左侧有返回按钮;2.基于1,在app-bar组件的setup里添加这个代码:onMounted(()=>{//不能少history.pu......
  • django 自定义模版过滤器
    虽然DTL给我们内置了许多好用的过滤器。但是有些时候还是不能满足我们的需求。因此Django给我们提供了一个接口,可以让我们自定义过滤器,实现自己的需求。模版过滤器必须要......
  • CAD怎么自定义线型?CAD线型自定义步骤
    有些设计师小伙伴绘制CAD图纸的过程中,在调用CAD线型时,觉得软件中自带的线型不适用,想要自定义CAD线型,那么,CAD怎么自定义线型呢?本节教程小编就来给大家分享一下浩辰CAD软件中......
  • 直播电商平台开发,vue 自定义指令过滤特殊字符
    直播电商平台开发,vue自定义指令过滤特殊字符 /** *@tagsinput只可以輸入数字、字母、汉字 *@examplev-emoji */exportdefault(app)=>{ app.directive('e......