自定义ConditionalOnXX注解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义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注解的主要内容,如果未能解决你的问题,请参考以下文章