在进行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. sublime text2 注册码

    近终于找到  sublime Text2 升级到 2.0.2 build 2221 64位 的破破解 输入注册码就成了 ----- BEGIN LICENSE ----- Andrew Weber S ...

  2. JSP 插入到数据库的数据出现 “SQLServerException: 将截断字符串或二进制数据” 错误解决方案

    最近在编写一个小型基于的jsp系统开发.掌握数据库一直感觉还不错.但是今天就出现了一个问题困扰我大半天.后来本来准备睡觉,但是觉得今天不解决这个问题恐怕晚上是“彻夜难眠啊”!!于是打开电脑,又开始捣腾 ...

  3. dnspod域名解析设置

    time: 2016-01-8 10:30     因为我的博客是用Github page搭建的,所以要把域名和Github_name.github.io的URL联系起来.本人实在小白一个,就纪录一下 ...

  4. Dynamics 365 Customer Engagement 中对API的调整内容分享

    当前版本中弃用了以下客户端 API 以重新组织 Xrm 客户端 API 对象模型,从而更好地满足以下需求:使用同一客户端脚本而不必基于上下文或基于运行这些脚本的客户端(Web 客户端或新的统一接口)来 ...

  5. MQTT介绍(3)java模拟MQTT的发布,订阅

    MQTT目录: MQTT简单介绍 window安装MQTT服务器和client java模拟MQTT的发布,订阅 在此强调一下mqtt的使用场景: 1.不可靠.网络带宽小的网络 2.运行的设备CPU. ...

  6. IIS测试环境搭建

    1.控制面板->程序->程序和功能->打开或关闭Windows功能->Internet信息服务->Web管理工具,打开如下服务: 2.打开IIS管理器 2.1检查.net ...

  7. Python 应用剖析工具介绍

    [编者按]本文作者为来自 HumanGeo 的工程师 Davis,主要介绍了用于 Python 应用性能分析的几个工具.由国内 ITOM 管理平台 OneAPM 编译呈现. 在 HumanGeo,我们 ...

  8. 【日常记录】【unity3d】 OnTriggerEnter 和 OnCollisionEnter (2D) 的区别

    问题:两个物体A,B 两者都有碰撞体 collider(Box Collider,Sphere Collider,Capsule Collider等)当两物体相撞时,会进入 OnTriggerEnte ...

  9. Oracle EBS 新增OAFM个数

    在 $INST_TOP/ora/10.1.3/opmn/conf/opmn.xml中找到<process-type id="oafm" module-id="OC4 ...

  10. [翻译] OCMaskedTextField

    OCMaskedTextField https://github.com/OmerCora/OCMaskedTextField Simple class to display dynamically ...