一、缘起

最近有这样一个场景,我们使用了elasticjob lite框架,希望某些job在指定服务器不启动。让spring动态的来装载所需要的job及相关bean

这个时候可以使用@Conditional家族注解,该注解spring4.X后出现

二、@Conditional

@Conditional源码如下,接受一个参数,实现了Condition接口的Class

Condition接口里面就一个方法

ConditionContext可以获取到spring比较多有用信息,具体翻看api,AnnotatedTypeMetadata能获取到标注@Conditional注解的类或方法的信息,有几个实现类,想获取这些信息需要强转到子类获取,matches()方法返回true他就会装载这个bean,返回false就不会去装载,当时我把他和@Bean注解还有@Service注解一起配合使用

以下是自定义Condition类代码

  1. import org.springframework.context.annotation.Condition;
  2. import org.springframework.context.annotation.ConditionContext;
  3. import org.springframework.core.env.Environment;
  4. import org.springframework.core.type.AnnotatedTypeMetadata;
  5. import org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor;
  6. import org.springframework.core.type.classreading.MethodMetadataReadingVisitor;
  7.  
  8. public class MyCondition implements Condition {
  9.  
  10. @Override
  11. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  12. Environment env = context.getEnvironment();
  13. String enableGroup = env.getProperty("simpleJob.enableGroup");
  14. boolean result = true;
  15. if (metadata instanceof MethodMetadataReadingVisitor){
  16. MethodMetadataReadingVisitor mmrv = (MethodMetadataReadingVisitor) metadata;
  17. String methodName = mmrv.getMethodName();
  18. result = methodName.toUpperCase().startsWith(enableGroup);
  19. }else if (metadata instanceof AnnotationMetadataReadingVisitor){
  20. AnnotationMetadataReadingVisitor amrv = (AnnotationMetadataReadingVisitor) metadata;
  21. String className = amrv.getClassName();
  22. String simpleClassName = className.substring(className.lastIndexOf("."));
  23. result = simpleClassName.toUpperCase().startsWith(enableGroup);
  24. }
  25. return result;
  26. }
  27. }

引用《Spring Boot实战》一书中@Conditional家族注解的解释

三、Spring Boot中的运用

其实Spring Boot的自动配置全都是基于这些注解来实现的,@Conditional家族注解是springboot提供自动配置的关键

1、首先配置类上面会有@ConditionalOnClass注解,来说明存在某个class我就启动这个配置类

2、然后类中的方法会带有@ConditionalOnMissBean注解,如果上下文不存在某个bean就去运行下面的方法,装载bean

下图以jdbcTemplate和web自动配置为例

springBoot启动的时候动态选择装载某些bean的更多相关文章

  1. springboot启动的时候排除加载某些bean

    由于公司把redis相关的配置类,工具类放在了一个类似common的工程里,这样以后肯定不可避免的出现某些项目可能并不需要使用redis,但是还是依赖common里的别的一些类库 所以排除spring ...

  2. springboot 启动的时候报错 Error creating bean with name 'solrClient'

    springboot 启动的时候报错: org.springframework.beans.factory.BeanCreationException: Error creating bean wit ...

  3. spring-boot+quartz的CRUD动态任务管理系统

    版权声明:作者: 小柒 出处: https://blog.52itstyle.com 分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大 ...

  4. SpringBoot整合MyBatisPlus配置动态数据源

    目录 SpringBoot整合MyBatisPlus配置动态数据源 SpringBoot整合MyBatisPlus配置动态数据源 推文:2018开源中国最受欢迎的中国软件MyBatis-Plus My ...

  5. 从SpringBoot启动,阅读源码设计

    目录 一.背景说明 二.SpringBoot工程 三.应用上下文 四.资源加载 五.应用环境 六.Bean对象 七.Tomcat服务 八.事件模型 九.配置加载 十.数据库集成 十一.参考源码 服务启 ...

  6. SpringBoot启动流程解析

    写在前面: 由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图ke ...

  7. SpringBoot启动原理分析

    用了差不多两年的SpringBoot了,可以说对SpringBoot已经很熟了,但是仔细一想SpringBoot的启动流程,还是让自己有点懵逼,不得不说是自己工作和学习的失误,所以以此文对Spring ...

  8. SpringBoot 启动概述

    透过现象看本质,SpringApplication 只是将一个典型的Spring应用的启动流程进行了扩展,因此,透彻理解 Spring 容器是打开 Spring Boot 大门的一把钥匙. Sprin ...

  9. springboot整合Quartz实现动态配置定时任务

    前言 在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功能. 一.新建一个springboot工程,并添加依赖 & ...

随机推荐

  1. CF1012A Photo of The Sky

    CF1012A Photo of The Sky 有 \(n\) 个打乱的点的 \(x,\ y\) 轴坐标,现在告诉你这 \(2\times n\) 个值,问最小的矩形面积能覆盖住n个点且矩形长和宽分 ...

  2. python小白——进阶之路——day4天-———流程控制while if循环

    # ### 代码块: 以冒号作为开始,用缩进来划分作用域,这个整体叫做代码块 if 5 == 5: print(1) print(2) # 注意点: 要么全部使用4个空格,要么全部使用1个缩进 ,这样 ...

  3. 单机部署 ELK

    对于一个体量不大的系统,运行在单机上的 ELK 就足以胜任日志的处理任务了.本文介绍如何在单台服务器上安装并配置 ELK(elalasticsearch + logstash + kibana),并最 ...

  4. TypeError: sequence item 1: expected str instance, int found

    Error Msg Traceback (most recent call last): File "E:/code/adva_code/my_orm.py", line 108, ...

  5. java内存模型详解

    对于本篇文章,将从四个概念来介绍:内存模型基础,重排序,顺序一致性和happens-before 1.内存模型基础 在并发编程中,有两个关键问题:线程之间如何通信和如何同步.由此而引出了两种并发模型: ...

  6. Java 异常体系

    1.异常简介 Java把异常作为一种类,当做对象来处理.所有异常类的基类是Throwable类,两大子类分别是Error和Exception. 系统错误由Java虚拟机抛出,用Error类表示.Err ...

  7. MySQL之 InnoDB记录结构(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)

    以下内容来自掘金小册 MySQL 是怎样运行的:从根儿上理解 MySQL 版权归原作者所有! 页是MySQL中磁盘和内存交互的基本单位,也是MySQL是管理存储空间的基本单位. 指定和修改行格式的语法 ...

  8. Android N和O中使用adb shell dpm set-device-owner 'com.android.cts.verifier/com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver' setup Device Owner失败

    PC端出现如下log: D:\workspace\AndroidO\CTS\CTS_Verifier>adb shell dpm set-device-owner 'com.android.ct ...

  9. rest framework 序列化

    serializers 序列化组件 可以实现很轻松的互相转换,最常用的组件 ,用量最大的组件 源码位置 rest_framework.serializers 源码中需要用到的    rest_fram ...

  10. 【CF1132G】Greedy Subsequences(线段树)

    [CF1132G]Greedy Subsequences(线段树) 题面 CF 题解 首先发现选完一个数之后选择下一个数一定是确定的. 对于每个数预处理出左侧第一个比他大的数\(L\),那么这个数加入 ...