最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

当前播报:自定义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: * * 
 * static class OnJndiAndProperty extends AllNestedConditions { * *    OnJndiAndProperty() { *        super(ConfigurationPhase.PARSE_CONFIGURATION); *    } * *    @ConditionalOnJndi() *    static class OnJndi { *    } * *    @ConditionalOnProperty("something") *    static class OnProperty { *    } * * } * 
*

* 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的注入方法

@Configurationpublic 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 msInitialized 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,点击查看。

关键词: 构造方法 点击查看 分为两种