在进行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;
}
}

通过条件注解@Conditional细粒度的选择bean实例的更多相关文章

  1. [读书笔记] 二、条件注解@Conditional,组合注解,元注解

    一.条件注解@Conditional,组合注解,元注解 1. @Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的. 例子: 首先,两个Condi ...

  2. Spring Boot实战笔记(八)-- Spring高级话题(条件注解@Conditional)

    一.条件注解@Conditional 在之前的学习中,通过活动的profile,我们可以获得不同的Bean.Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解 ...

  3. Spring_总结_04_高级配置(二)_条件注解@Conditional

    一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其 ...

  4. 条件注解@Conditional

    通过活动的profile,可以获得不同的Bean.Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditonal注解 @Conditional根据满足某一个特定条件创建一个特定 ...

  5. springboot自动装配(3)---条件注解@Conditional

    之前有说到springboot自动装配的时候,都是去寻找一个XXXAutoConfiguration的配置类,然而我们的springboot的spring.factories文件中有各种组件的自动装配 ...

  6. SpringBoot条件注解@Conditional

    最近项目中使用到了关于@Conditional注解的一些特性,故写此文记录一下 @Conditional是啥呀? @Conditional注解是个什么东西呢,它可以根据代码中设置的条件装载不同的bea ...

  7. Spring条件注解@Conditional

    @Conditional是Spring4新提供的注解,它的作用是根据某个条件创建特定的Bean,通过实现Condition接口,并重写matches接口来构造判断条件.总的来说,就是根据特定条件来控制 ...

  8. Spring知识点回顾(06)Profile 和 条件注解 @Conditional

    1.设定环境中的active profiles 如:DispatcherServerlet的init-param spring.profiles.active=production spring.pr ...

  9. JavaEE开发之Spring中的条件注解组合注解与元注解

    上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...

随机推荐

  1. 慕课网 javascript深入浅出编程练习

    任务 请在index.html文件中,编写arraysSimilar函数,实现判断传入的两个数组是否相似.具体需求: 1. 数组中的成员类型相同,顺序可以不同.例如[1, true] 与 [false ...

  2. Android sdcard之read-only

    AndroidManifest.xml是否加入了SDCard的权限设置 <!-- 创建与删除文件权限 --> <uses-permission android:name=" ...

  3. Android Toast:是一个类,主要管理消息的提示

    Toast:是一个类,主要管理消息的提示.makeText(),是Toast的一个方法,用来显示信息,分别有三个参数.第一个参数:this,是上下文参数,指当前页面显示第二个参数:“string st ...

  4. CSS 小结笔记之元素的隐藏与显示

    在网站上经常会有一些需要一定操作才会显示或隐藏的元素,这时会用到元素的隐藏与显示.主要通过以下三种属性实现. 1.display :none|block |inline |inline-block d ...

  5. leetCode题解之寻找一个数在有序数组中的范围Search for a Range

    1.问题描述 Given an array of integers sorted in ascending order, find the starting and ending position o ...

  6. phantomJs页面操作

    因为phantomjs能加载和操纵页面,它可以自动化地完美执行页面的各种操作. 操作文档: 脚本的被执行,就像它真的正在web 浏览器上运行一样. 下面的脚本,是读取元素id为myagent的文本内容 ...

  7. mac 打开整个系统的隐藏文件

    打开:defaults write com.apple.finder AppleShowAllFiles -bool true 关闭:defaults write com.apple.finder A ...

  8. 远程桌面报错解决:No Remote Desktop License Servers Available

    摘 要 用户发来反馈,使用部门Windows跳板机报错:The remote session was disconnected because there are no Remote Desktop ...

  9. 18c新特性的一些小结(from JimmyHe)

    Oracle 18c在2018-02-16 release出来的,还是秉承着Oracle的cloud first理念,18c现在cloud和Engineered Systems上推出,想在传统的机器上 ...

  10. django配置连接多个数据库,自定义表名称

    在项目tt下新建两个app,分别为app01.app02.配置app01使用default节点数据库:app02使用hvdb节点数据库(也可以配置app01下的model既使用default,也可以使 ...