springboot核心注解@EnableAutoConfiguration会导入@Import(AutoConfigurationImportSelector.class),这个类实现了DeferredImportSelector接口,即可以达到spring完成bean的初始化之后会回调该接口的selectImports方法,方法的参数是各个bean的类属性,注解等,返回的bean才会导入到spring中。AutoConfigurationImportSelector实现逻辑如下:

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = getAttributes(annotationMetadata);List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return StringUtils.toStringArray(configurations);
}

该方法逻辑大致就是加载各个jar包下的spring.factories配置文件,读取出自动配置的类,然后去掉重复的以及需要排除的,然后进行过滤,即filter方法,该方法如下:

private List<String> filter(List<String> configurations,AutoConfigurationMetadata autoConfigurationMetadata) {long startTime = System.nanoTime();String[] candidates = StringUtils.toStringArray(configurations);boolean[] skip = new boolean[candidates.length];boolean skipped = false;for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {invokeAwareMethods(filter);boolean[] match = filter.match(candidates, autoConfigurationMetadata);for (int i = 0; i < match.length; i++) {if (!match[i]) {skip[i] = true;skipped = true;}}}if (!skipped) {return configurations;}List<String> result = new ArrayList<>(candidates.length);for (int i = 0; i < candidates.length; i++) {if (!skip[i]) {result.add(candidates[i]);}}if (logger.isTraceEnabled()) {int numberFiltered = configurations.size() - result.size();logger.trace("Filtered " + numberFiltered + " auto configuration class in "+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)+ " ms");}return new ArrayList<>(result);
}

重点看第一个for循环,getAutoConfigurationImportFilters()会返回所有AutoConfigurationImportFilter的实现类,目前只有OnClassCondition这个类实现了该接口,即返回的都是OnClassCondition类的对象,而OnClassCondition继承自SpringBootCondition,match会根据条件过滤掉不符合条件的配置类,留下符合条件的配置类,从而被AutoConfigurationImportSelector注入spring完成加载。这里说一下match方法是如何处理ConditionOnClass注解的,看实现,其中的getOutcomes方法实现,其中使用createOutcomesResolver方法创建了2个OutcomesResolver,需要注意的是,留下了一半的解析任务放在新开线程中实现以获得更好的性能,这里主要看StandardOutcomesResolver的实现,对应的实现方法:

private ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,int start, int end, AutoConfigurationMetadata autoConfigurationMetadata) {ConditionOutcome[] outcomes = new ConditionOutcome[end - start];for (int i = start; i < end; i++) {String autoConfigurationClass = autoConfigurationClasses[i];Set<String> candidates = autoConfigurationMetadata.getSet(autoConfigurationClass, "ConditionalOnClass");if (candidates != null) {outcomes[i - start] = getOutcome(candidates);}}return outcomes;
}private ConditionOutcome getOutcome(Set<String> candidates) {try {List<String> missing = getMatches(candidates, MatchType.MISSING,this.beanClassLoader);if (!missing.isEmpty()) {return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class).didNotFind("required class", "required classes").items(Style.QUOTE, missing));}}catch (Exception ex) {// We'll get another chance later}return null;
}

可以看到读取了类上面的ConditionalOnClass注解的值,然后和环境中进行匹配,如果存在就返回ConditionOutcome对象,存在返回空。经过这些过滤,最终由上面说的AutoConfigurationImportSelector类返回后被spring加载从而实现了条件注解的配置功能。

另外@configuration类会在ConfigurationClassPostProcessor中进行处理,一些其他类型的@Condition条件判断等,如OnJavaCondition注解等,会在这里处理,这里不再赘述。

