在进行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. Navicat MySql乱码解决

    接着上一篇博客继续解决 如上图,鼠标放在localhost上右键,选择编辑连接,弹出下图. 如下选择好之后,连接数据库,进行测试.在test数据库上右键选择命令列界面,如下图,输入show varia ...

  2. ArcGIS10.3+Oracle12C+ArcGIS Server10.3安装布署(之二)

    1.创建PDB 输入 dbca 命令 2.安装完成后,连接PDBSDE的容器数据库 3.环境变量 从Oracle的官方网站下载   instantclient-basic-nt-12.1.0.2.0. ...

  3. x86项目中读取注册表Register数据项的方法

    x86项目中使用Registry读取key/value的时候,会出现重定向的问题,解决方法如下: public static string GetMachineGuid() { string guid ...

  4. 破解 jeb 2.3.7 demo

    前言 使用的技术和上文的一样. mips 版本的修改版 修改版: https://gitee.com/hac425/jeb-mips 正文 安卓版 jeb-2.3.7.201710262129-JEB ...

  5. mysql 安装版

    安装 1.MySQL的安装类型选择: 在“Choose Setup Type”对话框有“Typical”默认安装类型:“complete"完全安装类型:Custom自定义安装类型. 我们选择 ...

  6. 软工读书笔记 week 7 ——《构建之法》

    总时长近两周的结对项目终于算是结束了,马上要重新开启团队项目.于是这几天决定对<构建之法>一书中与团队项目及需求分析有关的章节进行重点阅读,希望能够从中得到启发,并运用到接下来的团队项目中 ...

  7. clr_zmq Vs2010版本

    .net的消息队列很方便的一个库. 在github上的主版本虽然也支持fw4.0,但是必须使用vs2012以上进行编译. 这样就依赖vcredist运行时. 因为win7 sp1以下版本,无法安装vc ...

  8. shell_advanced

    1.輸入輸出,重定向,管道 2.<(cmd):>(cmd) 3.>:<:>>:<<:>>>:<<< 4.文本处理_1 ...

  9. [WinCE] Win CE 屏幕截图

    VS2005自带了这个工具,这个工具的名称为:“远程放大”,其路径为:"C:\Program Files\CE Remote Tools\5.01\bin\cczoom.exe" ...

  10. teradata 查询创建表的时间

    如何查询teradata创建表的时间? select tablename,CreateTimeStamp from dbc.tables ---dbc的table,user是在dbc内的吗?具体不清楚 ...