文章目录

  • 1:定义bean类
  • 2:测试类
  • 3:修改为dev环境
  • 4:修改为test环境
  • 5:原理分析
  • 6:自己定义一个例子
  • 6.2:定义MyConditionAnnotation注解
  • 6.3:定义Condition实现类MyConditionalImpl
  • 6.4:使用@Import注解引入配置类
  • 6.5:测试
  • 7:spring5默认提供的Condition实现

原博文,点击这里
使用实例在开源项目jeecg-boot中广泛使用

1:定义bean类

@Configuration
public class ProfileTestConfiguration {@Bean@Profile(value = "dev")public MyProfileBean devProfileBean() {return new MyProfileBean("dev profile");}@Bean@Profile(value =  "test")public MyProfileBean testProfileBean() {return new MyProfileBean("test profile");}
}

以上类通过@Profle指定bean在哪个环境中生效。
同时需要注意:@Configuration不能将类放入到IOC,容器之中。但在运用的时候需要获取该类对应的bean,此时就需要用到@Import注解

2:测试类

@SpringBootApplication(exclude = { SpringApplicationAdminJmxAutoConfiguration.class })
@Import(ProfileTestConfiguration.class)
public class SpringbootHelloworldApplication {public static void main(String[] args) {ConfigurableApplicationContext cac = SpringApplication.run(SpringbootHelloworldApplication.class, args);MyProfileBean myProfileBean = cac.getBean(MyProfileBean.class);System.out.println(myProfileBean);}}

3:修改为dev环境

修改application.properties

spring.profiles.active=dev

测试:


2021-01-31 16:35:05.269  INFO 80572 --- [           main] d.d.s.SpringbootHelloworldApplication    : Started SpringbootHelloworldApplication in 3.907 seconds (JVM running for 5.498)
MyProfileBean{name='dev profile'}

4:修改为test环境

修改application.properties

spring.profiles.active=test

测试:

2021-01-31 17:14:33.127  INFO 81908 --- [           main] d.d.s.SpringbootHelloworldApplication    : Started SpringbootHelloworldApplication in 5.172 seconds (JVM running for 6.953)
MyProfileBean{name='test profile'}

5:原理分析

看下@Profile注解源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {String[] value();}

可以看到其组合了@Conditional条件注解,并且将ProfileCondition作为条件类,源码如下:

class ProfileCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());if (attrs != null) {// 判断在配置文件中配置的spring.active.profile的值是否与@Profile注解给的value相同,// 相同则为true,否则为false,为true时则加载,false则不加载for (Object value : attrs.get("value")) {if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {return true;}}return false;}return true;}}

再来看下org.springframework.context.annotation.Condition源码:

@FunctionalInterface
public interface Condition {boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}

可以看到这是一个函数接口,只有一个方法matches该方法就是执行具体条件匹配。
我们再来看下@Conditional注解,源码如下:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {Class<? extends Condition>[] value();}

从@Target({ElementType.TYPE, ElementType.METHOD})可以看出,该注解可以使用在类上和方法上,本例就是使用的在方法上,如springboot中的自动配置类,很多时候就是使用在类上。
最后为了加深理解,来将java config类翻译为如下注意不是可执行代码,只是为了示意:

@Configuration
public class ProfileTestConfiguration {if (spring.profiles.active=dev) {@Beanpublic MyProfileBean devProfileBean() {return new MyProfileBean("dev profile");}}if (spring.profiles.active=test) {@Bean@Profile(value =  "test")public MyProfileBean testProfileBean() {return new MyProfileBean("test profile");}}
}

6:自己定义一个例子

自己的理解:
@Conditional注解:使用在类上,表示满足条件的类会放在IOC容器之中。
在自定义注解上面使用@Conditional注解,是一种叠加的效果,表示该自定义注解有这种效果。

6.1:定义java config类

@Configuration
public class ProfileTestConfiguration {@Bean@MyConditionAnnotation(advantage = "帅")public GirlFriend giveYouOneGirlFriend() {return new GirlFriend("章子怡");}
}

6.2:定义MyConditionAnnotation注解

@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(MyConditionalImpl.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConditionAnnotation {String advantage();
}

6.3:定义Condition实现类MyConditionalImpl

public class MyConditionalImpl implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 获取在@MyConditionAnnotation上设置的advantage的值,如果是"帅"则// 如果是"丑"则为falseMultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(MyConditionAnnotation.class.getName());String advantage = attrs.get("advantage").get(0).toString();System.out.println("advantage: " + advantage);return "帅".equals(advantage);}
}

只有配置的是帅才为真。

6.4:使用@Import注解引入配置类

@SpringBootApplication
@Import(ProfileTestConfiguration.class)
public class SpringbootHelloWorldApplication {public static void main(String[] args) {ConfigurableApplicationContext cac = SpringApplication.run(SpringbootHelloWorldApplication.class, args);GirlFriend girlFriend = cac.getBean(GirlFriend.class);System.out.println(girlFriend);}}

6.5:测试

因为我们配置的就是@MyConditionAnnotation(advantage = “帅”)应该为true,直接测试:

2021-01-31 20:11:00.357  INFO 88760 --- [           main] d.d.s.SpringbootHelloWorldApplication    : The following profiles are active: test
advantage: 帅
...
d.s.SpringbootHelloWorldApplication    : Started SpringbootHelloWorldApplication in 3.967 seconds (JVM running for 5.463)
GirlFriend{name='章子怡'}

修改为@MyConditionAnnotation(advantage = “丑”),测试:

2021-01-31 20:13:31.277  INFO 88855 --- [           main] d.d.s.SpringbootHelloWorldApplication    : The following profiles are active: test
advantage: 丑
...
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'dongshi.daddy.profiletest.GirlFriend' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)at dongshi.daddy.springboothelloworld.SpringbootHelloWorldApplication.main(SpringbootHelloWorldApplication.java:16)

