• 通过条件注解@Conditional细粒度的选择bean实例


    在进行spring进行开发时,当某个接口有多种实现方式并且我们只想让一种生效时,比如声明如下一个接口和两个实现:

    public interface LanggageService {
          String say();
    }
    public class ChineseServiceImpl implements LanggageService {
        @Override
        public String say() {
            return "你好";
        }
    }
    public class EnglishServiceImpl implements LanggageService {
        @Override
        public String say() {
            return "hello";
        }
    }

    我们通常使用xml为某个接口配置实现类;

        <bean id="languageService" class="com.liam.service.ChineseServiceImpl"></bean>

    当然后来我们习惯使用注解的方式了,比如

       @Bean
        public LanggageService englishService(){
            return new EnglishServiceImpl();
         }

    当然也可以通过@Component进行扫描注入,这也是为了去除java令人发指的诸多xml配置的一项进步,所以当使用spring boot进行开发时,我们尽量摒弃了诸多配置,不管是Hibernate,JPA亦或者是mybatis...

    但是也显然,有时候我们需要通过配置来选择我们使用的bean,基于xml还好,但是基于注解的话通过重新编译打包显然是不能接受的。。比如测试环境我们设置的数据源是mysql,生产环境换成oracle了,当然我们通常使用的是profile进行配置,但还是不够灵活,我们需要更细粒度的管理bean..所以也就有了Conditional。。。(废话连篇。。。)

    比如我们在spring boot中要通过application.properties中进行配置来选择我们使用的bean

    say.method=chinese

    则可以声明两个Condition

    public class SayChineseCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
          String m=  conditionContext.getEnvironment().getProperty("say.method").toString();
            boolean isChi= "chinese".equals(m);
            System.err.println("current chinese   "+ isChi);
            return isChi;
        }
    }
    public class SayEnglishCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
          String m=  conditionContext.getEnvironment().getProperty("say.method").toString();
            boolean isEn= "english"==m;
            System.err.println("current english   "+ isEn);
            return isEn;
        }
    }

    然后实现类中配置上对应的Conditional:

    @Service
    @Conditional(SayChineseCondition.class)
    public class ChineseServiceImpl implements LanggageService {
        @Override
        public String say() {
            return "你好";
        }
    }

    简单,灵活。

    此处需要注意的是application.properties在spring boot中属于环境变量级别的配置加载,所以优先级较高,假如通过其他配置文件进行加载时借助PropertySource或者ConfigurationProperties之类的是不能如愿的,因为加载Condition时,我们的配置bean尚未加载,比如下面的方式是无效的。

    @PropertySource(value = "first.properties")
    public class SayEnglishCondition implements Condition {
        @Value("${say.method}")
        private String lang;
        public String getLang() {
            return lang;
        }
        public void setLang(String lang) {
            this.lang = lang;
        }
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            String m=lang;//  conditionContext.getEnvironment().getProperty("say.method").toString();
            boolean isEn= "english".equals(m);
            System.err.println("current english   "+ isEn);
            return isEn;
        }
    }

    所以。。我们只能手动加载了。。

    public class SayEnglishCondition implements Condition { 
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            Properties properties = new Properties();
            try {
                properties.load(conditionContext.getResourceLoader().getResource("first.properties").getInputStream());
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            boolean isEn = "english".equals(properties.getProperty("say.method"));
            System.err.println("current english   " + isEn);
            return isEn;
        }
    }
  • 相关阅读:
    thinkphp目录解析
    开发规范
    form
    命名空间
    类与对象
    OS知识点汇总
    C++每日一记!
    语言哲学和语言逻辑
    形式语言与自动机
    C#脚本
  • 原文地址:https://www.cnblogs.com/ylsforever/p/8047953.html
Copyright © 2020-2023  润新知