zoukankan      html  css  js  c++  java
  • Spring

    前言

    @Conditional是Spring4提供的注解,它可以根据条件判断是否将Bean注册到容器中,源码如下:

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

    简单示例

    举一个简单的例子,如何根据当前操作系统来进行对象实例化

    • 接口
    public interface SystemInter {
        String get();
    }
    
    • 实现类
    public class Linux implements SystemInter {
        @Override
        public String get() {
            return "System's Linux";
        }
    }
    
    public class Windows implements SystemInter {
        @Override
        public String get() {
            return "System's windows";
        }
    }
    
    • 控制器
    public class TestController {
        @Autowired
        private SystemInter systemInter;
    
        @GetMapping(value = "/system")
        public String getSystem(){
            return systemInter.get();
        }
    }
    

    上述代码用于表示操作系统的两个对象,问题来了,如何根据操作系统进行相应的对象实例化,在控制器中注入呢?

    这里就可以用到@Conditional注解,通过实现Condition接口重写方法来自定义match规则,Condition接口需要实现matches方法,返回true则注入bean,false则不注入。

    • 条件类
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    public class LinuxCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        	// 获取配置文件中system.condition的属性
            String name = conditionContext.getEnvironment().getProperty("system.condition");
            return "linux".equalsIgnoreCase(name);
        }
    }
    
    public class WindowsCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        	// 获取配置文件中system.condition的属性
            String name = conditionContext.getEnvironment().getProperty("system.condition");
            return "windows".equalsIgnoreCase(name);
        }
    }
    
    • application.properties的配置,配置操作系统为windows
    system.condition = windows
    
    • 创建SystemConfiguration 类,用于配置两个实例的注入
    @Configuration
    public class SystemConfiguration {
    
        @Bean
        @Conditional(LinuxCondition.class)
        public SystemInter linux() {
            return new Linux();
        }
    
        @Bean
        @Conditional(WindowsCondition.class)
        public SystemInter windows() {
            return new Windows();
        }
    }
    
    • 由上述代码可以看出,我们给两个操作系统对象分别建立的对应的条件类,并通过配置文件中的system.condition属性来判断是否实例化。

    • 访问接口结果如下,可以看出,我们从配置文件读取操作系统类型并实例化了windows对象。

    在这里插入图片描述

    • 切换application.properties的操作系统配置为linux
    system.condition = linux
    
    • 访问结果如下:

    在这里插入图片描述

    • 这是个简单的例子,却体现了Spring的策略模式(根据环境或者条件的不同选择不同的算法或者策略来完成该功能)

    • 注:以上的示例将@Conditional标注在方法上,而@Conditional标注在类上可以判断该配置类中的所有Bean是否注入。

    内置的条件注解

    注解 条件
    @ConditionalOnBean 当SpringIoC容器内存在指定Bean的条件
    @ConditionalOnMissingBean 当SpringIoC容器内不存在指定Bean的条件
    @ConditionalOnClass 当SpringIoC容器内存在指定Class的条件
    @ConditionalOnMissingClass 当SpringIoC容器内不存在指定Class的条件
    @ConditionalOnProperty 指定的属性是否有指定的值
    @ConditionalOnResource 类路径是否有指定的值
    @ConditionalOnWebApplication 当前项目是Web项目的条件
    @ConditionalOnNotWebApplication 当项目不是Web项目的条件
    @ConditionalOnExpression 基于SpEL表达式作为判断条件
    @ConditionalOnJava 基于JVM版本作为判断条件
    @ConditionalOnJndi 在JNDI存在时查找指定的位置
    @ConditionalOnSingleCandidate 当指定Bean在SpringIoC容器内只有一个,或者虽然有多个但是指定首选的Bean
    - End -
    梦想是咸鱼
    关注一下吧
    以上为本篇文章的主要内容,希望大家多提意见,如果喜欢记得点个推荐哦
    作者:Maggieq8324
    本文版权归作者和博客园共有,欢迎转载,转载时保留原作者和文章地址即可。
  • 相关阅读:
    ndk安装
    android studio安装
    navicat15安装及激活
    relative和absolute理解
    meta标签大全
    爆炸、翻转、扭曲、立方、翻页特效
    CSS3-多媒体查询
    CSS3-按钮
    CSS3-图片
    css3-多列
  • 原文地址:https://www.cnblogs.com/maggieq8324/p/15118941.html
Copyright © 2011-2022 走看看