在进行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. iframe跨源报错:"Blocked a frame with origin from accessing a cross-origin frame"

    一.报错信息: “Blocked a frame with origin from accessing a cross-origin frame” 二.在stackoverflow上找到原因 Same ...

  2. 分享一个oracle 完整备份的批处理文件

    该批处理是基本可以无限针对使用window 服务器的oracle 备份,如下: set mydate=%DATE:~0,10% exp e_cards2016/e_cards2016@orcl ful ...

  3. flutter Row里面元素居中显示

    直接上代码: new Expanded( flex: , child: new Row( children: <Widget>[ Expanded( child: new Containe ...

  4. BitmapFactory.Options

    BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inSampleSiz ...

  5. maven(19)-生命周期和内置插件

    生命周期和依赖一样,是maven中最重要的核心概念.平时在使用maven时并不一定需要知道生命周期,但是只有明白了生命周期,才能真正理解很多重要的命令和插件配置. default生命周期 defaul ...

  6. Winform 多个窗口编辑同一条数据同步的实现

    场景: 一个主窗口中,可以在列表(DataGridView)里选中一条记录编辑,打开一个编辑窗口(非模态窗口),编辑窗口保存后需要刷新父窗口,由于编辑窗口是非模态窗口,如果打开了多个窗口,并且都是编辑 ...

  7. 转:oracle 事务

    原文地址:http://blog.csdn.net/junmail/article/details/5556561 关于Oracle事务的总结 1.什么是事务,事务的特性是什么? 事务的任务便是使数据 ...

  8. consul日常操作命令

    #开发模式运行agent consul agent -dev #查看consul 集群成员 consul members [-detailed] members命令的输出基于gossip协议,并最终一 ...

  9. Linux系统重要的开机自启动的服务

    重要的开机自启动的服务 1.sshd  连接Linux服务器是需要用到的服务程序    2.rsyslog 操作日志的一种机制                系统日志:/var/log/message ...

  10. 17级-车辆工程-周金霖 计算机作业 MP4音乐网站