SpringBoot @Condition

@Conditional注解

这个注解在Spring4中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean

1. 定义

@Conditional注解定义如下,其内部主要就是利用了Condition接口,来判断是否满足条件,从而决定是否需要加载Bean

1
2
3
4
5
6
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

下面是Condtion接口的定义,这个可以说是最基础的入口了,其他的所有条件注解,归根结底,都是通过实现这个接口进行扩展的

1
2
3
4
@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

这个接口中,有个参数比较有意思ConditionContext,它持有不少有用的对象,可以用来获取很多系统相关的信息,来丰富条件判断,接口定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface ConditionContext {
    // 获取Bean定义
    BeanDefinitionRegistry getRegistry();
 
    // 获取Bean工程,因此就可以获取容器中的所有bean
    @Nullable
    ConfigurableListableBeanFactory getBeanFactory();
 
    // environment 持有所有的配置信息
    Environment getEnvironment();
     
    // 资源信息
    ResourceLoader getResourceLoader();
 
    // 类加载信息
    @Nullable
    ClassLoader getClassLoader();
}

2、如何使用Condition和@Conditional注解,来实现bean的条件加载,自动扫描Bean的条件加载

从使用来讲,和前面的没有什么区别,只是将注解放在具体的类上而言,同样给出一个示例,先定义一个bean

1
2
3
4
5
6
7
8
9
10
11
@Component
@Conditional(ScanDemoCondition.class)
public class ScanDemoBean {
 
    @Value("${conditional.demo.load}")
    private boolean load;
 
    public boolean getLoad() {
        return load;
    }
}

对应的判断条件如下,当配置文件中conditional.demo.load为true时,才会加载这个配置,否则不实例化

1
2
3
4
5
6
public class ScanDemoCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return "true".equalsIgnoreCase(conditionContext.getEnvironment().getProperty("conditional.demo.load"));
    }
}

测试类和前面差不多,稍微注意下的就是自动注入时,改一下必要条件,避免bean不存在时报错

1
2
3
4
5
6
7
8
9
10
11
12
@Autowired(required = false)
private ScanDemoBean scanDemoBean;
 
@GetMapping(path = "/scan")
public String showDemo() {
    String type = environment.getProperty("conditional.demo.load");
    if (scanDemoBean == null) {
        return "not exists! >>>" + type;
    } else {
        return "load : " + scanDemoBean.getLoad() + " >>>" + type;
    }
}

3、Spring框架提供了一系列相关的注解,如下表

注解说明
@ConditionalOnSingleCandidate 当给定类型的bean存在并且指定为Primary的给定类型存在时,返回true
@ConditionalOnMissingBean 当给定的类型、类名、注解、昵称在beanFactory中不存在时返回true.各类型间是or的关系
@ConditionalOnBean 与上面相反,要求bean存在
@ConditionalOnMissingClass 当给定的类名在类路径上不存在时返回true,各类型间是and的关系
@ConditionalOnClass 与上面相反,要求类存在
@ConditionalOnCloudPlatform 当所配置的CloudPlatform为激活时返回true
@ConditionalOnExpression spel表达式执行为true
@ConditionalOnJava 运行时的java版本号是否包含给定的版本号.如果包含,返回匹配,否则,返回不匹配
@ConditionalOnProperty 要求配置属性匹配条件
@ConditionalOnJndi 给定的jndi的Location 必须存在一个.否则,返回不匹配
@ConditionalOnNotWebApplication web环境不存在时
@ConditionalOnWebApplication web环境存在时
@ConditionalOnResource 要求制定的资源存在
@ConditionalOnExpression ? 当表达式为true的时候,才会实例化一个Bean。

@ConditionalOnProperty 注解

1
2
3
4
5
6
7
8
9
@Configuration
public class WebConfig {
  
    @Bean
    @ConditionalOnProperty(prefix = "rest", name = "auth-open", havingValue = "true", matchIfMissing = true)
    public AuthFilter jwtAuthenticationTokenFilter() {
        return new AuthFilter();
    }
}
  • prefix:application.properties配置的前缀
  • name:属性是从application.properties配置文件中读取属性值
  • havingValue:配置读取的属性值跟havingValue做比较,如果一样则返回true,否则返回false;如果返回值为false,则该configuration不生效;为true则生效
  • matchIfMissing = true:表示如果没有在application.properties设置该属性,则默认为条件符合

上面代码的意思:是否启动jwt的的配置,如果application.properties配置中没有设置就启动jwt,如果设置了true就启动,如果false就关闭。

application.properties 配置如下

1
2
rest:
    auth-open: true # jwt鉴权机制是否开启(true或者false)

  

 

posted on   书梦一生  阅读(455)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示