7:spring5默认提供的Condition实现

在spring5中默认的提供的org.springframework.context.annotation.ConfigurationCondition,org.springframework.context.annotation.ProfileCondition,但是准确来说只有org.springframework.context.annotation.ProfileCondition,因为前者还只是一个接口,并不是具体的类,如下图:

可见,在spring中并没有得到太大的重视,没有被大量使用,但是在springboot中,得到了很大范围的发扬光大,并且成为springboot的核心功能自动配置的重要一环,可以简单看下在springboot中的众多的实现类:

springboot对条件接口Condition的扩展和使用----1相关推荐

  1. SpringBoot 自动配置之 Condition

    文章目录 前言 简介 创建 springboot-condition 模块 开始操作 获取容器中的 Bean @Conditional() 注解 matches() 条件判断 导入 Jedis 坐标后 ...

  2. SAP SD 基础知识之定价中的条件技术(Condition Technique in Pricing)

    SAP SD 基础知识之定价中的条件技术(Condition Technique in Pricing) 一,定价程序Pricing Procedure 所有定价中允许的条件类型都包含在定价程序中: ...

  3. 定义定价用途的条件类型(Condition Types)

    一.说明 条件的存取顺序(access sequences)可以设置若干个条件表(Condition Table),但仅有存取顺序还不能维护条件的记录.能够维护条件记录的是条件类型(Condition ...

  4. MyBatisPlus条件构造器Condition的用法

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 基础搭建: https://blog.csdn.net/B ...

  5. c#分页_使用Kotlin搭配Springboot开发RESTFul接口(二)自定义配置、跨域、分页

    前言 上一篇文章请看这里:使用Kotlin搭配Springboot开发RESTFul接口与服务部署 上一篇文章介绍了Kotlin搭配Springboot的开发流程,从搭建项目.ORM.Controll ...

  6. python 线程超时设置_python 条件变量Condition(36)

    文章首发微信公众号,微信搜索:猿说python 对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – ...

  7. Python 线程条件变量 Condition - Python零基础入门教程

    目录 一.Python 线程条件变量 Condition 函数 二.Python 线程条件变量 Condition 原理 三.Python 线程条件变量 Condition 使用 四.Python 线 ...

  8. python 很高兴问题_Python 3.7曾有一个很老的GIL竞态条件(race condition),我是这么解决的...

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 作者:Victor Stinner 作为Python最关键的组成部分之一:GIL(全局解释器锁),我花了4 ...

  9. 记录:为啥没有雷电4接口的显卡扩展坞与移动硬盘?

    雷电4接口发布之后,intel同时发布了3款雷电接口主控芯片,它们分别为JHL8540.JHL8340.JHL8440. 其中JHL8440是给外部扩展设备使用的芯片,但是这一次JHL8440只留下了 ...

最新文章

  1. Cisco 2950 忘记密码如何重设
  2. python-34:极视界爬虫总结
  3. boost::adjacency_list用法的测试程序
  4. 网站三级分销数据库如何设计,简单案例
  5. swoole 连接mysql_Swoole 优雅的实现 MySQL 连接池
  6. c语言ftell函数,C语言中ftell函数的使用方法
  7. 魅族mx4pro刷linux,魅族MX4 Pro刷recovery教程_魅族MX4 Pro第三方recovery下载
  8. sqlServer相关
  9. 如何获取每周的星期一和星期天的日期
  10. 怎么调整tabcontrol的tabpage标签的宽度
  11. 第一章概述-------第一节--1.3互联网的组成
  12. python读取tiff图像,浅谈python下tiff图像的读取和保存方法
  13. 服务器 显示w3wp.exe,w3wp.exe占用cpu过高的解决方法
  14. 乾隆的“十常四勿”之道
  15. 做项目遇到的一些CSS问题
  16. 一条mysql语句查询出男女的人数
  17. 杂类--------文字型码表(备份)
  18. 从工控网络安全攻击中学习的经验
  19. 原生 和html5 性能,原生开发与HTML5开发的对比
  20. 数字经济与信息资本主义——美国商务部《数字经济2000》中译本序

热门文章

  1. gulp构建项目(三):gulp-watch监听文件改变、新增、删除
  2. 统计学在中国的发展与就业前景
  3. Yolact训练自己的数据集
  4. Office2016免费下载:Office 2016 Pro Plus 64位 (迅雷复制链接就能下)
  5. 河北计算机一级考试试题,河北计算机一级试题及答案.doc
  6. AI Studio 课程
  7. N2语法汇总(190条)
  8. mysql英文怎么发音_英语口语怎么练最有效?知道这3个方法就够了!
  9. 【毕业设计 大作业高分项目】html+php实现个人博客网站
  10. 专科程序员“霸面”蚂蚁金服,4轮面试,竟拿下offer(Java方向)