• SpringBoot @Condition


    @Conditional注解

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

    1. 定义

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

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

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

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

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

    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

    @Component
    @Conditional(ScanDemoCondition.class)
    public class ScanDemoBean {
    
        @Value("${conditional.demo.load}")
        private boolean load;
    
        public boolean getLoad() {
            return load;
        }
    }

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

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

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

    @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 注解

    @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 配置如下

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

      

     

  • 相关阅读:
    1.Vue.js的常用指令
    爬虫
    对key中有数字的字典进行排序
    微信公众号服务器验证的坑
    Linux之正则表达式grep
    Oracle之select
    Linux之文件与目录管理
    Linux之vim、压缩与解压缩
    Linux之文件权限、用户管理
    Oracle学习入门
  • 原文地址:https://www.cnblogs.com/yuarvin/p/14385256.html
Copyright © 2020-2023  润新知