如何查看注解实现_SpringBoot的注解@ConditonOnClass注解是如何实现的?相关推荐

  1. 如何查看注解实现_该怎么运用注解呢?Java团队元老有话说

    来源 | 异步 15讲能学好诞生24年的JAVA吗?你当然会感到怀疑,众所周知,在技术向的IT论坛上,"如何在十天之内快速掌握好Java?"这类问题,往往会招来嘲笑. 来源于知乎 ...

  2. @controlleradvice注解作用_springboot的常用注解分析

    在spring boot中,摒弃了spring以往项目中大量繁琐的配置,遵循约定大于配置的原则,通过自身默认配置,极大的降低了项目搭建的复杂度.同样在spring boot中,大量注解的使用,使得代码 ...

  3. 注解报错_Java中的注解使用:全面性的总结一下

    前话: 今天,我们又来聊一下注解的使用,做一下详细的解析,也介绍了自定义注解,请耐心往下看哟! 注解的介绍: 在2005年,sun公司推出了jdk1.5,同时推出的注解功能吸引了很多人的目光,使用注解 ...

  4. android打包成apk会屏蔽注解,Android解决混淆打包之后注解被去掉的问题-Go语言中文社区...

    一.实验环境(蓝色粗体字为特别注意内容) 1,环境:Eclipse+ADT 2,参考文献: 我们都知道Android中是通过findViewById()这个方法来绑定xml中的控件的.但是当控件较多时 ...

  5. spring中自定义注解(annotation)与AOP中获取注解___使用aspectj的@Around注解实现用户操作和操作结果日志

    spring中自定义注解(annotation)与AOP中获取注解 一.自定义注解(annotation) 自定义注解的作用:在反射中获取注解,以取得注解修饰的类.方法或属性的相关解释. packag ...

  6. java注解和反射原理_Java中的注解和反射

    最近又回顾了一下 Java 中的注解和反射知识点,注解在日常开发中使用很多,但是反射比较少.值得注意的是 Java 的各种框架底层源码中大量使用了注解和反射,阅读源码,这些是基本功,面试中这部分内容也 ...

  7. java编译时注解_Java注解处理器--编译时处理的注解

    1. 一些基本概念 在开始之前,我们需要声明一件重要的事情是:我们不是在讨论在运行时通过反射机制运行处理的注解,而是在讨论在编译时处理的注解. 注解处理器是 javac 自带的一个工具,用来在编译时期 ...

  8. Mybatis注解大全 Mybatis支持的所有注解说明

    注解 使用对象 相对应的XML 描述 @CacheNamespace 类 <cache> 为给定的命名空间(比如类)配置缓存.属性有:implemetation, eviction, fl ...

  9. SpringBoot注解--@SpringBootApplication/@MapperScan/自定义启动类注解

    原文网址:SpringBoot注解--@SpringBootApplication/@MapperScan/自定义启动类注解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SpringBoot启动类 ...

  10. java ssm常用注解_SSM框架中常用的注解

    @Controller:在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model , ...

最新文章

  1. ASP.NET中如何防范SQL注入式攻击
  2. Java调用.NET的WCF
  3. 如何更改tomcat7及以上版本内存设置
  4. webpack编译过程
  5. 【LeetCode笔记】117.填充每个节点的下一个右侧节点指针 II(二叉树、DFS)
  6. 华硕ROG5电竞手机跑分数据曝光:骁龙888+16G超大运存
  7. 回归标准差和残差平方和的关系_ISLR实验:简单线性回归
  8. 程序中,序列化与反序列化
  9. 海淀驾校怎么样?我的学车之路
  10. sshv2 mitm工具SSH MITM v2.1的使用记录
  11. android感应不了夜神模拟器,夜神模拟器使用(检测不到)
  12. java getbytes_JAVA的getBytes()方法
  13. Elasticsearch 集群报错 master not discovered yet
  14. 查找国外硕士博士论文
  15. centos lvm管理2t以上硬盘
  16. 基于Docker的frp内网穿透
  17. 我国个人缴税计算实例
  18. 木纹标识lisp_LISP架构中一种新的移动性管理方案研究
  19. 摄像头视频推流python_python中用FFmpeg向rtmp服务器推流,实现摄像头直播
  20. 分类与评估模型(一)

热门文章

  1. Springboot项目中Pom.xml报错
  2. 【279天】每日项目总结系列017(2017.11.11)
  3. Hammer.js分析(一)——基础结构
  4. parsley.js自定义验证规则之大小写
  5. C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
  6. 如何使用Beyond Compare中心窗格
  7. 垂直的SeekBar:VerticalSeekBar
  8. MongoDB进阶系列(12)——MongoDB 固定集合
  9. 苹果开发者中心宕机8天终于回归
  10. System Center Configuration Manager 文档